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();
}
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;
}
}
}
It looks like you're new here. If you want to get involved, click one of these buttons!
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.:
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: