popup menu refactor, player class refactor
This commit is contained in:
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"visualstudiotoolsforunity.vstuc"
|
||||
]
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Attach to Unity",
|
||||
"type": "vstuc",
|
||||
"request": "attach"
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"files.exclude": {
|
||||
"**/.DS_Store": true,
|
||||
"**/.git": true,
|
||||
"**/.vs": true,
|
||||
"**/.gitmodules": true,
|
||||
"**/.vsconfig": true,
|
||||
"**/*.booproj": true,
|
||||
"**/*.pidb": true,
|
||||
"**/*.suo": true,
|
||||
"**/*.user": true,
|
||||
"**/*.userprefs": true,
|
||||
"**/*.unityproj": true,
|
||||
"**/*.dll": true,
|
||||
"**/*.exe": true,
|
||||
"**/*.pdf": true,
|
||||
"**/*.mid": true,
|
||||
"**/*.midi": true,
|
||||
"**/*.wav": true,
|
||||
"**/*.gif": true,
|
||||
"**/*.ico": true,
|
||||
"**/*.jpg": true,
|
||||
"**/*.jpeg": true,
|
||||
"**/*.png": true,
|
||||
"**/*.psd": true,
|
||||
"**/*.tga": true,
|
||||
"**/*.tif": true,
|
||||
"**/*.tiff": true,
|
||||
"**/*.3ds": true,
|
||||
"**/*.3DS": true,
|
||||
"**/*.fbx": true,
|
||||
"**/*.FBX": true,
|
||||
"**/*.lxo": true,
|
||||
"**/*.LXO": true,
|
||||
"**/*.ma": true,
|
||||
"**/*.MA": true,
|
||||
"**/*.obj": true,
|
||||
"**/*.OBJ": true,
|
||||
"**/*.asset": true,
|
||||
"**/*.cubemap": true,
|
||||
"**/*.flare": true,
|
||||
"**/*.mat": true,
|
||||
"**/*.meta": true,
|
||||
"**/*.prefab": true,
|
||||
"**/*.unity": true,
|
||||
"build/": true,
|
||||
"Build/": true,
|
||||
"Library/": true,
|
||||
"library/": true,
|
||||
"obj/": true,
|
||||
"Obj/": true,
|
||||
"Logs/": true,
|
||||
"logs/": true,
|
||||
"ProjectSettings/": true,
|
||||
"UserSettings/": true,
|
||||
"temp/": true,
|
||||
"Temp/": true
|
||||
},
|
||||
"dotnet.defaultSolution": "SimUL.sln"
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
public abstract class BaseInteractableObject : MonoBehaviour
|
||||
@@ -30,52 +31,28 @@ public abstract class BaseInteractableObject : MonoBehaviour
|
||||
};
|
||||
}
|
||||
|
||||
public InteractionStatus Interact(Player player)
|
||||
public async Task<InteractionStatus> ShowPopupMenu(Player player)
|
||||
{
|
||||
_player = player;
|
||||
|
||||
PrepareMenuActions();
|
||||
|
||||
switch (_currentStatus)
|
||||
{
|
||||
case InteractionStatus.None:
|
||||
var filteredActions = _menuActions.Where(x => x.Value.IsEnabled).ToDictionary(i => i.Key, i => i.Value);
|
||||
GameManager.Instance.UI.ShowItemPopupMenu(filteredActions, PopupMenuCallback);
|
||||
_currentStatus = InteractionStatus.WaitForChoose;
|
||||
break;
|
||||
case InteractionStatus.Complete:
|
||||
_currentStatus = InteractionStatus.None;
|
||||
return InteractionStatus.Complete;
|
||||
default:
|
||||
if (_currentStatus != InteractionStatus.WaitForChoose && _currentStatus != InteractionStatus.Complete)
|
||||
{
|
||||
if (_player.IsPathComplete(_interactionPoint.position))
|
||||
{
|
||||
InteractAction(_selectedAction);
|
||||
_currentStatus = InteractionStatus.None;
|
||||
return InteractionStatus.Complete;
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentStatus = InteractionStatus.FarFromPlayer;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return _currentStatus;
|
||||
}
|
||||
|
||||
private void PopupMenuCallback(RadialMenuActions action)
|
||||
{
|
||||
if (action == RadialMenuActions.Cancel)
|
||||
var result=await GameManager.Instance.UI.ShowItemPopupMenu(filteredActions);
|
||||
if (result == RadialMenuActions.Cancel)
|
||||
{
|
||||
_currentStatus = InteractionStatus.Complete;
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectedAction= action;
|
||||
_selectedAction = result;
|
||||
_currentStatus = InteractionStatus.InProgress;
|
||||
}
|
||||
return _currentStatus;
|
||||
}
|
||||
|
||||
public TaskStatus Interact()
|
||||
{
|
||||
InteractAction(_selectedAction);
|
||||
return TaskStatus.Complete;
|
||||
}
|
||||
|
||||
protected abstract void InteractAction(RadialMenuActions interactAction);
|
||||
|
||||
@@ -42,14 +42,14 @@ public class InGameMouseHandler : UnityEngine.Object
|
||||
if (_selectedObject != null)
|
||||
{
|
||||
_waypointVisual.SetWaypoint(_selectedObject._interactionPoint.position);
|
||||
Player.Instance.AddTask(new PlayerTasks(Tasks.Interact, _selectedObject));
|
||||
Player.Instance.Interact(_selectedObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Physics.Raycast(_ray, out RaycastHit hit, 100f, _walkableLayerMask))
|
||||
{
|
||||
_waypointVisual.SetWaypoint(hit.point);
|
||||
Player.Instance.AddTask(new PlayerTasks(Tasks.Move, _waypointVisual));
|
||||
Player.Instance.GoToPoint( _waypointVisual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae6d3e3aea34ae447a6aa1914a953e8e
|
||||
+15
-140
@@ -1,38 +1,23 @@
|
||||
using Assets.Scripts.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
public class BlockingAnimation : Attribute { }
|
||||
|
||||
public class Player : MonoBehaviour
|
||||
public class Player : BaseCharacter
|
||||
{
|
||||
public static Player Instance { get; private set; }
|
||||
|
||||
[SerializeField]
|
||||
public NavMeshAgent _navAgent;
|
||||
[SerializeField]
|
||||
public Animator _animator;
|
||||
|
||||
[SerializeField]
|
||||
private Transform _holdPoint;
|
||||
|
||||
private PlayerStates _currentActing;
|
||||
private AnimationStates _currentAnimation;
|
||||
|
||||
public Dictionary<StatsId, object> Stats;
|
||||
public JobPositions JobPosition { get; set; }
|
||||
|
||||
public EducationSkill Education { get; set; }
|
||||
|
||||
private readonly Queue<PlayerTasks> _tasks = new Queue<PlayerTasks>();
|
||||
private PlayerTasks _currentTask;
|
||||
|
||||
private const string WALK_VELOCITY = "WalkVelocity";
|
||||
|
||||
private ContainerItem _containerItem;
|
||||
private Action _OnAnimationFinish;
|
||||
|
||||
private string _locationName;
|
||||
|
||||
private void Awake()
|
||||
@@ -66,142 +51,32 @@ public class Player : MonoBehaviour
|
||||
GameManager.Instance.Time.OnMinuteChanged -= UpdateStatsByClock;
|
||||
}
|
||||
|
||||
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:
|
||||
var result = _currentTask.TagretObject.Interact(this);
|
||||
switch (result)
|
||||
{
|
||||
case InteractionStatus.FarFromPlayer:
|
||||
AddTask(new PlayerTasks(Tasks.Move, _currentTask.TagretObject));
|
||||
AddTask(new PlayerTasks(Tasks.Rotate, _currentTask.TagretObject));
|
||||
AddTask(_currentTask);
|
||||
_currentTask = null;
|
||||
break;
|
||||
case InteractionStatus.Complete:
|
||||
_currentTask.UpdateStatus(TaskStatus.Complete);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPosition(Vector3 desiredPosition)
|
||||
{
|
||||
_navAgent.Warp(desiredPosition);
|
||||
_navAgent.updatePosition = false;
|
||||
}
|
||||
|
||||
private TaskStatus MoveToPoint()
|
||||
public void GoToPoint(BaseInteractableObject point)
|
||||
{
|
||||
_navAgent.isStopped = false;
|
||||
SetPlayerAnimation(AnimationStates.Walking);
|
||||
|
||||
_animator.SetFloat(WALK_VELOCITY, _navAgent.velocity.magnitude);
|
||||
return IsPathComplete(_navAgent.destination) ? TaskStatus.Complete : TaskStatus.InProgress;
|
||||
AddTask(new PlayerTasks(Tasks.Move, point));
|
||||
}
|
||||
|
||||
public bool IsPathComplete(Vector3 destination)
|
||||
public async void Interact(BaseInteractableObject interactionItem)
|
||||
{
|
||||
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)
|
||||
var result = await interactionItem.ShowPopupMenu(this);
|
||||
if (result != InteractionStatus.Complete)
|
||||
{
|
||||
transform.position = destination;
|
||||
if (!_navAgent.hasPath || _navAgent.velocity.sqrMagnitude < 0.2f)
|
||||
if (!IsPathComplete(interactionItem._interactionPoint.position))
|
||||
{
|
||||
SetPlayerAnimation(AnimationStates.Idle);
|
||||
_navAgent.isStopped = true;
|
||||
return true;
|
||||
AddTask(new PlayerTasks(Tasks.Move, interactionItem));
|
||||
AddTask(new PlayerTasks(Tasks.Rotate, interactionItem));
|
||||
AddTask(new PlayerTasks(Tasks.Interact, interactionItem));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddTask(new PlayerTasks(Tasks.Interact, interactionItem));
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private bool IsApproximate(Quaternion q1, Quaternion q2, float precision)
|
||||
{
|
||||
return Mathf.Abs(Quaternion.Dot(q1, q2)) >= 1 - precision;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 AddTask(PlayerTasks task)
|
||||
{
|
||||
_tasks.Enqueue(task);
|
||||
}
|
||||
|
||||
public void SetPlayerActing(PlayerStates state)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
@@ -9,13 +9,14 @@ public class RadialMenuItem : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private Button _radialMenuItemPrefab;
|
||||
private Action<RadialMenuActions> _menuButtonClick=null;
|
||||
private Dictionary<RadialMenuActions, RadialMenuActionDescription> _actions;
|
||||
TaskCompletionSource<RadialMenuActions> tcs = new TaskCompletionSource<RadialMenuActions>();
|
||||
|
||||
public void ShowButtons(RadialMenuItem popupMenu, Dictionary<RadialMenuActions, RadialMenuActionDescription> actions, Action<RadialMenuActions> menuButtonClick)
|
||||
|
||||
public Task<RadialMenuActions> ShowButtons(RadialMenuItem popupMenu, Dictionary<RadialMenuActions, RadialMenuActionDescription> actions)
|
||||
{
|
||||
|
||||
_actions = actions;
|
||||
_menuButtonClick = menuButtonClick;
|
||||
for (int buttonsCount = 0; buttonsCount < actions.Count; buttonsCount++)
|
||||
{
|
||||
var button = Instantiate(_radialMenuItemPrefab);
|
||||
@@ -31,25 +32,24 @@ public class RadialMenuItem : MonoBehaviour
|
||||
{
|
||||
textMeshPro.text = actions.ElementAt(buttonsCount).Value.Description;
|
||||
}
|
||||
|
||||
AddEvent(button, buttonsCount);
|
||||
|
||||
}
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
void AddEvent(Button b, int buttonNumber)
|
||||
{
|
||||
b.onClick.AddListener(() =>
|
||||
{
|
||||
tcs.SetResult(_actions.ElementAt(buttonNumber).Key);
|
||||
Close();
|
||||
_menuButtonClick?.Invoke(_actions.ElementAt(buttonNumber).Key);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public void CancelAndClose()
|
||||
{
|
||||
Close();
|
||||
_menuButtonClick?.Invoke(RadialMenuActions.Cancel);
|
||||
}
|
||||
|
||||
private void Close()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
public class UISystem : MonoBehaviour
|
||||
@@ -32,12 +33,12 @@ public class UISystem : MonoBehaviour
|
||||
jobSelector.ShowJobSelectionDialog(title, onCancel, onConfirm);
|
||||
}
|
||||
|
||||
public void ShowItemPopupMenu(Dictionary<RadialMenuActions, RadialMenuActionDescription> actions,Action<RadialMenuActions> itemsMenuCallback)
|
||||
public async Task<RadialMenuActions> ShowItemPopupMenu(Dictionary<RadialMenuActions, RadialMenuActionDescription> actions)
|
||||
{
|
||||
_popupMenu = Instantiate(_radialMenuItemPrefab);
|
||||
_popupMenu.transform.transform.SetParent(transform, false);
|
||||
_popupMenu.transform.position = Input.mousePosition;
|
||||
_popupMenu.ShowButtons(_popupMenu, actions,itemsMenuCallback);
|
||||
return await _popupMenu.ShowButtons(_popupMenu, actions);
|
||||
}
|
||||
|
||||
public void ClosePopupMenu()
|
||||
|
||||
Reference in New Issue
Block a user