Forum rules - please read before posting.

Transform Object Action

Often I want to transform any object, but the default transform in AC's list only transforms moveables. Here's a custom action you may want to import.

using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace AC
{
    [System.Serializable]
    public class ActionTransformSet : Action
    {
        public GameObject objectToAffect;
        public int constantID;
        public int parameterID = -1;

        public bool affectPosition = false;
        public Vector3 newPosition;

        public bool affectRotation = false;
        public Vector3 newRotation;

        public bool affectScale = true;
        public Vector3 newScale = Vector3.one;

        public bool isRelative = false;
        public bool useLocalSpace = true;

        public bool changeOverTime = false;
        public float transitionTime = 1f;

        // --- runtime-only state, not serialized ---
        private bool isRunning;
        private float startTimeAbs;
        private Vector3 startPosition, targetPosition;
        private Vector3 startRotation, targetRotation;
        private Vector3 startScale, targetScale;

        public override ActionCategory Category { get { return ActionCategory.Object; } }
        public override string Title { get { return "Set Transform"; } }
        public override string Description { get { return "Sets the position, rotation and/or scale of any GameObject directly - the object does not need to be 'Moveable'."; } }

        public override void AssignValues(List<ActionParameter> parameters)
        {
            objectToAffect = AssignFile(parameters, parameterID, constantID, objectToAffect);
        }

        public override float Run()
        {
            if (objectToAffect == null)
            {
                return 0f;
            }

            if (!isRunning)
            {
                isRunning = true;
                startTimeAbs = Time.time;

                startPosition = useLocalSpace ? objectToAffect.transform.localPosition : objectToAffect.transform.position;
                startRotation = objectToAffect.transform.localEulerAngles;
                startScale = objectToAffect.transform.localScale;

                targetPosition = affectPosition ? (isRelative ? startPosition + newPosition : newPosition) : startPosition;
                targetRotation = affectRotation ? (isRelative ? startRotation + newRotation : newRotation) : startRotation;
                targetScale = affectScale ? (isRelative ? startScale + newScale : newScale) : startScale;

                if (!changeOverTime || transitionTime <= 0f)
                {
                    Apply(1f);
                    isRunning = false;
                    return 0f;
                }

                Apply(0f);
                return 0.02f;
            }
            else
            {
                float t = Mathf.Clamp01((Time.time - startTimeAbs) / transitionTime);
                Apply(t);

                if (t >= 1f)
                {
                    isRunning = false;
                    return 0f;
                }
                return 0.02f;
            }
        }

        public override void Skip()
        {
            if (objectToAffect == null) return;

            Vector3 basePos = useLocalSpace ? objectToAffect.transform.localPosition : objectToAffect.transform.position;
            Vector3 baseRot = objectToAffect.transform.localEulerAngles;
            Vector3 baseScale = objectToAffect.transform.localScale;

            if (affectPosition)
            {
                Vector3 p = isRelative ? basePos + newPosition : newPosition;
                if (useLocalSpace) objectToAffect.transform.localPosition = p;
                else objectToAffect.transform.position = p;
            }
            if (affectRotation)
            {
                objectToAffect.transform.localEulerAngles = isRelative ? baseRot + newRotation : newRotation;
            }
            if (affectScale)
            {
                objectToAffect.transform.localScale = isRelative ? baseScale + newScale : newScale;
            }
        }

        private void Apply(float t)
        {
            if (objectToAffect == null) return;

            Vector3 pos = Vector3.Lerp(startPosition, targetPosition, t);
            Vector3 rot = Vector3.Lerp(startRotation, targetRotation, t);
            Vector3 scale = Vector3.Lerp(startScale, targetScale, t);

            if (affectPosition)
            {
                if (useLocalSpace) objectToAffect.transform.localPosition = pos;
                else objectToAffect.transform.position = pos;
            }
            if (affectRotation)
            {
                objectToAffect.transform.localEulerAngles = rot;
            }
            if (affectScale)
            {
                objectToAffect.transform.localScale = scale;
            }
        }

#if UNITY_EDITOR
        public override void ShowGUI(List<ActionParameter> parameters)
        {
            parameterID = Action.ChooseParameterGUI("Object to affect:", parameters, parameterID, ParameterType.GameObject);
            if (parameterID < 0)
            {
                objectToAffect = (GameObject)EditorGUILayout.ObjectField("Object to affect:", objectToAffect, typeof(GameObject), true);
                constantID = FieldToID(objectToAffect, constantID);
                objectToAffect = IDToField(objectToAffect, constantID, true);
            }

            EditorGUILayout.Space();
            isRelative = EditorGUILayout.Toggle("Relative change?", isRelative);
            useLocalSpace = EditorGUILayout.Toggle("Use local position?", useLocalSpace);

            EditorGUILayout.Space();
            affectPosition = EditorGUILayout.Toggle("Affect position?", affectPosition);
            if (affectPosition) newPosition = EditorGUILayout.Vector3Field("New position:", newPosition);

            affectRotation = EditorGUILayout.Toggle("Affect rotation?", affectRotation);
            if (affectRotation) newRotation = EditorGUILayout.Vector3Field("New rotation (euler):", newRotation);

            affectScale = EditorGUILayout.Toggle("Affect scale?", affectScale);
            if (affectScale) newScale = EditorGUILayout.Vector3Field("New scale:", newScale);

            EditorGUILayout.Space();
            changeOverTime = EditorGUILayout.Toggle("Change over time?", changeOverTime);
            if (changeOverTime)
            {
                transitionTime = EditorGUILayout.FloatField("Transition time (s):", transitionTime);
            }

            AfterRunningOption();
        }

        public override string SetLabel()
        {
            if (objectToAffect != null)
            {
                return objectToAffect.name;
            }
            return string.Empty;
        }
#endif
    }
}
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.