149 lines
3.5 KiB
C#
Raw Normal View History

2022-08-14 12:33:04 +01:00
using Mirror;
using OWML.Common;
2020-11-04 20:01:28 +00:00
using QSB.Utility;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
2022-03-02 19:46:33 -08:00
namespace QSB.Animation.Player;
public class AnimatorMirror : MonoBehaviour
{
2022-03-02 19:46:33 -08:00
private const float SmoothTime = 0.05f;
2022-03-02 19:46:33 -08:00
private Animator _from;
private Animator _to;
2022-08-14 12:33:04 +01:00
private NetworkAnimator _networkAnimator;
2022-03-02 19:46:33 -08:00
private readonly Dictionary<string, AnimFloatParam> _floatParams = new();
2021-06-18 22:38:32 +01:00
2022-08-14 12:33:04 +01:00
/// <summary>
/// Initializes the Animator Mirror
/// </summary>
/// <param name="from">The Animator to take the values from.</param>
/// <param name="to">The Animator to set the values on to.</param>
/// <param name="netAnimator">The NetworkAnimator to sync triggers through. Set only if you have auth over "<paramref name="from"/>", otherwise set to null.</param>
public void Init(Animator from, Animator to, NetworkAnimator netAnimator)
2022-03-02 19:46:33 -08:00
{
if (from == null)
{
2022-03-02 19:46:33 -08:00
DebugLog.ToConsole($"Error - Trying to init AnimatorMirror with null \"from\".", MessageType.Error);
}
2021-06-18 22:38:32 +01:00
2022-03-02 19:46:33 -08:00
if (to == null)
{
DebugLog.ToConsole($"Error - Trying to init AnimatorMirror with null \"to\".", MessageType.Error);
}
2021-06-18 22:38:32 +01:00
2022-03-02 19:46:33 -08:00
if (to == null || from == null)
{
// Doing the return this way so you can see if one or both are null
return;
2020-12-02 21:23:01 +00:00
}
2022-03-02 19:46:33 -08:00
_from = from;
_to = to;
if (_from.runtimeAnimatorController == null)
2020-12-02 21:23:01 +00:00
{
2022-03-02 19:46:33 -08:00
_from.runtimeAnimatorController = _to.runtimeAnimatorController;
}
else if (_to.runtimeAnimatorController == null)
{
_to.runtimeAnimatorController = _from.runtimeAnimatorController;
}
2022-08-14 12:33:04 +01:00
_networkAnimator = netAnimator;
2022-03-02 19:46:33 -08:00
RebuildFloatParams();
}
2022-03-02 19:46:33 -08:00
public void Update()
{
if (_to == null || _from == null)
{
return;
}
2022-03-02 19:46:33 -08:00
if (_to.runtimeAnimatorController != _from.runtimeAnimatorController)
2020-12-02 21:23:01 +00:00
{
2022-03-02 19:46:33 -08:00
_to.runtimeAnimatorController = _from.runtimeAnimatorController;
RebuildFloatParams();
2020-12-02 21:23:01 +00:00
}
2020-11-07 21:25:22 +00:00
2022-03-02 19:46:33 -08:00
SyncParams();
2022-08-14 12:05:55 +01:00
SyncLayerWeights();
2022-03-02 19:46:33 -08:00
SmoothFloats();
}
private void SyncParams()
{
foreach (var fromParam in _from.parameters)
2020-12-02 21:23:01 +00:00
{
2022-03-02 19:46:33 -08:00
switch (fromParam.type)
{
2022-03-02 19:46:33 -08:00
case AnimatorControllerParameterType.Float:
_floatParams[fromParam.name].Target = _from.GetFloat(fromParam.name);
break;
2022-08-13 12:31:08 -07:00
case AnimatorControllerParameterType.Int:
_to.SetInteger(fromParam.name, _from.GetInteger(fromParam.name));
break;
2022-08-13 12:31:29 -07:00
case AnimatorControllerParameterType.Bool:
_to.SetBool(fromParam.name, _from.GetBool(fromParam.name));
break;
case AnimatorControllerParameterType.Trigger:
2022-08-13 20:24:48 +01:00
if (_from.GetBool(fromParam.name) && !_to.GetBool(fromParam.name))
{
2022-08-14 12:33:04 +01:00
if (_networkAnimator != null)
{
_networkAnimator.SetTrigger(fromParam.name);
}
_to.SetTrigger(fromParam.name);
}
2022-08-14 12:33:04 +01:00
2022-08-13 12:31:08 -07:00
if (!_from.GetBool(fromParam.name) && _to.GetBool(fromParam.name))
{
2022-08-14 12:33:04 +01:00
if (_networkAnimator != null)
{
_networkAnimator.ResetTrigger(fromParam.name);
}
2022-08-13 12:31:08 -07:00
_to.ResetTrigger(fromParam.name);
}
2022-08-14 12:33:04 +01:00
break;
}
}
2022-03-02 19:46:33 -08:00
}
2022-08-14 12:05:55 +01:00
private void SyncLayerWeights()
{
for (var i = 0; i < _from.layerCount; i++)
{
var weight = _from.GetLayerWeight(i);
_to.SetLayerWeight(i, weight);
}
}
2022-03-02 19:46:33 -08:00
private void SmoothFloats()
{
foreach (var floatParam in _floatParams)
{
2022-03-02 19:46:33 -08:00
var current = floatParam.Value.Smooth(SmoothTime);
_to.SetFloat(floatParam.Key, current);
}
}
public void RebuildFloatParams()
{
_floatParams.Clear();
foreach (var param in _from.parameters.Where(p => p.type == AnimatorControllerParameterType.Float))
{
_floatParams.Add(param.name, new AnimFloatParam());
2020-12-02 21:23:01 +00:00
}
}
2022-08-13 12:31:08 -07:00
}