Forum rules - please read before posting.

Problem with custom action

edited August 2022 in Technical Q&A

I made a custom action based off the Object: Animate action that allows me to call multiple animators in the same action. The action works except for the fact that whenever I open Unity, the action doesn't "load in" and none of the animators are called. The rest of the action list runs as expected. I just have to open the action list for it to "load in" and it keeps working for the rest of my session. Even if I close the action list. Is there something I'm missing for it to work properly?
Here is the code (Sorry about the formatting):

namespace AC
{
[System.Serializable]
public class ActionRunMultipleAnimators : Action
{

    public override ActionCategory Category { get { return ActionCategory.Custom; } }
    public override string Title { get { return "Run Multiple Animators"; } }
    public override string Description { get { return "run a parameter in multiple animators"; } }

    public int animatorLength;
    public int runtimeAnimatorLenght;
    public int animatorLenghtParameterID = -1;

    public List<Animator> animators = new List<Animator>();
    public List<Animator> runtimeAnimators = new List<Animator>();

    public List<int> animatorsConstantIDs = new List<int>(10) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    public List<int> animatorsParameterIDs = new List<int>(10) { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };

    public string parameterName;
    public enum ParameterType { trigger, boolean, intNum, floatNum }
    public ParameterType parameterType;
    public float floatValue;
    public int intValue;
    public bool boolValue;


    public override void AssignValues(List<ActionParameter> parameters)
    {
        runtimeAnimatorLenght = AssignInteger(parameters, animatorLenghtParameterID, animatorLength);
        for (int i = 0; i < animators.Count; i++)
        {
            if (runtimeAnimators.Count > i)
            {
                runtimeAnimators[i] = AssignFile<Animator>(parameters, animatorsConstantIDs[i], animatorsParameterIDs[i], animators[i]);
            }
            else
            {
                Animator runtimeAnim = AssignFile<Animator>(parameters, animatorsConstantIDs[i], animatorsParameterIDs[i], animators[i]);
                runtimeAnimators.Add(runtimeAnim);
            }
        }

    }

    public override float Run()
    {
        if (!isRunning)
        {
            isRunning = true;
            //Debug.Log("RUNNING MULTI ANIMATOR");
            if (string.IsNullOrEmpty(parameterName))
            {
                Debug.LogError("Parameter name is empty");
            }

            for (int i = 0; i < runtimeAnimators.Count; i++)
            {
                if (runtimeAnimators[i] == null) Debug.LogWarning("Animator is null, remeber to assign the animators");
                switch (parameterType)
                {
                    case ParameterType.trigger:
                        if (runtimeAnimators[i])
                        {
                            runtimeAnimators[i].SetTrigger(parameterName);
                        }
                        break;
                    case ParameterType.boolean:
                        if (runtimeAnimators[i]) { runtimeAnimators[i].SetBool(parameterName, boolValue); }
                        break;
                    case ParameterType.intNum:
                        if (runtimeAnimators[i]) { runtimeAnimators[i].SetInteger(parameterName, intValue); }
                        break;
                    case ParameterType.floatNum:
                        if (runtimeAnimators[i]) { runtimeAnimators[i].SetFloat(parameterName, floatValue); }
                        break;
                    default:
                        break;
                }
            }
        }

        if (!isRunning)
        {
            isRunning = true;
            return defaultPauseTime;
        }
        else
        {
            isRunning = false;
            return 0f;
        }
    }


    public override void Skip()
    {
        /*
         * This function is called when the Action is skipped, as a
         * result of the player invoking the "EndCutscene" input.
         * 
         * It should perform the instructions of the Action instantly -
         * regardless of whether or not the Action itself has been run
         * normally yet.  If this method is left blank, then skipping
         * the Action will have no effect.  If this method is removed,
         * or if the Run() method call is left below, then skipping the
         * Action will cause it to run itself as normal.
         */

        // Run();
    }

if UNITY_EDITOR

