popup menu refactor, player class refactor
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
public class BlockingAnimation : Attribute { }
|
||||
public abstract class BaseCharacter : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public NavMeshAgent _navAgent;
|
||||
[SerializeField]
|
||||
public Animator _animator;
|
||||
|
||||
private const string WALK_VELOCITY = "WalkVelocity";
|
||||
private readonly Queue<PlayerTasks> _tasks = new Queue<PlayerTasks>();
|
||||
private PlayerTasks _currentTask;
|
||||
|
||||
private Action _OnAnimationFinish;
|
||||
private AnimationStates _currentAnimation;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (PlayerHelper.IsBlockingAnimation(_currentAnimation))
|
||||
{
|
||||
if (IsAnimationStatePlaying(0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_OnAnimationFinish?.Invoke();
|
||||
_OnAnimationFinish = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (_currentTask == null || _currentTask.Status == TaskStatus.Complete)
|
||||
{
|
||||
_tasks.TryDequeue(out _currentTask);
|
||||
}
|
||||
if (_currentTask != null)
|
||||
{
|
||||
if (_currentTask.Status == TaskStatus.Waiting)
|
||||
Debug.Log($"Current task {_currentTask.Task}");
|
||||
switch (_currentTask.Task)
|
||||
{
|
||||
case Tasks.Rotate:
|
||||
_currentTask.UpdateStatus(Rotate(_currentTask.TagretObject._interactionPoint.forward));
|
||||
break;
|
||||
case Tasks.Move:
|
||||
if (_currentAnimation == AnimationStates.Sitting)
|
||||
{
|
||||
SetPlayerAnimation(AnimationStates.Standing);
|
||||
return;
|
||||
}
|
||||
_navAgent.SetDestination(_currentTask.TagretObject._interactionPoint.position);
|
||||
_currentTask.UpdateStatus(MoveToPoint());
|
||||
break;
|
||||
case Tasks.Interact:
|
||||
_currentTask.UpdateStatus(_currentTask.TagretObject.Interact());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private TaskStatus MoveToPoint()
|
||||
{
|
||||
_navAgent.isStopped = false;
|
||||
SetPlayerAnimation(AnimationStates.Walking);
|
||||
|
||||
_animator.SetFloat(WALK_VELOCITY, _navAgent.velocity.magnitude);
|
||||
return IsPathComplete(_navAgent.destination) ? TaskStatus.Complete : TaskStatus.InProgress;
|
||||
}
|
||||
|
||||
public bool IsPathComplete(Vector3 destination)
|
||||
{
|
||||
var dest = new Vector3(destination.x, 0, destination.z);
|
||||
var pos = new Vector3(_navAgent.transform.position.x, 0, _navAgent.transform.position.z);
|
||||
|
||||
if (Vector3.Distance(dest, pos) <= _navAgent.radius)
|
||||
{
|
||||
transform.position = destination;
|
||||
if (!_navAgent.hasPath || _navAgent.velocity.sqrMagnitude < 0.2f)
|
||||
{
|
||||
SetPlayerAnimation(AnimationStates.Idle);
|
||||
_navAgent.isStopped = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public TaskStatus Rotate(Vector3 target)
|
||||
{
|
||||
var targetRot = Quaternion.LookRotation(target);
|
||||
Quaternion rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(target), 10 * Time.deltaTime);
|
||||
rotation.x = 0;
|
||||
transform.rotation = rotation;
|
||||
if (IsApproximate(targetRot, transform.rotation, 0.000004f))
|
||||
{
|
||||
return TaskStatus.Complete;
|
||||
}
|
||||
return TaskStatus.InProgress;
|
||||
}
|
||||
|
||||
protected void AddTask(PlayerTasks task)
|
||||
{
|
||||
_tasks.Enqueue(task);
|
||||
}
|
||||
|
||||
public bool IsAnimationStatePlaying(int animLayer)
|
||||
{
|
||||
string stateName = PlayerHelper.GetEnumMemberValue(_currentAnimation);
|
||||
var stateInfo = _animator.GetCurrentAnimatorStateInfo(animLayer);
|
||||
return stateInfo.IsName(stateName) && stateInfo.normalizedTime < 1.0f;
|
||||
}
|
||||
|
||||
public void SetPlayerAnimation(AnimationStates newState, Action onAnimationFinish)
|
||||
{
|
||||
_OnAnimationFinish = onAnimationFinish;
|
||||
SetPlayerAnimation(newState);
|
||||
}
|
||||
|
||||
public void SetPlayerAnimation(AnimationStates newState)
|
||||
{
|
||||
if (newState == _currentAnimation)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_animator.Play(PlayerHelper.GetEnumMemberValue(newState));
|
||||
_currentAnimation = newState;
|
||||
}
|
||||
|
||||
private bool IsApproximate(Quaternion q1, Quaternion q2, float precision)
|
||||
{
|
||||
return Mathf.Abs(Quaternion.Dot(q1, q2)) >= 1 - precision;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user