using System; using System.Collections.Generic; using Syntriax.Modules.ToggleState; using UnityEngine; namespace Syntriax.Modules.Movement { public class MovementController : MonoBehaviour, IMovementController { 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; } = null; protected IToggleState toggleState = null; protected virtual void Awake() => Movements = new List(32); protected virtual void Start() { RecacheMovements(); toggleState = GetComponent(); } protected virtual void FixedUpdate() { if (!toggleState.IsToggledNullChecked()) 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; } try { ActiveMovement = Movements[Movements.Count - 1]; } catch (System.Exception) { Debug.LogError("Movement Controller component needs at least one Monobehaviour attached that implements IMovement interface", this); } } public void Move(float x = 0, float y = 0, float z = 0) => ActiveMovement?.Move(x, y, z); } }