MirrorNetworking / MirrorNetworking/Mirror
NetworkAnimator breaks when Animator.runtimeAnimatorController is Instantiated in Runtime
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 6.3k
- Forks
- 870
- PR merge metrics
- No merged PRs in 30d
Description
Describe the bug
When we want to control AnimatorController Speed for each Player the best way is to instantiate the AnimatorController and control each instance speed instead just assign the AnimatorController in inspector or so all Animator Controller instances will change the speed because its source. The NetworkAnimator its seems like not read for this behaviour. It's happen because of script execution order so if other classe that instantiate the AnimatorController run after awake from NetworkAnimator this will happen.
[IMPORTANT] How can we reproduce the issue, step by step:
- Instantiate the AnimatorController in Animator component thats is referenced by NetworkAnimator
Expected behavior
NetworkAnimator needs to check animator.runtimeAnimatorController(line 33) is not null before call methos bellow:
bool CheckAnimStateChanged(out int stateHash, out float normalizedTime, int layerId)
bool WriteParameters(NetworkWriter writer, bool forceAll = false)
Desktop (please complete the following information):
- OS: Windows
- Build target: Windows
- Unity version: 2021.3.4f
- Mirror branch: Last Asset Store version
Additional context
I am able to Solve follow the example:
void Awake()
{
StartCoroutine(WaitAnimatorControllerBeInstantiated());
}
private IEnumerator WaitAnimatorControllerBeInstantiated()
{
while (animator.runtimeAnimatorController == null)
{
yield return null;
}
// store the animator parameters in a variable - the "Animator.parameters" getter allocates
// a new parameter array every time it is accessed so we should avoid doing it in a loop
parameters = animator.parameters
.Where(par => !animator.IsParameterControlledByCurve(par.nameHash))
.ToArray();
lastIntParameters = new int[parameters.Length];
lastFloatParameters = new float[parameters.Length];
lastBoolParameters = new bool[parameters.Length];
animationHash = new int[animator.layerCount];
transitionHash = new int[animator.layerCount];
layerWeight = new float[animator.layerCount];
}
bool CheckAnimStateChanged(out int stateHash, out float normalizedTime, int layerId)
{
bool change = false;
stateHash = 0;
normalizedTime = 0;
if (parameters == null)
{
return false;
}
bool WriteParameters(NetworkWriter writer, bool forceAll = false)
{
if (parameters == null)
{
return false;
}
void ReadParameters(NetworkReader reader)
{
if (parameters == null)
{
return;
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Locate the NetworkAnimator implementation and inspect CheckAnimStateChanged, WriteParameters, and ReadParameters, especially initialization that depends on animator.runtimeAnimatorController. Reproduce the issue with a runtime-instantiated controller, then verify these methods safely wait for the controller and begin parameter and state handling once it exists.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, unity
- Domain
- game-dev, networking
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100