using System.Collections; using CleverCrow.Fluid.BTs.Tasks; using CleverCrow.Fluid.BTs.Trees; using UnityEngine; using UnityEngine.AI; namespace CleverCrow.Fluid.BTs.Examples { public class FlagChaser : MonoBehaviour { public NavMeshAgent agent; public GameObject flagGraphic; public Team team; public bool defender; public enum Team { Red, Blue } private Vector3 _origin; private bool _stun; private bool _speedBoosted; [SerializeField] private BehaviorTree _tree; private GameObject SpeedBoost => FlagManager.current.speedBoost; private GameObject Flag => FlagManager.current.flag; private GameObject Goal => team == Team.Blue ? FlagManager.current.goalRed : FlagManager.current.goalBlue; private void Awake() { _origin = transform.position; var bd = new BehaviorTreeBuilder(); bd.Selector(); { bd.Condition(() => _stun); } { bd.Sequence("Speed Boost"); bd.Condition("No Flag", () => Flag != gameObject); bd.Condition("Not a Defender", () => !defender); bd.Condition("Speed Boost Spawned", () => SpeedBoost != null); bd.Condition("Not boosted", () => !_speedBoosted); bd.Do("Grab Powerup", () => { agent.SetDestination(SpeedBoost.transform.position); if (Vector3.Distance(SpeedBoost.transform.position, transform.position) <= 1) { GrabSpeedBoost(); } return TaskStatus.Success; }); bd.End(); } { bd.Sequence("Capture Flag"); bd.Condition("No Flag", () => Flag != gameObject); bd.Selector(); { bd.Condition("Team Missing Flag", () => { var character = Flag.GetComponent(); if (character == null) return true; return character.team != team; }); bd.Condition("Not a Defender", () => !defender); bd.End(); } bd.Do("Capture Flag", () => { agent.SetDestination(Flag.transform.position); if (Vector3.Distance(Flag.transform.position, transform.position) <= 1) { GrabFlag(); } return TaskStatus.Success; }); bd.End(); } { bd.Sequence("Score"); bd.Condition("Has Flag", () => Flag == gameObject); bd.Do("Seek Goal", () => { agent.SetDestination(Goal.transform.position); if (Vector3.Distance(Goal.transform.position, transform.position) <= 2) { ScoreGoal(); } return TaskStatus.Success; }); bd.End(); } { bd.Do("Return To Origin", () => { agent.SetDestination(_origin); return TaskStatus.Success; }); } _tree = bd.Build(); flagGraphic.SetActive(false); } public void Stun() { StopCoroutine(StunLoop()); StartCoroutine(StunLoop()); } private IEnumerator StunLoop() { agent.ResetPath(); _stun = true; yield return new WaitForSeconds(1); _stun = false; } private void ScoreGoal() { FlagManager.current.flagStart.SetActive(true); FlagManager.current.flag = FlagManager.current.flagStart; } private void GrabFlag() { Flag.SendMessage("Stun", SendMessageOptions.DontRequireReceiver); if (Flag == FlagManager.current.flagStart) { FlagManager.current.flagStart.SetActive(false); } FlagManager.current.flag = gameObject; } private void GrabSpeedBoost() { Destroy(SpeedBoost); StopCoroutine(SpeedBoostLoop()); StartCoroutine(SpeedBoostLoop()); } private IEnumerator SpeedBoostLoop() { var speed = agent.speed; var turning = agent.angularSpeed; _speedBoosted = true; agent.speed += 5; agent.angularSpeed += 50; yield return new WaitForSeconds(10); _speedBoosted = false; agent.speed = speed; agent.angularSpeed = turning; } private void Update() { _tree.Tick(); flagGraphic.SetActive(Flag == gameObject); } } }