Can anyone help me with strange issue, I have upgraded a game to version 5.6
all seems okay, but when I try to switch a weapon in game, there is a character
freeze and nothing happens. This is the only message in the console.
My script code: The Animator Line>
public void SwitchGun(int gunIndex)
{
gunIndex -= 1;
for (int i = 0; i < GunObject.Length; i++)
{
GunObject[i].SetActive(i == gunIndex);
GunObject[i].GetComponent<Animator>().Play(0, 0, 0);
}
}
}
There are a couple things that could be happening based on the script snippet you provided. Here are some observations commented into your script:
public void SwitchGun(int gunIndex)
{
// There is no clamping of the gunIndex value
// within a range, so it could easily reach
// a value of -1 and result in an
// IndexOutOfRange Exception
gunIndex -= 1;
for (int i = 0; i < GunObject.Length; i++)
{
// These methods are called on every object
// in the array and that is probably not
// intended as you would be calling Play on
// an Animator of an inactive object
GunObject[i].SetActive(i == gunIndex);
// You are supplying a hashID of 0 to the
// Animator. This isn't an index, but rather
// a hash conversion of the state name, so
// 0 will most likely never be a valid ID
GunObject[i].GetComponent<Animator>().Play(0, 0, 0);
}
}
So, here are some possibilties to look into for you.
The Animator does not have a matching state for the hash you have provided. When using this version of the Animator.Play method:
public void Play(int stateNameHash, int layer = -1, float normalizedTime = float.NegativeInfinity);
You will first need to determine the hash for the desired state using the Animator.StringToHash method:
public static int StringToHash(string name);
I would recommend caching the hash so you only do the conversion once. Here is an example that corrects the issues I have discussed
private int gunSwitchID = Animator.StringToHash("gunSwitch");
public void SwitchGun(int gunIndex)
{
// Clamp this value between 0
// and the last valid array index
gunIndex = Mathf.Clamp(gunIndex -= 1, 0, GunObject.Length - 1);
for (int i = 0; i < GunObject.Length; i++)
{
// Set the appropriate active state
// for each object
GunObject[i].SetActive(i == gunIndex);
}
// Play the animation on the desired object
GunObject[gunIndex].GetComponent<Animator>().Play(gunSwitchID, 0, 0);
}
The code above is untested as I’m not sure how to replicate your set up. However, I hope this helps you out.
Thank you sir for detailed reply.
I will try and understand this, the code was written long time ago by another team member so was not sure what he was doing and I admit not a advanced coder myself.
I just tried your solution, the result is new warning:
Animator.GotoState: State could not be found
UnityEngine.Animator:Play(Int32, Int32, Single)
[/code]
Its weird because when switching the weapon ingame, player freezes and does not move, no Red error messages and all carries on in background…
I don’t know what to do. The console prompts this exact message, but my “animation” is still working (I surround it between “” because it works more as an status indicator than as an animation, and maybe that is why is still working)
There is a single animation in the Animator, and it simply enables or disables a series of objects in order to show them. I set and “freeze” the corresponding frame by code with a Animator.Play() call of that frame every Update ().
Normally, “CentroKing” is a prefab that is not on the Scene and I instantiate it by code.
The lines of code that fires this warning are the animator1.Play and animator2.Play calls:
public Animator animator1;
public Animator animator2;
private int circuloID = Animator.StringToHash("circulo");
private int circulo2ID = Animator.StringToHash("circulo2");
public float valor;
public float valormax;
void Update () {
float cantirelleno = valor / valormax;
if (cantirelleno>0.5d) {
animator1.Play(circuloID, -1, 2f * (1f - cantirelleno));
animator2.Play(circulo2ID, -1, 0.01f);
} else {
animator1.Play(circuloID, -1, 0.99f);
animator2.Play(circulo2ID, -1, 2f * (0.5f - cantirelleno));
}
}
Should I instantiate the Animator controllers too?
The Animator needs time to initialize, when you call animator methods in the gameobject initialize phase (likely inside Awake() call) it will show this warning. You can do the the job in next frame to avoid this warning.
Did you make sure that your Animator Component has a controller associated? This happened to me and it was because my Animator component had no controller…