using System; using System.Collections.Generic; using UnityEngine; namespace BehaviorTreeSlayer { /// <summary> /// Agent of behavior tree, /// This class is not required. /// You only need to call Entry.update in the right place to drive the behavior tree to run /// use event drive method to communicate data with outside /// </summary> public class BehaviorTree : MonoBehaviour { System.Random rd = new System.Random(); public System.Random MyRandom => rd;//random inside behavior tree call public bool AutoRun; Dictionary<string, Action<object>> actions = new Dictionary<string, Action<object>>(); public void Regist(string key, Action<object> onEvent) { if (actions.ContainsKey(key)) { actions[key] = onEvent; } else { actions.Add(key, onEvent); } } public void UnRegist(string key) { actions.Remove(key); } public void Dispatch(string key, object obj) { if (actions.ContainsKey(key)) { actions[key].Invoke(obj); } } public TextAsset config; Entry Entry; public List<GameObject> Obj = new List<GameObject>(); Dictionary<string, object> blackBoard = new Dictionary<string, object>(); public object this[string key] { get { if (blackBoard.TryGetValue(key, out object v)) { return v; } GameObject obj = Obj.Find(o => o.name.Equals(key)); return obj; } set { if (blackBoard.ContainsKey(key)) { blackBoard[key] = value; } else { blackBoard.Add(key, value); } } } public void Remove(string key) { blackBoard.Remove(key); } private void Start() { Load(); if (AutoRun) Entry?.Enter(this); } public Entry Load() { if (Entry == null && config != null) { Entry = XmlUtils.DeSerialize<Entry>(config.text); } return Entry; } private void Update() { Entry?.Tick(Time.deltaTime, this); } } }