using System; using System.Collections.Generic; using Syntriax.Modules.ToggleState; 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); } } private bool areBothToggleStatesToggled => ToggleStateMember.IsToggledNullChecked() && toggleStateOnGameObject.IsToggledNullChecked(); public List Movements { get; protected set; } = new List(32); public IToggleState ToggleStateMember { get; protected set; } = new ToggleStateMember(true); protected IToggleState toggleStateOnGameObject = null; protected virtual void Start() { if (GetComponent() == null) gameObject.AddComponent(); RecacheMovements(); toggleStateOnGameObject = GetComponent(); toggleStateOnGameObject.OnToggleStateChanged += (_) => InvokeOnMoveAction(); ToggleStateMember.OnToggleStateChanged += (_) => InvokeOnMoveAction(); } protected virtual void FixedUpdate() { if (!areBothToggleStatesToggled) 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 (!areBothToggleStatesToggled) return; OnMoveCalled?.Invoke(lastMove.x, lastMove.y, lastMove.z); } } }