// Animancer // Copyright 2020 Kybernetik // #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value. using Animancer.FSM; using System; using UnityEngine; namespace Animancer.Examples.StateMachines.Brains { /// /// A centralised group of references to the common parts of a creature and a state machine for their actions. /// [AddComponentMenu(Strings.MenuPrefix + "Examples/Brains - Creature")] [HelpURL(Strings.APIDocumentationURL + ".Examples.StateMachines.Brains/Creature")] [DefaultExecutionOrder(-5000)]// Initialise the State Machine early. public sealed class Creature : MonoBehaviour { /************************************************************************************************************************/ [SerializeField] private AnimancerComponent _Animancer; public AnimancerComponent Animancer { get { return _Animancer; } } [SerializeField] private CreatureState _Idle; public CreatureState Idle { get { return _Idle; } } [SerializeField] private Rigidbody _Rigidbody; public Rigidbody Rigidbody { get { return _Rigidbody; } } [SerializeField] private CreatureBrain _Brain; public CreatureBrain Brain { get { return _Brain; } set { // The More Brains example uses this to swap between brains at runtime. if (_Brain == value) return; var oldBrain = _Brain; _Brain = value; // Make sure the old brain doesn't still reference this creature. if (oldBrain != null) oldBrain.Creature = null; // Give the new brain a reference to this creature. if (value != null) value.Creature = this; } } [SerializeField] private CreatureStats _Stats; public CreatureStats Stats { get { return _Stats; } } // Ground Detector. // Health and Mana. // Pathfinding. // Etc. // Anything common to most creatures. /************************************************************************************************************************/ /// /// The Finite State Machine that manages the actions of this creature. /// public StateMachine StateMachine { get; private set; } /// /// Forces the to return to the state. /// public Action ForceEnterIdleState { get; private set; } /************************************************************************************************************************/ private void Awake() { // Note that this class has a [DefaultExecutionOrder] attribute to ensure that this method runs before any // other components that might want to access it. ForceEnterIdleState = () => StateMachine.ForceSetState(_Idle); StateMachine = new StateMachine(_Idle); } /************************************************************************************************************************/ #if UNITY_EDITOR /************************************************************************************************************************/ /// [Editor-Only] /// Inspector Gadgets Pro calls this method after drawing the regular Inspector GUI, allowing this script to /// display its current state in Play Mode. /// /// /// Inspector Gadgets Pro allows you to easily customise the Inspector without writing a full custom Inspector /// class by simply adding a method with this name. Without Inspector Gadgets, this method will do nothing. /// It can be purchased from https://kybernetik.com.au/inspector-gadgets/pro /// private void AfterInspectorGUI() { if (UnityEditor.EditorApplication.isPlaying) { var enabled = GUI.enabled; GUI.enabled = false; UnityEditor.EditorGUILayout.ObjectField("Current State", StateMachine.CurrentState, typeof(CreatureState), true); GUI.enabled = enabled; } } /************************************************************************************************************************/ #endif /************************************************************************************************************************/ } }