    public override void ShowGUI(List<ActionParameter> parameters)
    {
        // Action-specific Inspector GUI code here
        int OldNumber = animatorLength;
        animatorLenghtParameterID = Action.ChooseParameterGUI("Transition time (s):", parameters, animatorLenghtParameterID, AC.ParameterType.Integer);
        if (animatorLenghtParameterID < 0)
        {
            animatorLength = EditorGUILayout.IntSlider("Aniamtors", animatorLength, 1, 10);
        }
        if (animatorLength < 1)
        {
            animatorLength = 1;
        }
        int Dif = OldNumber - animatorLength;
        if (Dif > 0)
        {
            animators.RemoveRange(animatorLength, Dif);
        }
        else if (Dif < 0)
        {
            for (int Count = 0; Count < -Dif; Count++)
            {
                animators.Add(null);
            }
        }
        for (int i = 0; i < animators.Count; i++)
        {

            if (animatorsConstantIDs.Count <= i)
            {
                animatorsConstantIDs.Add(0);
                Debug.Log("Count: " + animatorsConstantIDs.Count + " i: " + i);
            }
            animators[i] = (Animator)EditorGUILayout.ObjectField("Animator " + i, animators[i], typeof(Animator), true);
            animatorsConstantIDs[i] = FieldToID<Animator>(animators[i], animatorsConstantIDs[i]);
            animators[i] = IDToField<Animator>(animators[i], animatorsConstantIDs[i], true);
        }
        parameterName = EditorGUILayout.TextField("Parameter Name:", parameterName);
        if (string.IsNullOrEmpty(parameterName))
        {
            EditorGUILayout.HelpBox("Parameter name must not be empty", MessageType.Warning);
        }
        parameterType = (ParameterType)EditorGUILayout.EnumPopup("Parameter Type:", parameterType);

        switch (parameterType)
        {
            case ParameterType.trigger:
                break;
            case ParameterType.boolean:
                boolValue = EditorGUILayout.Toggle("Bool Value", boolValue);
                break;
            case ParameterType.intNum:
                intValue = EditorGUILayout.IntField("Int Value", intValue);
                break;
            case ParameterType.floatNum:
                floatValue = EditorGUILayout.FloatField("float Value", floatValue);
                break;
            default:
                break;
        }
    }

    public override string SetLabel()
    {
        return string.Empty;
    }

endif

}

}

