109 lines
3.2 KiB
C#
109 lines
3.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Syntriax.Modules.State;
|
|
using UnityEngine;
|
|
|
|
namespace Syntriax.Modules.Movement
|
|
{
|
|
public class MovementController : MonoBehaviour, IMovementController
|
|
{
|
|
public Action<float, float, float> OnMoveCalled { get; set; } = null;
|
|
|
|
public Action<IMovement> OnMovementDeactivated { get; set; } = null;
|
|
public Action<IMovement> OnMovementActivated { get; set; } = null;
|
|
|
|
private IMovement _activeMovement = null;
|
|
public IMovement ActiveMovement
|
|
{
|
|
get => _activeMovement;
|
|
protected set
|
|
{
|
|
if (_activeMovement == value)
|
|
return;
|
|
|
|
IMovement oldMovement = _activeMovement;
|
|
|
|
_activeMovement = value;
|
|
|
|
if (oldMovement != null)
|
|
OnMovementDeactivated?.Invoke(oldMovement);
|
|
OnMovementActivated?.Invoke(value);
|
|
}
|
|
}
|
|
|
|
public List<IMovement> Movements { get; protected set; } = new List<IMovement>(32);
|
|
|
|
private IStateEnable _stateEnable = null;
|
|
public IStateEnable StateEnable
|
|
{
|
|
get
|
|
{
|
|
_stateEnable = _stateEnable ?? GetComponent<State.IStateEnable>() ?? gameObject.AddComponent<State.StateEnableMonoBehaviour>();
|
|
return _stateEnable;
|
|
}
|
|
}
|
|
|
|
protected virtual void Start()
|
|
{
|
|
if (GetComponent<DefaultMovement>() == null)
|
|
gameObject.AddComponent<DefaultMovement>();
|
|
|
|
RecacheMovements();
|
|
|
|
StateEnable.OnEnabledChanged += (_) => InvokeOnMoveAction();
|
|
OnMovementActivated += (newMovement) => newMovement.Move(lastMove);
|
|
}
|
|
|
|
protected virtual void FixedUpdate()
|
|
{
|
|
if (!StateEnable.IsEnabledNullChecked())
|
|
return;
|
|
|
|
ActiveMovement?.ApplyMovement();
|
|
}
|
|
|
|
public virtual void RecacheMovements()
|
|
{
|
|
foreach (IMovement movement in Movements)
|
|
movement.OnTakeOverStateChanged -= OnTakeOver;
|
|
|
|
Movements.Clear();
|
|
GetComponents<IMovement>(Movements);
|
|
UpdateActiveMovement();
|
|
|
|
foreach (IMovement movement in Movements)
|
|
movement.OnTakeOverStateChanged += OnTakeOver;
|
|
}
|
|
|
|
private void OnTakeOver(bool arg0) => UpdateActiveMovement();
|
|
|
|
protected virtual void UpdateActiveMovement()
|
|
{
|
|
foreach (IMovement movement in Movements)
|
|
if (movement.CanTakeOver)
|
|
{
|
|
ActiveMovement = movement;
|
|
return;
|
|
}
|
|
}
|
|
|
|
private Vector3 lastMove = Vector3.zero;
|
|
|
|
public void Move(float x = 0, float y = 0, float z = 0)
|
|
{
|
|
ActiveMovement?.Move(x, y, z);
|
|
(lastMove.x, lastMove.y, lastMove.z) = (x, y, z);
|
|
|
|
InvokeOnMoveAction();
|
|
}
|
|
|
|
private void InvokeOnMoveAction()
|
|
{
|
|
if (!StateEnable.IsEnabledNullChecked())
|
|
return;
|
|
|
|
OnMoveCalled?.Invoke(lastMove.x, lastMove.y, lastMove.z);
|
|
}
|
|
}
|
|
}
|