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 ;
2020-02-18 21:39:18 +01:00
using System.Linq ;
using UnityEngine ;
2020-02-18 11:08:08 +01:00
2022-03-02 19:46:33 -08:00
namespace QSB.Animation.Player ;
public class AnimatorMirror : MonoBehaviour
2020-02-18 11:08:08 +01:00
{
2022-03-02 19:46:33 -08:00
private const float SmoothTime = 0.05f ;
2020-02-18 11:08:08 +01:00
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 ;
2020-02-18 21:39:18 +01:00
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-02-24 22:04:54 -08:00
{
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
}
2020-02-18 11:08:08 +01: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 ;
}
2020-02-18 11:08:08 +01:00
2022-08-14 12:33:04 +01:00
_networkAnimator = netAnimator ;
2022-03-02 19:46:33 -08:00
RebuildFloatParams ( ) ;
}
2022-02-24 22:04:54 -08:00
2022-03-02 19:46:33 -08:00
public void Update ( )
{
if ( _to = = null | | _from = = null )
{
return ;
2022-02-27 04:40:44 -08:00
}
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-02-27 04:40:44 -08:00
{
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 ;
2022-08-13 20:07:13 +01:00
case AnimatorControllerParameterType . Trigger :
2022-08-13 20:24:48 +01:00
if ( _from . GetBool ( fromParam . name ) & & ! _to . GetBool ( fromParam . name ) )
2022-08-13 20:07:13 +01:00
{
2022-08-14 12:33:04 +01:00
if ( _networkAnimator ! = null )
{
_networkAnimator . SetTrigger ( fromParam . name ) ;
}
2022-08-13 20:07:13 +01:00
_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
2022-08-13 20:07:13 +01:00
break ;
2022-02-27 04:40:44 -08:00
}
2022-02-24 22:04:54 -08:00
}
2022-03-02 19:46:33 -08:00
}
2022-02-24 22:04:54 -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-02-24 22:04:54 -08:00
{
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
}