/********************************************************************* * \file LeafChase.cs * \author Ryan Wang Nian Jing * \brief Leaf node implementation for AI chasing the player * * * \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.Text; using System.Threading.Tasks; //VARIABLES public partial class LeafChase : BehaviourTreeNode { //Used to move entity around private Transform transform; private RigidBody rb; private float chaseSpeed; private float turnSpeed; private float captureDistance; private float captureTime; } //FUNCTIONS public partial class LeafChase : BehaviourTreeNode { //Despite inheriting from BehaviourTreeNode, we don't have children to this node, //and hence we don't need to inherit its constructors public LeafChase(string name, Transform t, RigidBody rb, float cSpd, float tSpd, float capDist, float capTime) : base (name) { transform = t; this.rb = rb; chaseSpeed = cSpd; turnSpeed = tSpd; captureDistance = capDist; captureTime = capTime; } public override BehaviourTreeNodeStatus Evaluate() { //Debug.LogWarning("LeafChase"); //Fail if no target in blackboard if (GetNodeData("target") == null) { //Debug.Log("Failure: No target in blackboard"); return BehaviourTreeNodeStatus.FAILURE; } onEnter(BehaviourTreeNodeStatus.RUNNING); Transform target = (Transform)GetNodeData("target"); Vector3 normalisedDifference = target.GlobalPosition - transform.GlobalPosition; normalisedDifference.y = 0.0f; //Do not consider Y normalisedDifference /= normalisedDifference.GetMagnitude(); //Over maximum distance, stop chase if ((transform.GlobalPosition - target.GlobalPosition).GetMagnitude() > 1000.0f) { //Debug.Log("Failure: Over maximum distance"); ClearNodeData("target"); if (GetNodeData("isAlert") != null && (bool)GetNodeData("isAlert") == true) { Debug.Log("AI play unalert hmm"); } SetNodeData("isAlert", false); status = BehaviourTreeNodeStatus.FAILURE; onExit(BehaviourTreeNodeStatus.FAILURE); return status; } else if (false) //TODO If collided against a wall { //Debug.Log("Running: Collided against wall"); SetNodeData("isPathfinding", true); status = BehaviourTreeNodeStatus.RUNNING; onExit(BehaviourTreeNodeStatus.RUNNING); return BehaviourTreeNodeStatus.RUNNING; } //Keep chasing else if ((transform.GlobalPosition - target.GlobalPosition).GetMagnitude() > captureDistance) { //Debug.Log("Running: Chasing"); Quaternion targetRotation = Quaternion.LookRotation(normalisedDifference, new Vector3(0.0f, 1.0f, 0.0f)); transform.LocalRotation = Quaternion.Slerp(transform.LocalRotation, targetRotation, turnSpeed * Time.DeltaTimeF); //TODO delete this when original intendd code above works with velocity being limited correctly rb.LinearVelocity = normalisedDifference * chaseSpeed; //Reset capture timing to base SetNodeData("captureTimeLeft", captureTime); //Not capturing, don't play SFX SetNodeData("isCapturing", false); status = BehaviourTreeNodeStatus.RUNNING; onExit(BehaviourTreeNodeStatus.RUNNING); return BehaviourTreeNodeStatus.RUNNING; } //Once player is close enough, perform attack else { //Debug.Log("Success: Near enough. Begin attack"); //Look at the correct direction Quaternion targetRotation = Quaternion.LookRotation(normalisedDifference, new Vector3(0.0f, 1.0f, 0.0f)); transform.LocalRotation = Quaternion.Slerp(transform.LocalRotation, targetRotation, turnSpeed * Time.DeltaTimeF); //Play SFX if (GetNodeData("isCapturing") != null && (bool)GetNodeData("isCapturing") == false) { Debug.Log("AI Play capturing SFX"); } SetNodeData("isCapturing", true); //TODO resetting the capture time once it's less than 0 doesn't work as //there is quite some time (about .1 seconds) after the timer falls below 0 //that the capture actually happens status = BehaviourTreeNodeStatus.SUCCESS; onExit(BehaviourTreeNodeStatus.SUCCESS); return status; } } }