working on animations
This commit is contained in:
@@ -37,6 +37,7 @@ namespace RebootReality.jelycho.Feedbacks {
|
||||
PaniniProjection m_PaniniProjection;
|
||||
ChromaticAberration m_ChromaticAberration;
|
||||
|
||||
bool m_IsChargeReady;
|
||||
float m_QuickAttackTimer;
|
||||
|
||||
List<CameraShakeFeedback> m_ActiveCameraShakes = new List<CameraShakeFeedback>();
|
||||
@@ -106,6 +107,14 @@ namespace RebootReality.jelycho.Feedbacks {
|
||||
m_QuickAttackTimer = m_QuickAttackIndicatorDuration;
|
||||
}
|
||||
|
||||
public void ShowChargeReadyIndicator() {
|
||||
m_IsChargeReady = true;
|
||||
}
|
||||
|
||||
public void HideChargeReadyIndicator() {
|
||||
m_IsChargeReady = false;
|
||||
}
|
||||
|
||||
//
|
||||
// @MARK: Actor
|
||||
//
|
||||
@@ -127,19 +136,7 @@ namespace RebootReality.jelycho.Feedbacks {
|
||||
}
|
||||
|
||||
m_QuickAttackTimer -= Time.deltaTime;
|
||||
if (m_QuickAttackTimer <= 0.0f) {
|
||||
float chromaticIntensity = m_ChromaticAberration.intensity.value;
|
||||
chromaticIntensity = Mathf.MoveTowards(chromaticIntensity,
|
||||
0.0f,
|
||||
deltaTime * m_QuickAttackIndicatorChromaticDisappearSpeed);
|
||||
m_ChromaticAberration.intensity.value = chromaticIntensity;
|
||||
|
||||
float paniniIntensity = m_PaniniProjection.distance.value;
|
||||
paniniIntensity = Mathf.MoveTowards(paniniIntensity,
|
||||
0.0f,
|
||||
deltaTime * m_QuickAttackIndicatorPaniniDisappearSpeed);
|
||||
m_PaniniProjection.distance.value = paniniIntensity;
|
||||
} else {
|
||||
if (m_QuickAttackTimer > 0.0f || m_IsChargeReady) {
|
||||
float chromaticIntensity = m_ChromaticAberration.intensity.value;
|
||||
chromaticIntensity = Mathf.MoveTowards(chromaticIntensity,
|
||||
m_QuickAttackIndicatorChromaticIntensity,
|
||||
@@ -151,6 +148,18 @@ namespace RebootReality.jelycho.Feedbacks {
|
||||
m_QuickAttackIndicatorPaniniIntensity,
|
||||
deltaTime * m_QuickAttackIndicatorPaniniAppearSpeed);
|
||||
m_PaniniProjection.distance.value = paniniIntensity;
|
||||
} else {
|
||||
float chromaticIntensity = m_ChromaticAberration.intensity.value;
|
||||
chromaticIntensity = Mathf.MoveTowards(chromaticIntensity,
|
||||
0.0f,
|
||||
deltaTime * m_QuickAttackIndicatorChromaticDisappearSpeed);
|
||||
m_ChromaticAberration.intensity.value = chromaticIntensity;
|
||||
|
||||
float paniniIntensity = m_PaniniProjection.distance.value;
|
||||
paniniIntensity = Mathf.MoveTowards(paniniIntensity,
|
||||
0.0f,
|
||||
deltaTime * m_QuickAttackIndicatorPaniniDisappearSpeed);
|
||||
m_PaniniProjection.distance.value = paniniIntensity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using RebootKit.Engine.Simulation;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
|
||||
namespace RebootReality.jelycho.Items {
|
||||
public interface IItemChargeAction {
|
||||
@@ -26,12 +27,21 @@ namespace RebootReality.jelycho.Items {
|
||||
public AnimationClip block;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct ItemActorMountingConfig {
|
||||
public AssetReferenceGameObject actor;
|
||||
[MaxLength(32)] public string slotName;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ItemConfig {
|
||||
public Sprite icon;
|
||||
|
||||
[Header("Mounting")]
|
||||
[MaxLength(32)] public string characterEquippedMountSlotName = "hand_right";
|
||||
|
||||
public ItemActorMountingConfig[] additionalActorsToMount;
|
||||
|
||||
[Header("Character Animations")]
|
||||
public ItemHandsAnimationClipsSet handsAnimationClipsSets;
|
||||
|
||||
|
||||
@@ -13,6 +13,12 @@ namespace RebootReality.jelycho.Main {
|
||||
|
||||
[Header("Player")]
|
||||
[SerializeField] AssetReferenceGameObject m_PlayerActorPrefab;
|
||||
|
||||
protected override void Awake() {
|
||||
base.Awake();
|
||||
|
||||
// Time.timeScale = 0.2f;
|
||||
}
|
||||
|
||||
protected override void OnPlayerBecameReady(ulong clientID) {
|
||||
s_Logger.Info($"Player {clientID} became ready");
|
||||
|
||||
@@ -10,6 +10,7 @@ using RebootReality.jelycho.Items;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
|
||||
namespace RebootReality.jelycho.Player {
|
||||
@@ -134,6 +135,7 @@ namespace RebootReality.jelycho.Player {
|
||||
Inventory.OnItemDropped += OnItemDropped;
|
||||
|
||||
m_PlayerAnimator.onQuickAttackFinished.AddListener(OnQuickAttackFinishedAnimation);
|
||||
m_PlayerAnimator.onChargeReady.AddListener(OnChargeReadyAnimation);
|
||||
}
|
||||
|
||||
void OnDisable() {
|
||||
@@ -141,6 +143,7 @@ namespace RebootReality.jelycho.Player {
|
||||
Inventory.OnItemDropped -= OnItemDropped;
|
||||
|
||||
m_PlayerAnimator.onQuickAttackFinished.RemoveListener(OnQuickAttackFinishedAnimation);
|
||||
m_PlayerAnimator.onChargeReady.RemoveListener(OnChargeReadyAnimation);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -271,7 +274,11 @@ namespace RebootReality.jelycho.Player {
|
||||
itemConfig.chargeAction.OnChargeCancel(this, m_EquippedItem);
|
||||
SetHandsIdleAnimation();
|
||||
}
|
||||
|
||||
|
||||
if (RR.World.Context is WorldContext context) {
|
||||
context.FeedbacksManager.HideChargeReadyIndicator();
|
||||
}
|
||||
|
||||
m_IsCharging = false;
|
||||
} else if (m_EquippedItem.Config.canQuickAttack) {
|
||||
if (m_QuickAttackState == QuickAttackState.None) {
|
||||
@@ -307,6 +314,18 @@ namespace RebootReality.jelycho.Player {
|
||||
}
|
||||
}
|
||||
|
||||
void OnChargeReadyAnimation() {
|
||||
if (!m_IsCharging) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_IsSetupAsOwner) {
|
||||
if (RR.World.Context is WorldContext context) {
|
||||
context.FeedbacksManager.ShowChargeReadyIndicator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SecondaryAction() {
|
||||
if (!m_IsSetupAsOwner) {
|
||||
s_Logger.Error("Cannot perform secondary action when not set up as owner.");
|
||||
@@ -338,48 +357,16 @@ namespace RebootReality.jelycho.Player {
|
||||
//
|
||||
// @MARK: Hands animations
|
||||
//
|
||||
void PlayHandsAnimation(string animationName) {
|
||||
// int hash = Animator.StringToHash(animationName);
|
||||
//
|
||||
// if (!m_Animator.HasState(m_HandsLayerIndex, hash)) {
|
||||
// s_Logger.Error($"Animator does not have state with name {animationName}");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// PlayHandsAnimation(hash);
|
||||
}
|
||||
|
||||
void PlayHandsAnimation(int animationHash) {
|
||||
// m_Animator.CrossFade(animationHash, 0.0f, m_HandsLayerIndex);
|
||||
//
|
||||
// if (RR.IsServer()) {
|
||||
// PlayerPlayHandsAnimationEvent handsAnimationEvent = new PlayerPlayHandsAnimationEvent {
|
||||
// AnimationHash = animationHash
|
||||
// };
|
||||
// SendActorEvent((byte)PlayerActorEvents.PlayHandsAnimation, ref handsAnimationEvent);
|
||||
// } else {
|
||||
// PlayerActorRequestHandsAnimationCommand handsAnimationCommand =
|
||||
// new PlayerActorRequestHandsAnimationCommand {
|
||||
// AnimationHash = animationHash
|
||||
// };
|
||||
// SendActorCommand((byte) PlayerActorCommands.RequestHandsAnimation, ref handsAnimationCommand);
|
||||
// }
|
||||
}
|
||||
|
||||
void SetHandsIdleAnimation() {
|
||||
m_PlayerAnimator.PlayHandsIdle();
|
||||
}
|
||||
|
||||
void SetChargingAnimation() {
|
||||
if (m_EquippedItem != null) {
|
||||
// PlayHandsAnimation(m_EquippedItem.Config.chargingAnimation);
|
||||
}
|
||||
m_PlayerAnimator.PlayCharging();
|
||||
}
|
||||
|
||||
void SetChargedUseAnimation() {
|
||||
if (m_EquippedItem != null) {
|
||||
// PlayHandsAnimation(m_EquippedItem.Config.chargedUseAnimation);
|
||||
}
|
||||
m_PlayerAnimator.PlayChargedUse();
|
||||
}
|
||||
|
||||
void PlayQuickAttackAnimation(int combo) {
|
||||
@@ -769,6 +756,7 @@ namespace RebootReality.jelycho.Player {
|
||||
|
||||
if (m_EquippedItem != null) {
|
||||
m_PlayerAnimator.SetHandsAnimationSet(m_EquippedItem.Config.handsAnimationClipsSets);
|
||||
SpawnAdditionalEquippedItemActors();
|
||||
} else {
|
||||
m_PlayerAnimator.SetHandsAnimationSet(null);
|
||||
}
|
||||
@@ -776,6 +764,13 @@ namespace RebootReality.jelycho.Player {
|
||||
SetHandsIdleAnimation();
|
||||
}
|
||||
|
||||
void SpawnAdditionalEquippedItemActors() {
|
||||
foreach (ItemActorMountingConfig localMountInfo in m_EquippedItem.Config.additionalActorsToMount) {
|
||||
Actor actor = RR.SpawnLocalOnlyActor(localMountInfo.actor, Vector3.zero, Quaternion.identity);
|
||||
actor.MountTo(this, localMountInfo.slotName);
|
||||
}
|
||||
}
|
||||
|
||||
public void WarpTo(Vector3 position) {
|
||||
if (!RR.IsServer()) {
|
||||
s_Logger.Error("Only the server can warp players.");
|
||||
@@ -789,14 +784,7 @@ namespace RebootReality.jelycho.Player {
|
||||
// @MARK: Common
|
||||
//
|
||||
void TickCharacterRotation() {
|
||||
// @TODO: restore old delayed character rotation
|
||||
m_Locomotion.YawRotation = m_Camera.Yaw;
|
||||
|
||||
float3 targetCharacterForward = math.normalize(LookDirection.With(y: 0.0f));
|
||||
float3 currentCharacterForward = math.normalize(m_CharacterForwardTransform.forward.With(y: 0.0f));
|
||||
|
||||
float angleRad = math.acos(math.clamp(math.dot(targetCharacterForward, currentCharacterForward) / (math.length(targetCharacterForward) * math.length(currentCharacterForward)), -1f, 1f));
|
||||
float angleDeg = math.degrees(angleRad);
|
||||
float angleDeg = Mathf.DeltaAngle(m_Camera.Yaw, m_Locomotion.YawRotation);
|
||||
|
||||
bool rotateCharacter = false;
|
||||
float rotateCharacterSpeed = m_CharacterRotateSpeed;
|
||||
@@ -820,11 +808,9 @@ namespace RebootReality.jelycho.Player {
|
||||
if (rotateCharacter) {
|
||||
m_CharacterTurnVelocity = rotateCharacterSpeed * Time.deltaTime;
|
||||
|
||||
Vector3 newForward = Vector3.RotateTowards(currentCharacterForward,
|
||||
targetCharacterForward,
|
||||
math.radians(m_CharacterTurnVelocity),
|
||||
0.0f);
|
||||
m_CharacterForwardTransform.forward = newForward;
|
||||
m_Locomotion.YawRotation = Mathf.MoveTowardsAngle(m_Locomotion.YawRotation,
|
||||
m_Camera.Yaw,
|
||||
m_CharacterTurnVelocity);
|
||||
}
|
||||
|
||||
// Aim Target adjustment
|
||||
@@ -925,6 +911,9 @@ namespace RebootReality.jelycho.Player {
|
||||
float forwardNormalized = localVelocity.z / m_Locomotion.runSpeed;
|
||||
float rightNormalized = localVelocity.x / m_Locomotion.runSpeed;
|
||||
|
||||
forwardNormalized = math.clamp(forwardNormalized, -1.0f, 1.0f);
|
||||
rightNormalized = math.clamp(rightNormalized, -1.0f, 1.0f);
|
||||
|
||||
float turnVelocity = m_CharacterTurnVelocity;
|
||||
if (math.abs(forwardNormalized) > 0.01f ||
|
||||
math.abs(rightNormalized) > 0.01f ||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using RebootKit.Engine.Animations;
|
||||
using RebootReality.jelycho.Items;
|
||||
using Unity.Mathematics;
|
||||
using UnityEditor.Search;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Animations;
|
||||
using UnityEngine.Events;
|
||||
@@ -16,13 +19,126 @@ namespace RebootReality.jelycho.Player {
|
||||
public bool IsGrounded;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class BasicCharacterLocomotionReAnimatorNode : IReAnimatorNode {
|
||||
[field: SerializeField] public string Name { get; private set; }
|
||||
|
||||
[SerializeField] AnimationClip m_IdleClip;
|
||||
[SerializeField] AnimationClip m_RunForwardClip;
|
||||
[SerializeField] AnimationClip m_RunBackwardsClip;
|
||||
[SerializeField] AnimationClip m_StrafeRightClip;
|
||||
[SerializeField] AnimationClip m_StrafeLeftClip;
|
||||
[SerializeField] AnimationClip m_TurnRightClip;
|
||||
[SerializeField] AnimationClip m_TurnLeftClip;
|
||||
[SerializeField] float m_TransitionSpeed = 5.0f;
|
||||
[SerializeField, Range(0.0f, 1.0f)] float m_ForceIdleMagnitudeThreshold = 0.2f;
|
||||
|
||||
AnimationMixerPlayable m_Mixer;
|
||||
float2 m_TargetInput;
|
||||
float2 m_CurrentInput;
|
||||
|
||||
float m_Turning;
|
||||
|
||||
public void Tick(float deltaTime) {
|
||||
if (m_TransitionSpeed > 0.0f) {
|
||||
m_CurrentInput = Vector2.MoveTowards(m_CurrentInput,
|
||||
m_TargetInput,
|
||||
m_TransitionSpeed * deltaTime);
|
||||
} else {
|
||||
m_CurrentInput = m_TargetInput;
|
||||
}
|
||||
|
||||
if (math.length(m_CurrentInput) <= m_ForceIdleMagnitudeThreshold) {
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
m_Mixer.SetInputWeight(i, 0.0f);
|
||||
}
|
||||
|
||||
if (m_Turning > 0.1f) {
|
||||
m_Mixer.SetInputWeight(5, 1.0f);
|
||||
} else if (m_Turning < -0.1f) {
|
||||
m_Mixer.SetInputWeight(6, 1.0f);
|
||||
} else {
|
||||
m_Mixer.SetInputWeight(0, 1.0f);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float inputMagnitude = math.length(m_CurrentInput);
|
||||
float2 inputNormalized = math.normalizesafe(m_CurrentInput);
|
||||
|
||||
inputMagnitude = math.min(1.0f, inputMagnitude);
|
||||
|
||||
float forwardWeight = math.max(0.0f, math.dot(inputNormalized, new float2(0, 1)) * inputMagnitude);
|
||||
float backwardsWeight = math.max(0.0f, math.dot(inputNormalized, new float2(0, -1)) * inputMagnitude);
|
||||
float rightWeight = math.max(0.0f, math.dot(inputNormalized, new float2(1, 0)) * inputMagnitude);
|
||||
float leftWeight = math.max(0.0f, math.dot(inputNormalized, new float2(-1, 0)) * inputMagnitude);
|
||||
|
||||
float totalWeight = forwardWeight + backwardsWeight + rightWeight + leftWeight;
|
||||
|
||||
if (totalWeight > 1.0f) {
|
||||
forwardWeight /= totalWeight;
|
||||
backwardsWeight /= totalWeight;
|
||||
rightWeight /= totalWeight;
|
||||
leftWeight /= totalWeight;
|
||||
totalWeight = 1.0f;
|
||||
}
|
||||
|
||||
float idleWeight = math.max(0.0f, 1.0f - totalWeight);
|
||||
|
||||
m_Mixer.SetInputWeight(0, idleWeight);
|
||||
m_Mixer.SetInputWeight(1, forwardWeight);
|
||||
m_Mixer.SetInputWeight(2, backwardsWeight);
|
||||
m_Mixer.SetInputWeight(3, rightWeight);
|
||||
m_Mixer.SetInputWeight(4, leftWeight);
|
||||
m_Mixer.SetInputWeight(5, 0.0f);
|
||||
m_Mixer.SetInputWeight(6, 0.0f);
|
||||
}
|
||||
|
||||
public IPlayable Build(PlayableGraph graph) {
|
||||
m_Mixer = AnimationMixerPlayable.Create(graph, 7);
|
||||
|
||||
AnimationClipPlayable idlePlayable = AnimationClipPlayable.Create(graph, m_IdleClip);
|
||||
AnimationClipPlayable runForwardPlayable = AnimationClipPlayable.Create(graph, m_RunForwardClip);
|
||||
AnimationClipPlayable runBackwardsPlayable = AnimationClipPlayable.Create(graph, m_RunBackwardsClip);
|
||||
AnimationClipPlayable strafeRightPlayable = AnimationClipPlayable.Create(graph, m_StrafeRightClip);
|
||||
AnimationClipPlayable strafeLeftPlayable = AnimationClipPlayable.Create(graph, m_StrafeLeftClip);
|
||||
AnimationClipPlayable turnRightPlayable = AnimationClipPlayable.Create(graph, m_TurnRightClip);
|
||||
AnimationClipPlayable turnLeftPlayable = AnimationClipPlayable.Create(graph, m_TurnLeftClip);
|
||||
|
||||
m_Mixer.ConnectInput(0, idlePlayable, 0, 1.0f);
|
||||
m_Mixer.ConnectInput(1, runForwardPlayable, 0, 0.0f);
|
||||
m_Mixer.ConnectInput(2, runBackwardsPlayable, 0, 0.0f);
|
||||
m_Mixer.ConnectInput(3, strafeRightPlayable, 0, 0.0f);
|
||||
m_Mixer.ConnectInput(4, strafeLeftPlayable, 0, 0.0f);
|
||||
m_Mixer.ConnectInput(5, turnRightPlayable, 0, 0.0f);
|
||||
m_Mixer.ConnectInput(6, turnLeftPlayable, 0, 0.0f);
|
||||
|
||||
return m_Mixer;
|
||||
}
|
||||
|
||||
public bool TryFindChild(string name, out IReAnimatorNode node) {
|
||||
node = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetInput(float2 input, float turning) {
|
||||
m_TargetInput = input;
|
||||
m_Turning = turning;
|
||||
}
|
||||
}
|
||||
|
||||
public class CharacterHandsReAnimatorNode : IReAnimatorNode {
|
||||
enum State {
|
||||
None,
|
||||
Idle,
|
||||
QuickAttack
|
||||
QuickAttack,
|
||||
Charging,
|
||||
ChargedIdle,
|
||||
Charged,
|
||||
ChargedUse
|
||||
}
|
||||
|
||||
|
||||
[field: SerializeField] public string Name { get; private set; }
|
||||
|
||||
PlayableGraph m_Graph;
|
||||
@@ -34,19 +150,33 @@ namespace RebootReality.jelycho.Player {
|
||||
State m_State;
|
||||
|
||||
public event Action OnQuickAttackAnimationFinished = delegate { };
|
||||
public event Action OnCharged = delegate { };
|
||||
|
||||
public void Tick(float deltaTime) {
|
||||
switch (m_State) {
|
||||
|
||||
case State.QuickAttack: {
|
||||
if (m_CurrentPlayable.GetTime() >= m_CurrentPlayable.GetAnimationClip().length &&
|
||||
m_CurrentPlayable.GetPlayState() == PlayState.Playing) {
|
||||
if (IsCurrentClipFinished() && m_CurrentPlayable.GetPlayState() == PlayState.Playing) {
|
||||
m_CurrentPlayable.Pause();
|
||||
OnQuickAttackAnimationFinished?.Invoke();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case State.Charging: {
|
||||
if (IsCurrentClipFinished()) {
|
||||
SetChargedIdle();
|
||||
OnCharged?.Invoke();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case State.ChargedUse: {
|
||||
if (IsCurrentClipFinished()) {
|
||||
SetIdle();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,12 +193,12 @@ namespace RebootReality.jelycho.Player {
|
||||
|
||||
public void UpdateClips(ItemHandsAnimationClipsSet clipsSet) {
|
||||
m_ClipsSet = clipsSet;
|
||||
|
||||
|
||||
if (clipsSet == null) {
|
||||
m_State = State.None;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SetIdle();
|
||||
}
|
||||
|
||||
@@ -80,7 +210,7 @@ namespace RebootReality.jelycho.Player {
|
||||
AnimationClip clip = m_ClipsSet.quickAttacks[combo % m_ClipsSet.quickAttacks.Length];
|
||||
|
||||
m_CurrentPlayable = AnimationClipPlayable.Create(m_Graph, clip);
|
||||
|
||||
|
||||
m_Mixer.DisconnectInput(0);
|
||||
m_Mixer.ConnectInput(0, m_CurrentPlayable, 0, 1.0f);
|
||||
|
||||
@@ -92,46 +222,90 @@ namespace RebootReality.jelycho.Player {
|
||||
if (m_ClipsSet == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_CurrentPlayable = AnimationClipPlayable.Create(m_Graph, m_ClipsSet.idle);
|
||||
m_Mixer.DisconnectInput(0);
|
||||
m_Mixer.ConnectInput(0, m_CurrentPlayable, 0, 1.0f);
|
||||
|
||||
|
||||
m_CurrentPlayable.Play();
|
||||
m_State = State.Idle;
|
||||
}
|
||||
|
||||
public void SetCharging() {
|
||||
if (m_ClipsSet == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_CurrentPlayable = AnimationClipPlayable.Create(m_Graph, m_ClipsSet.charging);
|
||||
m_Mixer.DisconnectInput(0);
|
||||
m_Mixer.ConnectInput(0, m_CurrentPlayable, 0, 1.0f);
|
||||
|
||||
m_CurrentPlayable.Play();
|
||||
m_State = State.Charging;
|
||||
}
|
||||
|
||||
public void SetChargedIdle() {
|
||||
if (m_ClipsSet == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_CurrentPlayable = AnimationClipPlayable.Create(m_Graph, m_ClipsSet.chargedIdle);
|
||||
m_Mixer.DisconnectInput(0);
|
||||
m_Mixer.ConnectInput(0, m_CurrentPlayable, 0, 1.0f);
|
||||
|
||||
m_CurrentPlayable.Play();
|
||||
m_State = State.ChargedIdle;
|
||||
}
|
||||
|
||||
public void PlayChargedUse() {
|
||||
if (m_ClipsSet == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_CurrentPlayable = AnimationClipPlayable.Create(m_Graph, m_ClipsSet.chargedUse);
|
||||
m_Mixer.DisconnectInput(0);
|
||||
m_Mixer.ConnectInput(0, m_CurrentPlayable, 0, 1.0f);
|
||||
|
||||
m_CurrentPlayable.Play();
|
||||
m_State = State.ChargedUse;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
bool IsCurrentClipFinished() {
|
||||
return m_CurrentPlayable.GetTime() >= m_CurrentPlayable.GetAnimationClip().length;
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerAnimator : MonoBehaviour {
|
||||
[SerializeField] ReAnimator m_ReAnimator;
|
||||
|
||||
MixerNode m_LocomotionRootMixer;
|
||||
BlendTree2DNode m_GroundBlendTree;
|
||||
BasicCharacterLocomotionReAnimatorNode m_GroundBlendTree;
|
||||
CharacterHandsReAnimatorNode m_Hands;
|
||||
|
||||
// @TODO: for some reason `SetLocomotionParams` is called before awake
|
||||
bool m_IsReady = false;
|
||||
|
||||
public UnityEvent onQuickAttackFinished = new UnityEvent();
|
||||
public UnityEvent onChargeReady = new UnityEvent();
|
||||
|
||||
void Awake() {
|
||||
m_LocomotionRootMixer = m_ReAnimator.FindNode<MixerNode>("locomotion_root");
|
||||
m_LocomotionRootMixer.SetInputWeight(0, 1.0f);
|
||||
m_LocomotionRootMixer.SetInputWeight(1, 0.0f);
|
||||
|
||||
m_GroundBlendTree = m_ReAnimator.FindNode<BlendTree2DNode>("locomotion_ground");
|
||||
m_GroundBlendTree.SetDirection(new float2(0, 1));
|
||||
|
||||
m_GroundBlendTree = m_ReAnimator.FindNode<BasicCharacterLocomotionReAnimatorNode>("locomotion_ground");
|
||||
m_GroundBlendTree.SetInput(new float2(0, 0), 0.0f);
|
||||
|
||||
m_Hands = m_ReAnimator.FindNode<CharacterHandsReAnimatorNode>("hands");
|
||||
m_Hands.OnQuickAttackAnimationFinished += () => { onQuickAttackFinished?.Invoke(); };
|
||||
m_Hands.OnCharged += () => { onChargeReady?.Invoke(); };
|
||||
|
||||
m_IsReady = true;
|
||||
}
|
||||
|
||||
void Update() {
|
||||
void Update() { }
|
||||
|
||||
}
|
||||
|
||||
public void SetLocomotionParams(PlayerLocomotionAnimatorParams locomotionParams) {
|
||||
if (!m_IsReady) {
|
||||
return;
|
||||
@@ -142,7 +316,7 @@ namespace RebootReality.jelycho.Player {
|
||||
|
||||
float2 groundBlendDirection = new float2(locomotionParams.VelocityRightNormalized,
|
||||
locomotionParams.VelocityForwardNormalized);
|
||||
m_GroundBlendTree.SetDirection(groundBlendDirection);
|
||||
m_GroundBlendTree.SetInput(groundBlendDirection, locomotionParams.TurnVelocity);
|
||||
}
|
||||
|
||||
public void SetHandsAnimationSet(ItemHandsAnimationClipsSet clipsSet) {
|
||||
@@ -150,7 +324,7 @@ namespace RebootReality.jelycho.Player {
|
||||
m_ReAnimator.SetLayerWeight(1, 0.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_ReAnimator.SetLayerWeight(1, 1.0f);
|
||||
m_Hands.UpdateClips(clipsSet);
|
||||
}
|
||||
@@ -162,5 +336,13 @@ namespace RebootReality.jelycho.Player {
|
||||
public void PlayHandsIdle() {
|
||||
m_Hands.SetIdle();
|
||||
}
|
||||
|
||||
public void PlayCharging() {
|
||||
m_Hands.SetCharging();
|
||||
}
|
||||
|
||||
public void PlayChargedUse() {
|
||||
m_Hands.PlayChargedUse();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user