2
0
Fork 0
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#

2 years ago
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);
}
}
}