您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
185 行
7.9 KiB
185 行
7.9 KiB
using System.Collections.Generic;
|
|
using System.Security.Cryptography;
|
|
using UnityEngine;
|
|
using UnityEngine.Playables;
|
|
using UnityEngine.Animations;
|
|
|
|
public class CharacterAnimatorController {
|
|
|
|
public CharacterAnimatorController(PlayableGraph graph, RuntimeAnimatorController animatorController)
|
|
{
|
|
m_animatorController = AnimatorControllerPlayable.Create(graph, animatorController);
|
|
|
|
// Find valid parameters in animatorcontroller
|
|
var animStateParams = new List<AnimStateParams>();
|
|
var actionStateParams = new List<ActionStateParams>();
|
|
m_supportedActionTriggers = new int[(int)CharacterPredictedState.StateData.Action.NumActions];
|
|
for (int i = 0; i < m_animatorController.GetParameterCount(); i++)
|
|
{
|
|
AnimatorControllerParameter param = m_animatorController.GetParameter(i);
|
|
|
|
switch (param.type)
|
|
{
|
|
case AnimatorControllerParameterType.Bool:
|
|
{
|
|
CharacterPredictedState.StateData.LocoState animState;
|
|
if (s_charLocoStateHashes.TryGetValue(param.nameHash, out animState))
|
|
{
|
|
var p = new AnimStateParams();
|
|
p.state = animState;
|
|
p.hash = param.nameHash;
|
|
animStateParams.Add(p);
|
|
continue;
|
|
}
|
|
|
|
CharacterPredictedState.StateData.Action action;
|
|
if (s_actionStateHashes.TryGetValue(param.nameHash, out action))
|
|
{
|
|
var p = new ActionStateParams();
|
|
p.action = action;
|
|
p.hash = param.nameHash;
|
|
actionStateParams.Add(p);
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
case AnimatorControllerParameterType.Trigger:
|
|
{
|
|
CharacterPredictedState.StateData.Action action;
|
|
if (s_actionTriggerHashes.TryGetValue(param.nameHash, out action))
|
|
{
|
|
m_supportedActionTriggers[(int)action] = param.nameHash;
|
|
continue;
|
|
}
|
|
|
|
if (param.nameHash == s_resetHash)
|
|
{
|
|
m_resetSupported = true;
|
|
continue;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
m_supportedAnimStates = animStateParams.ToArray();
|
|
m_supportedActionStates = actionStateParams.ToArray();
|
|
}
|
|
|
|
public Playable GetRootPlayable()
|
|
{
|
|
return m_animatorController;
|
|
}
|
|
|
|
public void Update(ref CharAnimState animState)
|
|
{
|
|
// Set supported animation state bools
|
|
for (var i = 0; i < m_supportedAnimStates.Length; i++)
|
|
m_animatorController.SetBool(m_supportedAnimStates[i].hash, animState.charLocoState == m_supportedAnimStates[i].state);
|
|
|
|
// Set supported action state bools
|
|
for (var i = 0; i < m_supportedActionStates.Length; i++)
|
|
m_animatorController.SetBool(m_supportedActionStates[i].hash, animState.charAction == m_supportedActionStates[i].action);
|
|
|
|
// Set supported triggers
|
|
if (animState.charAction != m_lastActionTriggered || animState.charActionTick != lastActionTick)
|
|
{
|
|
// Clear last trigger
|
|
if (m_lastActionTriggered != CharacterPredictedState.StateData.Action.None)
|
|
{
|
|
m_animatorController.ResetTrigger(m_supportedActionTriggers[(int)m_lastActionTriggered]);
|
|
}
|
|
|
|
m_lastActionTriggered = CharacterPredictedState.StateData.Action.None;
|
|
|
|
// Trigger new action trigger if it is supported
|
|
if (m_supportedActionTriggers[(int)animState.charAction] != 0)
|
|
{
|
|
m_lastActionTriggered = animState.charAction;
|
|
m_animatorController.SetTrigger(m_supportedActionTriggers[(int)m_lastActionTriggered]);
|
|
}
|
|
}
|
|
lastActionTick = animState.charActionTick;
|
|
|
|
m_animatorController.SetBool(m_sprintState, animState.sprinting == 1);
|
|
|
|
if (animState.damageTick > m_lastReactionTick + m_waitFor)
|
|
{
|
|
m_animatorController.SetTrigger(m_hitReaction);
|
|
m_lastReactionTick = animState.damageTick;
|
|
|
|
Random.InitState(animState.damageTick);
|
|
m_waitFor = Random.Range(4, 6);
|
|
}
|
|
}
|
|
|
|
|
|
public void Start()
|
|
{
|
|
if (m_resetSupported)
|
|
m_animatorController.SetTrigger(s_resetHash);
|
|
m_animatorController.Play();
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
m_animatorController.Pause();
|
|
}
|
|
|
|
|
|
struct AnimStateParams
|
|
{
|
|
public CharacterPredictedState.StateData.LocoState state;
|
|
public int hash;
|
|
}
|
|
|
|
struct ActionStateParams
|
|
{
|
|
public CharacterPredictedState.StateData.Action action;
|
|
public int hash;
|
|
}
|
|
|
|
readonly static int s_resetHash = Animator.StringToHash("Trigger_Reset");
|
|
|
|
readonly static Dictionary<int, CharacterPredictedState.StateData.LocoState> s_charLocoStateHashes = new Dictionary<int, CharacterPredictedState.StateData.LocoState>() {
|
|
{ Animator.StringToHash("AnimState_Stand"), CharacterPredictedState.StateData.LocoState.Stand },
|
|
{ Animator.StringToHash("AnimState_Run"), CharacterPredictedState.StateData.LocoState.GroundMove },
|
|
{ Animator.StringToHash("AnimState_Jump"), CharacterPredictedState.StateData.LocoState.Jump },
|
|
{ Animator.StringToHash("AnimState_DoubleJump"), CharacterPredictedState.StateData.LocoState.DoubleJump },
|
|
{ Animator.StringToHash("AnimState_InAir"), CharacterPredictedState.StateData.LocoState.InAir },
|
|
};
|
|
|
|
readonly static Dictionary<int, CharacterPredictedState.StateData.Action> s_actionStateHashes = new Dictionary<int, CharacterPredictedState.StateData.Action>() {
|
|
{ Animator.StringToHash("Action_None"), CharacterPredictedState.StateData.Action.None },
|
|
{ Animator.StringToHash("Action_PrimaryFire"), CharacterPredictedState.StateData.Action.PrimaryFire },
|
|
{ Animator.StringToHash("Action_SecondaryFire"), CharacterPredictedState.StateData.Action.SecondaryFire },
|
|
{ Animator.StringToHash("Action_Reloading"), CharacterPredictedState.StateData.Action.Reloading },
|
|
{ Animator.StringToHash("Action_Melee"), CharacterPredictedState.StateData.Action.Melee },
|
|
};
|
|
|
|
readonly static Dictionary<int, CharacterPredictedState.StateData.Action> s_actionTriggerHashes = new Dictionary<int, CharacterPredictedState.StateData.Action>() {
|
|
{ Animator.StringToHash("TriggerAction_None"), CharacterPredictedState.StateData.Action.None },
|
|
{ Animator.StringToHash("TriggerAction_PrimaryFire"), CharacterPredictedState.StateData.Action.PrimaryFire },
|
|
{ Animator.StringToHash("TriggerAction_SecondaryFire"), CharacterPredictedState.StateData.Action.SecondaryFire },
|
|
{ Animator.StringToHash("TriggerAction_Reloading"), CharacterPredictedState.StateData.Action.Reloading },
|
|
{ Animator.StringToHash("TriggerAction_Melee"), CharacterPredictedState.StateData.Action.Melee },
|
|
};
|
|
|
|
readonly int m_sprintState = Animator.StringToHash("State_Sprint");
|
|
readonly int m_hitReaction = Animator.StringToHash("Hit_Reaction");
|
|
|
|
int m_lastReactionTick;
|
|
int m_waitFor;
|
|
|
|
|
|
AnimatorControllerPlayable m_animatorController;
|
|
AnimStateParams[] m_supportedAnimStates;
|
|
ActionStateParams[] m_supportedActionStates;
|
|
int[] m_supportedActionTriggers;
|
|
bool m_resetSupported;
|
|
|
|
|
|
CharacterPredictedState.StateData.Action m_lastActionTriggered = CharacterPredictedState.StateData.Action.None;
|
|
int lastActionTick;
|
|
}
|
|
|