using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Tools
{
///
/// This class will let you mirror the behaviour of an Animator's parameters on a Source Animator onto the ones of a Target Animator.
/// Target will mirror Source.
/// Only the parameters existing on both Target and Source will be considered, you'll need to have the same on both before entering runtime.
///
public class MMAnimatorMirror : MonoBehaviour
{
/// a struct used to store bindings
public struct MMAnimatorMirrorBind
{
public int ParameterHash;
public AnimatorControllerParameterType ParameterType;
}
[Header("Bindings")]
/// the animator to mirror
public Animator SourceAnimator;
/// the animator to mirror to
public Animator TargetAnimator;
protected AnimatorControllerParameter[] _sourceParameters;
protected AnimatorControllerParameter[] _targetParameters;
protected List _updateParameters;
///
/// On Awake we initialize
///
protected virtual void Awake()
{
Initialization();
}
///
/// Stores animation parameters hashes
///
protected virtual void Initialization()
{
if (TargetAnimator == null)
{
TargetAnimator = this.gameObject.GetComponent();
}
if ((TargetAnimator == null) || (SourceAnimator == null))
{
return;
}
// we store our source parameters
int numberOfParameters = SourceAnimator.parameterCount;
_sourceParameters = new AnimatorControllerParameter[numberOfParameters];
for (int i = 0; i < numberOfParameters; i++)
{
_sourceParameters[i] = SourceAnimator.GetParameter(i);
}
// we store our target parameters
numberOfParameters = TargetAnimator.parameterCount;
_targetParameters = new AnimatorControllerParameter[numberOfParameters];
for (int i = 0; i < numberOfParameters; i++)
{
_targetParameters[i] = TargetAnimator.GetParameter(i);
}
// we store our matching parameters
_updateParameters = new List();
foreach (AnimatorControllerParameter sourceParam in _sourceParameters)
{
foreach (AnimatorControllerParameter targetParam in _targetParameters)
{
if (sourceParam.name == targetParam.name)
{
MMAnimatorMirrorBind bind = new MMAnimatorMirrorBind();
bind.ParameterHash = sourceParam.nameHash;
bind.ParameterType = sourceParam.type;
_updateParameters.Add(bind);
}
}
}
}
///
/// On Update we mirror our behaviours
///
protected virtual void Update()
{
Mirror();
}
///
/// Copies animation parameter states from one animator to the other
///
protected virtual void Mirror()
{
if ((TargetAnimator == null) || (SourceAnimator == null))
{
return;
}
foreach (MMAnimatorMirrorBind bind in _updateParameters)
{
switch (bind.ParameterType)
{
case AnimatorControllerParameterType.Bool:
TargetAnimator.SetBool(bind.ParameterHash, SourceAnimator.GetBool(bind.ParameterHash));
break;
case AnimatorControllerParameterType.Float:
TargetAnimator.SetFloat(bind.ParameterHash, SourceAnimator.GetFloat(bind.ParameterHash));
break;
case AnimatorControllerParameterType.Int:
TargetAnimator.SetInteger(bind.ParameterHash, SourceAnimator.GetInteger(bind.ParameterHash));
break;
case AnimatorControllerParameterType.Trigger:
if (SourceAnimator.GetBool(bind.ParameterHash))
{
TargetAnimator.SetTrigger(bind.ParameterHash);
}
break;
}
}
}
}
}