animations mechanism refactor

This commit is contained in:
Vladimir Koshevarov
2023-02-28 16:01:51 +02:00
parent c62b8ddd32
commit dad45af7a9
5 changed files with 71 additions and 68 deletions
@@ -240,7 +240,7 @@ AnimatorState:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: Stand To Sit m_Name: StandToSit
m_Speed: 1 m_Speed: 1
m_CycleOffset: 0 m_CycleOffset: 0
m_Transitions: m_Transitions:
@@ -33901,7 +33901,7 @@ AnimationClip:
m_LoopBlend: 0 m_LoopBlend: 0
m_LoopBlendOrientation: 0 m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 1 m_LoopBlendPositionY: 1
m_LoopBlendPositionXZ: 1 m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0 m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 0 m_KeepOriginalPositionY: 0
m_KeepOriginalPositionXZ: 0 m_KeepOriginalPositionXZ: 0
@@ -36,7 +36,7 @@ public class ConversationController : MonoBehaviour
ApplyActionOnPlayer(_selectedAction); ApplyActionOnPlayer(_selectedAction);
}); });
Player.Instance.allowMovement = false; //Player.Instance.allowMovement = false;
RemoveChoices(); RemoveChoices();
_title.text = title; _title.text = title;
gameObject.SetActive(true); gameObject.SetActive(true);
@@ -83,6 +83,6 @@ public class ConversationController : MonoBehaviour
RemoveChoices(); RemoveChoices();
gameObject.SetActive(false); gameObject.SetActive(false);
Time.timeScale = 1; Time.timeScale = 1;
Player.Instance.allowMovement = true; //Player.Instance.allowMovement = true;
} }
} }
+1 -1
View File
@@ -6,6 +6,6 @@ public class Bed : BaseInteractableObject
public override void Interact(Player player) public override void Interact(Player player)
{ {
Debug.Log("Sitting"); Debug.Log("Sitting");
player.SetPlayerState(ActionStates.Sitting); player.SetPlayerAnimation(AnimationStates.Sitting);
} }
} }
+66 -63
View File
@@ -1,11 +1,34 @@
using Assets.Scripts.Actions.Interfaces; using Assets.Scripts.Actions.Interfaces;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using UnityEngine; using UnityEngine;
using UnityEngine.AI; using UnityEngine.AI;
public class BlockingAnimation : Attribute
{
}
public enum Tasks { Move, Interact, Rotate }; public enum Tasks { Move, Interact, Rotate };
public enum TaskStatus { Waiting, InProgress, Complete }; public enum TaskStatus { Waiting, InProgress, Complete };
public enum ActionStates { Idle, Walking, Sleeping, Sitting, Standing }; public enum AnimationStates
{
[EnumMember(Value = "Idle")]
Idle,
[EnumMember(Value = "Move")]
Walking,
[EnumMember(Value = "Sleeping")]
Sleeping,
[EnumMember(Value = "StandToSit")]
[BlockingAnimation]
Sitting,
[EnumMember(Value = "SitToStand")]
[BlockingAnimation]
Standing
};
public class Player : MonoBehaviour public class Player : MonoBehaviour
{ {
@@ -16,8 +39,8 @@ public class Player : MonoBehaviour
[SerializeField] [SerializeField]
public Animator _animator; public Animator _animator;
public bool allowMovement = true; private bool _isAllowMovement;
private ActionStates _currentState; private AnimationStates _currentAnimation;
private Vector3 _groundDeltaPosition; private Vector3 _groundDeltaPosition;
public Dictionary<StatsId, Stat> PlayerStats; public Dictionary<StatsId, Stat> PlayerStats;
@@ -26,9 +49,6 @@ public class Player : MonoBehaviour
private readonly Queue<PlayerTasks> _tasks = new Queue<PlayerTasks>(); private readonly Queue<PlayerTasks> _tasks = new Queue<PlayerTasks>();
private PlayerTasks _currentTask; private PlayerTasks _currentTask;
private const string FALL_DOWN = "Fall";
private const string SIT_DOWN = "SitDown";
private const string WALK = "Walk";
private const string WALK_VELOCITY = "WalkVelocity"; private const string WALK_VELOCITY = "WalkVelocity";
private bool _isInAnimation = false; private bool _isInAnimation = false;
@@ -43,26 +63,22 @@ public class Player : MonoBehaviour
} }
private void Start() private void Start()
{ {
TimeManager.OnMinuteChanged += UpdatePlayerState; TimeManager.OnMinuteChanged += UpdateStatsByClock;
allowMovement = true; _isAllowMovement = true;
_navAgent.updatePosition = false; _navAgent.updatePosition = false;
PlayerStats = GameManager.Instance.PlayerStats; PlayerStats = GameManager.Instance.PlayerStats;
} }
private void OnDestroy() private void OnDestroy()
{ {
TimeManager.OnMinuteChanged -= UpdatePlayerState; TimeManager.OnMinuteChanged -= UpdateStatsByClock;
} }
private void Update() private void Update()
{ {
if (_isInAnimation) if (IsBlockingAnimation(_currentAnimation))
{ {
if (!isAnimationStatePlaying(0, "SitToStand")) if (IsAnimationStatePlaying(0, GetEnumMemberValue(_currentAnimation)))
{
_isInAnimation = false;
}
else
return; return;
} }
@@ -80,9 +96,9 @@ public class Player : MonoBehaviour
_currentTask.UpdateStatus(Rotate(_currentTask.TagretObject._playerArrivePoint.forward)); _currentTask.UpdateStatus(Rotate(_currentTask.TagretObject._playerArrivePoint.forward));
break; break;
case Tasks.Move: case Tasks.Move:
if (_currentState == ActionStates.Sitting) if (_currentAnimation == AnimationStates.Sitting)
{ {
SetPlayerState(ActionStates.Standing); SetPlayerAnimation(AnimationStates.Standing);
return; return;
} }
_navAgent.SetDestination(_currentTask.TagretObject._playerArrivePoint.position); _navAgent.SetDestination(_currentTask.TagretObject._playerArrivePoint.position);
@@ -105,7 +121,7 @@ public class Player : MonoBehaviour
private TaskStatus MoveToPoint() private TaskStatus MoveToPoint()
{ {
SetPlayerState(ActionStates.Walking); SetPlayerAnimation(AnimationStates.Walking);
var worldDeltaPosition = _navAgent.nextPosition - transform.position; var worldDeltaPosition = _navAgent.nextPosition - transform.position;
_groundDeltaPosition.x = Vector3.Dot(transform.right, worldDeltaPosition); _groundDeltaPosition.x = Vector3.Dot(transform.right, worldDeltaPosition);
@@ -121,9 +137,9 @@ public class Player : MonoBehaviour
{ {
if (Vector3.Distance(destination, _navAgent.transform.position) <= _navAgent.radius) if (Vector3.Distance(destination, _navAgent.transform.position) <= _navAgent.radius)
{ {
if (!_navAgent.hasPath || _navAgent.velocity.sqrMagnitude == 0f) if (!_navAgent.hasPath || _navAgent.velocity.sqrMagnitude < 0.2f)
{ {
SetPlayerState(ActionStates.Idle); SetPlayerAnimation(AnimationStates.Idle);
return true; return true;
} }
} }
@@ -150,36 +166,17 @@ public class Player : MonoBehaviour
return TaskStatus.Complete; return TaskStatus.Complete;
} }
public void SetPlayerState(ActionStates newState) public void SetPlayerAnimation(AnimationStates newState)
{ {
if (newState == _currentState) if (newState == _currentAnimation)
{ {
return; return;
} }
_isInAnimation = true; _animator.Play(GetEnumMemberValue(newState));
switch (newState) _currentAnimation = newState;
{
case ActionStates.Idle:
_animator.SetBool(WALK, false);
break;
case ActionStates.Walking:
_animator.SetBool(WALK, true);
break;
case ActionStates.Sleeping:
break;
case ActionStates.Sitting:
_animator.SetBool(SIT_DOWN, true);
break;
case ActionStates.Standing:
_animator.SetBool(SIT_DOWN, false);
break;
}
_currentState = newState;
} }
private bool IsAnimationStatePlaying(int animLayer, string stateName)
bool isAnimationStatePlaying(int animLayer, string stateName)
{ {
if (_animator.GetCurrentAnimatorStateInfo(animLayer).IsName(stateName) && if (_animator.GetCurrentAnimatorStateInfo(animLayer).IsName(stateName) &&
_animator.GetCurrentAnimatorStateInfo(animLayer).normalizedTime < 1.0f) _animator.GetCurrentAnimatorStateInfo(animLayer).normalizedTime < 1.0f)
@@ -198,30 +195,17 @@ public class Player : MonoBehaviour
_tasks.Enqueue(task); _tasks.Enqueue(task);
} }
public void UpdatePlayerState() public void UpdateStatsByClock()
{ {
PlayerStats[StatsId.Food].deduct(0.034m); // 48 hours it's 100, 100/2880=~0.034 per minute PlayerStats[StatsId.Food].deduct(0.034m); // 48 hours it's 100, 100/2880=~0.034 per minute
switch (_currentState) if (_currentAnimation != AnimationStates.Sleeping)
{ {
case ActionStates.Idle: PlayerStats[StatsId.Energy].deduct(0.1m); // 24 hours it's 100, 100/1440=~0.096 per minute
case ActionStates.Walking:
PlayerStats[StatsId.Energy].deduct(0.1m); // 24 hours it's 100, 100/1440=~0.096 per minute
break;
case ActionStates.Sleeping:
PlayerStats[StatsId.Energy].increase(1m);
break;
} }
if (PlayerStats[StatsId.Energy].Value <= 10 && _currentState != ActionStates.Sleeping) else
{ {
_currentState = ActionStates.Sleeping; PlayerStats[StatsId.Energy].increase(1m);
allowMovement = false;
_animator.SetBool(FALL_DOWN, true);
}
if (PlayerStats[StatsId.Energy].Value >= 100 && _currentState == ActionStates.Sleeping)
{
_currentState = ActionStates.Idle;
allowMovement = true;
_animator.SetBool(FALL_DOWN, false);
} }
} }
@@ -231,4 +215,23 @@ public class Player : MonoBehaviour
action.ApplyAction(this); action.ApplyAction(this);
} }
private static string GetEnumMemberValue<T>(T value)
where T : struct, IConvertible
{
return typeof(T)
.GetTypeInfo()
.DeclaredMembers
.SingleOrDefault(x => x.Name == value.ToString())
?.GetCustomAttribute<EnumMemberAttribute>(false)
?.Value;
}
private static bool IsBlockingAnimation<T>(T value)
where T : struct, IConvertible
{
var enumType = typeof(T);
var memInfo = enumType.GetMember(value.ToString());
var attr = memInfo.FirstOrDefault()?.GetCustomAttributes(false).OfType<BlockingAnimation>().FirstOrDefault();
return attr != null;
}
} }