SHADE_Y3/Assets/Scripts/Gameplay/AIBehaviour/Implemented/Homeowner1.cs

210 lines
7.8 KiB
C#

/*********************************************************************
* \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 SHADE_Scripting.Audio;
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<GameObject> waypoints;
[SerializeField]
private GameObject startWaypoint;
[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;
//singleton for AI
public static Homeowner1 aiInstance { get; private set; }
}
//AI tree
public partial class Homeowner1 : BehaviourTree
{
//Called at the start
protected override void Initialise()
{
_events = new Homeowner1Events(this);
events.Initialise();
//(25 Nov) DO NOT Initialise the data here
/*if (waypointsPool)
{
waypoints = (List<GameObject>)waypointsPool.GetChildren();
SetData("waypoints", waypoints);
}
SetData("transform", GetComponent<Transform>());
SetData("rigidBody", GetComponent<RigidBody>());
SetData("eyeOffset", eyeOffset);
SetData("sightDistance", sightDistance);
SetData("patrolSpeed", patrolSpeed);
SetData("chaseSpeed", chaseSpeed);
SetData("turningSpeed", turningSpeed);
SetData("distanceToCapture", distanceToCapture);
SetData("baseCaptureTime", captureTime);*/
//These should be somewhere else
//Debug.Log("TESTING");
//AudioHandler.audioClipHandlers["BGMUnalert"] = Audio.CreateAudioClip("event:/Music/player_undetected");
//AudioHandler.audioClipHandlers["BGMAlert"] = Audio.CreateAudioClip("event:/Music/player_detected");
AudioHandler.audioClipHandlers["BGMAdaptive"] = Audio.CreateAudioClip("event:/Music/bgm_adaptive");
AudioHandler.audioClipHandlers["SFXFootstep"] = Audio.CreateAudioClip("event:/Homeowner/homeowner_footsteps");
Audio.AttachAudioClipToObject(AudioHandler.audioClipHandlers["SFXFootstep"], GameObject.EntityId);
AudioHandler.audioClipHandlers["SFXDetectAh"] = Audio.CreateAudioClip("event:/Homeowner/homeowner_detect_raccoon");
Audio.AttachAudioClipToObject(AudioHandler.audioClipHandlers["SFXDetectAh"], GameObject.EntityId);
AudioHandler.audioClipHandlers["SFXDetectSting"] = Audio.CreateAudioClip("event:/Music/stingers/player_detected");
AudioHandler.audioClipHandlers["SFXHumming"] = Audio.CreateAudioClip("event:/Homeowner/homeowner_humming");
Audio.AttachAudioClipToObject(AudioHandler.audioClipHandlers["SFXHumming"], GameObject.EntityId);
//AudioHandler.audioClipHandlers["SFXHumming"].SetVolume(0.15f);
AudioHandler.audioClipHandlers["SFXHumming"].Play();
if (aiInstance != null && aiInstance != this)
RemoveScript<Homeowner1>();
else
aiInstance = this;
}
//Called every tick
protected override void Tick()
{
//Debug.Log("Ticking");
//Update data
if (GetData("waypoints") == null)
{
if (waypointsPool != GameObject.Null)
SetData("waypoints", (List<GameObject>)waypointsPool.GetChildren());
else
Debug.LogError("No waypoints, no AI");
}
if (GetData("transform") == null)
SetData("transform", GetComponent<Transform>());
if (GetData("rigidBody") == null)
SetData("rigidBody", GetComponent<RigidBody>());
if (GetData("eyeOffset") == null || (Vector3)GetData("eyeOffset") != eyeOffset)
SetData("eyeOffset", eyeOffset);
if (GetData("sightDistance") == null || (float)GetData("sightDistance") != sightDistance)
SetData("sightDistance", sightDistance);
if (GetData("patrolSpeed") == null || (float)GetData("patrolSpeed") != patrolSpeed)
SetData("patrolSpeed", patrolSpeed);
if (GetData("chaseSpeed") == null || (float)GetData("chaseSpeed") != chaseSpeed)
SetData("chaseSpeed", chaseSpeed);
if (GetData("turningSpeed") == null || (float)GetData("turningSpeed") != turningSpeed)
SetData("turningSpeed", turningSpeed);
if (GetData("distanceToCapture") == null || (float)GetData("distanceToCapture") != distanceToCapture)
SetData("distanceToCapture", distanceToCapture);
if (GetData("baseCaptureTime") == null || (float)GetData("baseCaptureTime") != captureTime)
SetData("baseCaptureTime", captureTime);
if (GetData("startWaypoint") == null || (GameObject)GetData("startWaypoint") != startWaypoint)
SetData("startWaypoint", startWaypoint);
events.Tick();
//Footsteps SFX, move them somewhere else soon
float velocity = GetComponent<RigidBody>().LinearVelocity.GetMagnitude();
footstepTimeRemaining -= velocity * Time.DeltaTimeF;
if (footstepTimeRemaining < 0.0f)
{
//Audio.PlaySFXOnce2D("event:/Homeowner/homeowner_footsteps");
//AudioHandler.audioClipHandlers["SFXFootstep"].Play();
footstepTimeRemaining = footstepSFXIntervalMultiplier;
}
//Debug.Log("Ticked");
}
//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()
{
//Debug.Log("Creating Tree");
//Start from the root, structure it like this to make it look like a tree
BehaviourTreeNode root = new BehaviourTreeSelector("Root", new List<BehaviourTreeNode>
{
new BehaviourTreeSequence("Alerted", new List<BehaviourTreeNode>
{
new LeafSearch("SearchFOV"),
new BehaviourTreeSequence("CatchPlayer", new List<BehaviourTreeNode>
{
new LeafChase("Chasing"),
new LeafAttack("Attacking")
})
}),
new LeafPatrol("Patrol")
});
//Debug.Log("Tree Created");
return root;
}
protected override void onDestroy()
{
if (aiInstance == this)
aiInstance = null;
}
}