Comments

  • What is the exact error/log message that shows when the issue occurs?

    I'm not clear on your intent with the animatorLenghtParameterID variable, since runtimeAnimatorLenght is ultimately not used.

    However, the runtimeAnimators List should not be public as this will serialize it - and it will be added to each time the Action is run.

    Make this List private and clear it in AssignValues, i.e.:

    public override void AssignValues(List<ActionParameter> parameters)
    {
        runtimeAnimators.Clear ();
        runtimeAnimatorLenght = AssignInteger(parameters, animatorLenghtParameterID, animatorLength);
        for (int i = 0; i < animators.Count; i++)
        {
            runtimeAnimators.Add (AssignFile<Animator>(parameters, animatorsConstantIDs[i], animatorsParameterIDs[i], animators[i]));
        }
    }
    
  • The log message I get is the one I have in this line of code:
    if (runtimeAnimators[i] == null) Debug.LogWarning("Animator is null, remeber to assign the animators");

    This is what the action looks like. In case it helps clear up what I want to do with it.

    I tried doing what you said but it didn't work. I no longer got the log message, but the animators were still not running.

  • Are you working with asset files, so that the Constant ID numbers are necessary? The AssignFile function has the animatorsConstantIDs and animatorsParameterIDs parameters the wrong way around.

    Since parameters aren't being assigned in ShowGUI, animatorsParameterIDs can be removed:

    using System.Collections.Generic;
    using UnityEngine;
    using UnityEditor;
    
    namespace AC
    {
    
        [System.Serializable]
        public class ActionRunMultipleAnimators : Action
        {
    
            public override ActionCategory Category { get { return ActionCategory.Custom; } }
            public override string Title { get { return "Run Multiple Animators"; } }
            public override string Description { get { return "run a parameter in multiple animators"; } }
    
            public List<Animator> animators = new List<Animator>();
            private List<Animator> runtimeAnimators = new List<Animator>();
    
            public List<int> animatorsConstantIDs = new List<int>();
    
            public string parameterName;
            public enum ParameterType { trigger, boolean, intNum, floatNum }
            public ParameterType parameterType;
            public float floatValue;
            public int intValue;
            public bool boolValue;
    
    
            public override void AssignValues(List<ActionParameter> parameters)
            {
                for (int i = 0; i < animators.Count; i++)
                {
                    Animator runtimeAnim = AssignFile<Animator>(parameters, -1, animatorsConstantIDs[i], animators[i]);
                    if (runtimeAnim) runtimeAnimators.Add(runtimeAnim);
                }
            }
    
    
            public override float Run ()
            {
                if (string.IsNullOrEmpty(parameterName))
                {
                    Debug.LogError("Parameter name is empty");
                    return 0f;
                }
    
                for (int i = 0; i < runtimeAnimators.Count; i++)
                {
                    switch (parameterType)
                    {
                        case ParameterType.trigger:
                            runtimeAnimators[i].SetTrigger (parameterName);
                            break;
    
                        case ParameterType.boolean:
                            runtimeAnimators[i].SetBool (parameterName, boolValue);
                            break;
    
                        case ParameterType.intNum:
                            runtimeAnimators[i].SetInteger (parameterName, intValue);
                            break;
    
                        case ParameterType.floatNum:
                            runtimeAnimators[i].SetFloat (parameterName, floatValue);
                            break;
    
                        default:
                            break;
                    }
                }
    
                return 0f;
            }
    
    
            public override void Skip ()
            {
                if (parameterType != ParameterType.trigger)
                {
                    Run ();
                }
            }
    
    
            #if UNITY_EDITOR
    
            public override void ShowGUI(List<ActionParameter> parameters)
            {
                int animatorLength = animators.Count;
                animatorLength = EditorGUILayout.IntSlider("# Animators:", animatorLength, 1, 10);
                if (animatorLength < 1)
                {
                    animatorLength = 1;
                }
                int Dif = animators.Count - animatorLength;
                if (Dif > 0)
                {
                    animators.RemoveRange (animatorLength, Dif);
                }
                else if (Dif < 0)
                {
                    for (int Count = 0; Count < -Dif; Count++)
                    {
                        animators.Add (null);
                    }
                }
    
                while (animatorsConstantIDs.Count <= animators.Count)
                {
                    animatorsConstantIDs.Add(0);
                }
    
                for (int i = 0; i < animators.Count; i++)
                {
                    animators[i] = (Animator) EditorGUILayout.ObjectField("Animator " + i, animators[i], typeof(Animator), true);
                    animatorsConstantIDs[i] = FieldToID<Animator>(animators[i], animatorsConstantIDs[i]);
                    animators[i] = IDToField<Animator>(animators[i], animatorsConstantIDs[i], true);
                }
    
                parameterName = EditorGUILayout.TextField("Parameter Name:", parameterName);
                if (string.IsNullOrEmpty(parameterName))
                {
                    EditorGUILayout.HelpBox("Parameter name must not be empty", MessageType.Warning);
                }
    
                parameterType = (ParameterType)EditorGUILayout.EnumPopup("Parameter Type:", parameterType);
                switch (parameterType)
                {
                    case ParameterType.trigger:
                        break;
                    case ParameterType.boolean:
                        boolValue = EditorGUILayout.Toggle("Bool Value", boolValue);
                        break;
                    case ParameterType.intNum:
                        intValue = EditorGUILayout.IntField("Int Value", intValue);
                        break;
                    case ParameterType.floatNum:
                        floatValue = EditorGUILayout.FloatField("float Value", floatValue);
                        break;
                    default:
                        break;
                }
            }
    
            #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.