ActionSimpleOpenClose

 avatar
unknown
csharp
22 days ago
7.9 kB
4
Indexable
using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace AC
{
    [System.Serializable]
    public class ActionSimpleOpenClose : Action
    {
        public int targetObjectParameterID = -1;
        public int additionalObjectParameterID = -1;
        public int waitForAnimationParameterID = -1;

        public GameObject targetObject;
        public GameObject additionalObject;
        public bool waitForAnimation = true;

        private Animator myAnimator;
        private Animator additionalAnimator;
        private bool objectOpen;
        private bool objectOpenAdditional;
        private bool hasAdditional = false;
        private bool isWaiting = false;

        public ActionSimpleOpenClose()
        {
            isDisplayed = true;
            category = ActionCategory.Custom;
            title = "Simple Open/Close";
            description = "Opens or closes an object based on its current state.";
        }

        public override void AssignValues(List<ActionParameter> parameters)
        {
            // Instead of AssignFile<T>, we use our own function for GameObject
            targetObject = AssignGameObject(parameters, targetObjectParameterID, targetObject);
            additionalObject = AssignGameObject(parameters, additionalObjectParameterID, additionalObject);

            // We convert the boolean variable from AC
            AC.BoolValue boolVal = waitForAnimation ? AC.BoolValue.True : AC.BoolValue.False;
            boolVal = AssignBoolean(parameters, waitForAnimationParameterID, boolVal);
            waitForAnimation = (boolVal == AC.BoolValue.True);
        }

        /// <summary>
        /// Helper function to assign a GameObject
        /// from a "GameObject" parameter in AC.
        /// </summary>
        private GameObject AssignGameObject(List<ActionParameter> parameters, 
                                            int parameterID, 
                                            GameObject currentValue)
        {
            if (parameterID >= 0 && parameterID < parameters.Count)
            {
                ActionParameter param = parameters[parameterID];
                if (param != null && param.parameterType == ParameterType.GameObject)
                {
                    GameObject foundObj = param.gameObject;
                    ///Debug.Log("[ActionSimpleOpenClose] Param '"
                    ///        + param.label + "' = " 
                    ///        + (foundObj != null ? foundObj.name : "NULL"));
                    return foundObj;
                }
            }
            ///Debug.Log("[ActionSimpleOpenClose] Using currentValue = "
            ///        + (currentValue != null ? currentValue.name : "NULL"));
            return currentValue;
        }

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

            if (!isWaiting)
            {
                myAnimator = targetObject.GetComponent<Animator>();
                if (myAnimator == null)
                {
                    myAnimator = targetObject.GetComponentInParent<Animator>();
                }

                if (myAnimator == null)
                {
                    return 0f;
                }

                objectOpen = IsObjectOpen(myAnimator);

                if (additionalObject != null)
                {
                    additionalAnimator = additionalObject.GetComponent<Animator>();
                    if (additionalAnimator != null)
                    {
                        hasAdditional = true;
                        objectOpenAdditional = IsObjectOpen(additionalAnimator);
                    }
                }

                ToggleObject();
                isWaiting = waitForAnimation;
            }

            if (isWaiting)
            {
                if (IsAnimationComplete())
                {
                    isWaiting = false;
                    return 0f;
                }
                return defaultPauseTime;
            }

            return 0f;
        }

        private bool IsObjectOpen(Animator animator)
        {
            AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
            // Adjust the criteria according to your "Open"/"Close" clips
            return stateInfo.IsName("Open") ||
                (stateInfo.normalizedTime > 0.5f && stateInfo.IsName("Open"));
        }

        private void ToggleObject()
        {
            if (objectOpen)
            {
                myAnimator.Play("Close", 0, 0.0f);
                if (hasAdditional && objectOpenAdditional)
                {
                    additionalAnimator.Play("Close", 0, 0.0f);
                }
            }
            else
            {
                myAnimator.Play("Open", 0, 0.0f);
                if (hasAdditional && !objectOpenAdditional)
                {
                    additionalAnimator.Play("Open", 0, 0.0f);
                }
            }
        }

        private bool IsAnimationComplete()
        {
            bool mainAnimComplete = myAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1.0f;
            bool additionalAnimComplete = !hasAdditional ||
                additionalAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1.0f;

            return mainAnimComplete && additionalAnimComplete;
        }

#if UNITY_EDITOR
        public override void ShowGUI(List<ActionParameter> parameters)
        {
            targetObjectParameterID = Action.ChooseParameterGUI(
                "Target object:",
                parameters,
                targetObjectParameterID,
                ParameterType.GameObject
            );
            if (targetObjectParameterID < 0)
            {
                targetObject = (GameObject)EditorGUILayout.ObjectField(
                    "Target object:",
                    targetObject,
                    typeof(GameObject),
                    true
                );
            }

            additionalObjectParameterID = Action.ChooseParameterGUI(
                "Additional object:",
                parameters,
                additionalObjectParameterID,
                ParameterType.GameObject
            );
            if (additionalObjectParameterID < 0)
            {
                additionalObject = (GameObject)EditorGUILayout.ObjectField(
                    "Additional object:",
                    additionalObject,
                    typeof(GameObject),
                    true
                );
            }

            waitForAnimationParameterID = Action.ChooseParameterGUI(
                "Wait for animation:",
                parameters,
                waitForAnimationParameterID,
                ParameterType.Boolean
            );
            if (waitForAnimationParameterID < 0)
            {
                waitForAnimation = EditorGUILayout.Toggle("Wait for animation:", waitForAnimation);
            }
        }
#endif

        public string SetLabel()
        {
            return (targetObject != null) ? targetObject.name : string.Empty;
        }

        public override void Skip()
        {
            // We force the end of the animation if it is "skipped."
            if (myAnimator != null)
            {
                myAnimator.Play(objectOpen ? "Close" : "Open", 0, 1f);
            }
            if (hasAdditional && additionalAnimator != null)
            {
                additionalAnimator.Play(objectOpenAdditional ? "Close" : "Open", 0, 1f);
            }
        }
    }
}
Leave a Comment