using System; using System.Collections.Generic; using Syntriax.Modules.State; using UnityEngine; namespace Syntriax.Modules.Movement { public class MovementController : MonoBehaviour, IMovementController { public Action OnMoveCalled { get; set; } = null; public Action OnMovementDeactivated { get; set; } = null; public Action 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 Movements { get; protected set; } = new List(32); private IStateEnable _stateEnable = null; public IStateEnable StateEnable { get { _stateEnable = _stateEnable ?? GetComponent() ?? gameObject.AddComponent(); return _stateEnable; } } protected virtual void Start() { if (GetComponent() == null) gameObject.AddComponent(); 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(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); } } }