/********************************************************************* * \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 turningSpeed; private float captureDistance; private float baseCaptureTime; } //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) : base (name) { Debug.Log("LeafChase ctor"); } /* * transform = t; this.rb = rb; chaseSpeed = cSpd; turnSpeed = tSpd; captureDistance = capDist; captureTime = capTime; */ public override BehaviourTreeNodeStatus Evaluate() { Debug.LogWarning("LeafChase"); onEnter(BehaviourTreeNodeStatus.RUNNING); //Get Data if (GetNodeData("transform") == null || GetNodeData("rigidBody") == null || GetNodeData("turningSpeed") == null || GetNodeData("chaseSpeed") == null || GetNodeData("distanceToCapture") == null || GetNodeData("baseCaptureTime") == null) { status = BehaviourTreeNodeStatus.FAILURE; onExit(BehaviourTreeNodeStatus.FAILURE); return status; } else { transform = (Transform)GetNodeData("transform"); rb = (RigidBody)GetNodeData("rigidBody"); chaseSpeed = (float)GetNodeData("chaseSpeed"); turningSpeed = (float)GetNodeData("turningSpeed"); captureDistance = (float)GetNodeData("distanceToCapture"); baseCaptureTime = (float)GetNodeData("baseCaptureTime"); } //Fail if no target in blackboard if (GetNodeData("target") == null) { Debug.Log("Failure: No target in blackboard"); return BehaviourTreeNodeStatus.FAILURE; } 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) { Audio.PlaySFXOnce2D("event:/Homeowner/humming"); } 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, turningSpeed * 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", baseCaptureTime); //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, turningSpeed * 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; } } }