using UnityEngine; using Lightbug.Utilities; namespace Lightbug.CharacterControllerPro.Implementation { /// /// This class is responsable for detecting inputs and managing character actions. /// [AddComponentMenu("Character Controller Pro/Implementation/Character/Character Brain")] [DefaultExecutionOrder(int.MinValue)] public class CharacterBrain : MonoBehaviour { [Tooltip("Indicates when actions should be consumed.\n\n" + "FixedUpdate (recommended): use this when the gameplay logic needs to run during FixedUpdate.\n\n" + "Update: use this when the gameplay logic needs to run every frame during Update.")] public UpdateModeType UpdateMode = UpdateModeType.FixedUpdate; [BooleanButton("Brain type", "Player", "AI", true)] [SerializeField] bool isAI = false; [Condition("isAI", ConditionAttribute.ConditionType.IsFalse)] [Expand] [SerializeField] InputHandlerSettings inputHandlerSettings = new InputHandlerSettings(); [Condition("isAI", ConditionAttribute.ConditionType.IsTrue)] [SerializeField] CharacterAIBehaviour aiBehaviour = null; [Expand] [ReadOnly] [SerializeField] CharacterActions characterActions = new CharacterActions(); // ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── // ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── public enum UpdateModeType { FixedUpdate, Update } CharacterAIBehaviour currentAIBehaviour = null; bool firstUpdateFlag = false; /// /// Gets the current brain mode (AI or Human). /// public bool IsAI => isAI; /// /// Gets the current actions values from the brain. /// public CharacterActions CharacterActions => characterActions; /// /// Sets the internal CharacterActions value. /// public void SetAction(CharacterActions characterActions) => this.characterActions = characterActions; /// /// Sets the type of brain. /// public void SetBrainType(bool isAI) { characterActions.Reset(); if (isAI) SetAIBehaviour(aiBehaviour); this.isAI = isAI; } /// /// Sets the player's input handler. /// public void SetInputHandler(InputHandler inputHandler) { if (inputHandler == null) return; inputHandlerSettings.InputHandler = inputHandler; characterActions.Reset(); } /// /// Sets the AI behaviour type. /// public void SetAIBehaviour(CharacterAIBehaviour aiBehaviour) { if (aiBehaviour == null) return; currentAIBehaviour?.ExitBehaviour(Time.deltaTime); characterActions.Reset(); currentAIBehaviour = aiBehaviour; currentAIBehaviour.EnterBehaviour(Time.deltaTime); } public void UpdateBrainValues(float dt) { if (Time.timeScale == 0) return; if (IsAI) UpdateAIBrainValues(dt); else UpdateHumanBrainValues(dt); } void UpdateHumanBrainValues(float dt) { characterActions.SetValues(inputHandlerSettings.InputHandler); characterActions.Update(dt); } void UpdateAIBrainValues(float dt) { currentAIBehaviour?.UpdateBehaviour(dt); characterActions.SetValues(currentAIBehaviour.characterActions); characterActions.Update(dt); } #region Unity's messages protected virtual void Awake() { characterActions.InitializeActions(); inputHandlerSettings.Initialize(gameObject); } protected virtual void OnEnable() { characterActions.InitializeActions(); characterActions.Reset(); } protected virtual void OnDisable() { characterActions.Reset(); } void Start() { SetBrainType(isAI); } protected virtual void FixedUpdate() { firstUpdateFlag = true; if (UpdateMode == UpdateModeType.FixedUpdate) { UpdateBrainValues(0f); } } protected virtual void Update() { float dt = Time.deltaTime; if (UpdateMode == UpdateModeType.FixedUpdate) { if (firstUpdateFlag) { firstUpdateFlag = false; characterActions.Reset(); } } else { characterActions.Reset(); } UpdateBrainValues(dt); } #endregion } }