/********************************************************************* * \file Homeowner1.cs * \author Ryan Wang Nian Jing * \brief The implemented behaviour tree for the homeowner * A prototype to prove that behaviour trees can be worked and expanded * on in the custom engine for GAM300 Milestone 3 and expanded over * GAM350 * * * \copyright Copyright (c) 2022 DigiPen Institute of Technology. Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. *********************************************************************/ using SHADE; using SHADE_Scripting.AIBehaviour.BehaviourTree; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; //Variables required for the AI to function //To be attached to the game object via the inspector public partial class Homeowner1 : BehaviourTree { private BehaviourTreeEvents _events { get; set; } public override BehaviourTreeEvents events { get => _events; } //PATROL FIELDS/////////////////////////////////////////////////////////////// [SerializeField] [Tooltip("The list of waypoints for the AI to cycle around")] private GameObject waypointsPool; private List waypoints; [SerializeField] [Tooltip("The AI will patrol at this speed")] private float patrolSpeed; [SerializeField] [Tooltip("The speed at which the AI will chase the player if sighted")] private float chaseSpeed; [SerializeField] [Tooltip("Turning speed multiplier of the AI. 10 is good")] private float turningSpeed; //FIELD OF VISION///////////////////////////////////////////////////////////// [SerializeField] [Tooltip("How far the AI can see up to")] private float sightDistance; [SerializeField] [Tooltip("How far the eyes are offset from the AI's actual position")] private Vector3 eyeOffset; //ATTACKING/////////////////////////////////////////////////////////////////// [SerializeField] [Tooltip("How near the player mut be to the AI for capture")] private float distanceToCapture; [SerializeField] [Tooltip("How long the player should be in the attack range for successful capture")] private float captureTime; //There's definitely a better way to do this [SerializeField] [Tooltip("TO BE REMOVED IN 350. Interval multiplier between footsteps")] private float footstepSFXIntervalMultiplier; private float footstepTimeRemaining; } //AI tree public partial class Homeowner1 : BehaviourTree { //Called at the start protected override void Initialise() { _events = new Homeowner1Events(this); events.Initialise(); //Initialise the waypoints here if (waypointsPool) { waypoints = (List)waypointsPool.GetChildren(); SetData("waypoints", waypoints); } } //Called every tick protected override void Tick() { events.Tick(); //Footsteps SFX, move them somewhere else soon float velocity = GetComponent().LinearVelocity.GetMagnitude(); footstepTimeRemaining -= velocity * Time.DeltaTimeF; if (footstepTimeRemaining < 0.0f) { Debug.Log("AI Play Footstep SFX"); footstepTimeRemaining = footstepSFXIntervalMultiplier; } } //Define the behaviour tree here //Order of which nodes are created affects order of execution //The tree is called from the root every tick protected override BehaviourTreeNode CreateTree() { //Start from the root, structure it like this to make it look like a tree BehaviourTreeNode root = new BehaviourTreeSelector("Root", new List { new BehaviourTreeSequence("Alerted", new List { new LeafSearch("SearchFOV", GetComponent(), eyeOffset, sightDistance), new BehaviourTreeSequence("CatchPlayer", new List { new LeafChase("Chasing", GetComponent(), GetComponent(), chaseSpeed, turningSpeed, distanceToCapture, captureTime), new LeafAttack("Attacking", GameObject.Find("Player").GetValueOrDefault()) }) }), new LeafPatrol("Patrol", GetComponent(), patrolSpeed, turningSpeed, GetComponent()) }); return root; } }