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_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Stand To Sit
m_Name: StandToSit
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
@@ -33901,7 +33901,7 @@ AnimationClip:
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 1
m_LoopBlendPositionXZ: 1
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 0
m_KeepOriginalPositionXZ: 0
@@ -36,7 +36,7 @@ public class ConversationController : MonoBehaviour
ApplyActionOnPlayer(_selectedAction);
});
Player.Instance.allowMovement = false;
//Player.Instance.allowMovement = false;
RemoveChoices();
_title.text = title;
gameObject.SetActive(true);
@@ -83,6 +83,6 @@ public class ConversationController : MonoBehaviour
RemoveChoices();
gameObject.SetActive(false);
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)
{
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 System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using UnityEngine;
using UnityEngine.AI;
public class BlockingAnimation : Attribute
{
}
public enum Tasks { Move, Interact, Rotate };
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
{
@@ -16,8 +39,8 @@ public class Player : MonoBehaviour
[SerializeField]
public Animator _animator;
public bool allowMovement = true;
private ActionStates _currentState;
private bool _isAllowMovement;
private AnimationStates _currentAnimation;
private Vector3 _groundDeltaPosition;
public Dictionary<StatsId, Stat> PlayerStats;
@@ -26,9 +49,6 @@ public class Player : MonoBehaviour
private readonly Queue<PlayerTasks> _tasks = new Queue<PlayerTasks>();
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 bool _isInAnimation = false;
@@ -43,26 +63,22 @@ public class Player : MonoBehaviour
}
private void Start()
{
TimeManager.OnMinuteChanged += UpdatePlayerState;
allowMovement = true;
TimeManager.OnMinuteChanged += UpdateStatsByClock;
_isAllowMovement = true;
_navAgent.updatePosition = false;
PlayerStats = GameManager.Instance.PlayerStats;
}
private void OnDestroy()
{
TimeManager.OnMinuteChanged -= UpdatePlayerState;
TimeManager.OnMinuteChanged -= UpdateStatsByClock;
}
private void Update()
{
if (_isInAnimation)
if (IsBlockingAnimation(_currentAnimation))
{
if (!isAnimationStatePlaying(0, "SitToStand"))
{
_isInAnimation = false;
}
else
if (IsAnimationStatePlaying(0, GetEnumMemberValue(_currentAnimation)))
return;
}
@@ -80,9 +96,9 @@ public class Player : MonoBehaviour
_currentTask.UpdateStatus(Rotate(_currentTask.TagretObject._playerArrivePoint.forward));
break;
case Tasks.Move:
if (_currentState == ActionStates.Sitting)
if (_currentAnimation == AnimationStates.Sitting)
{
SetPlayerState(ActionStates.Standing);
SetPlayerAnimation(AnimationStates.Standing);
return;
}
_navAgent.SetDestination(_currentTask.TagretObject._playerArrivePoint.position);
@@ -105,7 +121,7 @@ public class Player : MonoBehaviour
private TaskStatus MoveToPoint()
{
SetPlayerState(ActionStates.Walking);
SetPlayerAnimation(AnimationStates.Walking);
var worldDeltaPosition = _navAgent.nextPosition - transform.position;
_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 (!_navAgent.hasPath || _navAgent.velocity.sqrMagnitude == 0f)
if (!_navAgent.hasPath || _navAgent.velocity.sqrMagnitude < 0.2f)
{
SetPlayerState(ActionStates.Idle);
SetPlayerAnimation(AnimationStates.Idle);
return true;
}
}
@@ -150,36 +166,17 @@ public class Player : MonoBehaviour
return TaskStatus.Complete;
}
public void SetPlayerState(ActionStates newState)
public void SetPlayerAnimation(AnimationStates newState)
{
if (newState == _currentState)
if (newState == _currentAnimation)
{
return;
}
_isInAnimation = true;
switch (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;
_animator.Play(GetEnumMemberValue(newState));
_currentAnimation = newState;
}
bool isAnimationStatePlaying(int animLayer, string stateName)
private bool IsAnimationStatePlaying(int animLayer, string stateName)
{
if (_animator.GetCurrentAnimatorStateInfo(animLayer).IsName(stateName) &&
_animator.GetCurrentAnimatorStateInfo(animLayer).normalizedTime < 1.0f)
@@ -198,30 +195,17 @@ public class Player : MonoBehaviour
_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
switch (_currentState)
if (_currentAnimation != AnimationStates.Sleeping)
{
case ActionStates.Idle:
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;
PlayerStats[StatsId.Energy].deduct(0.1m); // 24 hours it's 100, 100/1440=~0.096 per minute
}
if (PlayerStats[StatsId.Energy].Value <= 10 && _currentState != ActionStates.Sleeping)
else
{
_currentState = ActionStates.Sleeping;
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);
PlayerStats[StatsId.Energy].increase(1m);
}
}
@@ -231,4 +215,23 @@ public class Player : MonoBehaviour
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;
}
}