You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			178 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			178 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C#
		
	
| 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<FlagChaser>();
 | |
|                         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);
 | |
|         }
 | |
|     }
 | |
| } |