using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; using SHADE; public class AIPrototype : Script { //This object's relevant components private Transform transform; private RigidBody rb; /*[SerializeField] [Tooltip("The list of waypoints that the object will move around on")] private Vector3[] waypoints;*/ private Vector3[] waypoints = { new Vector3(-8.0f, -2.0f, 3.5f), new Vector3(-8.0f, -2.0f, -13.0f), new Vector3(8.0f, -2.0f, -13.0f), new Vector3(8.0f, -2.0f, 3.5f) }; [SerializeField] [Tooltip("How much force is applied in movement")] private float movementForceMultiplier = 100.0f; [SerializeField] [Tooltip("How fast the object moves about waypoints")] private float patrolSpeed = 0.4f; [SerializeField] [Tooltip("How fast the object moves while chasing")] private float chaseSpeed = 0.8f; [SerializeField] [Tooltip("How near the player must be to the AI for capture")] private float distanceToCapture = 1.2f; [SerializeField] [Tooltip("How near the player must be for the chase to begin. Should be less than distanceToEndChase")] private float distanceToStartChase = 2.0f; [SerializeField] [Tooltip("How far the player must be for the chase to end. Should be greater than distanceToStartChase")] private float distanceToEndChase = 2.5f; //Whether the AI is chasing or not private bool chaseMode; //To cycle depending on the length of waypoints private int currentTargetWaypointIndex; private GameObject? player; public AIPrototype(GameObject gameObj) : base(gameObj) { } protected override void awake() { transform = GetComponent(); if (transform == null) { Debug.LogError("Transform is NULL!"); } rb = GetComponent(); if (rb == null) { Debug.LogError("Rigidbody is NULL!"); } currentTargetWaypointIndex = 0; player = GameObject.Find("Player"); if (player == null) { Debug.LogError("Player is NULL!"); } chaseMode = false; } protected override void fixedUpdate() { //Patrolling if (!chaseMode) { //Head towards the next target Vector3 normalisedDifference = waypoints[currentTargetWaypointIndex] - transform.GlobalPosition; normalisedDifference /= normalisedDifference.GetMagnitude(); //transform.GlobalPosition += normalisedDifference * moveSpeed * (float)Time.DeltaTime; //rb.LinearVelocity = normalisedDifference * patrolSpeed; //ORIGINAL INTENDED CODE /*rb.AddForce(new Vector3(normalisedDifference.x, 0.0f, normalisedDifference.z) * movementForceMultiplier); float currentSpeed = MathF.Sqrt(rb.LinearVelocity.x * rb.LinearVelocity.x + rb.LinearVelocity.z * rb.LinearVelocity.z); if (currentSpeed > patrolSpeed) { float adjustmentFactor = patrolSpeed / currentSpeed; Vector3 adjustedVelocity = rb.LinearVelocity; //adjustedVelocity *= adjustmentFactor; adjustedVelocity.x = patrolSpeed; adjustedVelocity.z = patrolSpeed; rb.LinearVelocity = adjustedVelocity; }*/ //TODO delete this when original intended code above works with velocity being limited correctly rb.LinearVelocity = normalisedDifference * patrolSpeed; //transform.GlobalRotation.SetLookRotation(waypoints[currentTargetWaypointIndex], Vector3.Up); //Cycle to next waypoint if near enough current waypoint if ((waypoints[currentTargetWaypointIndex] - transform.GlobalPosition).GetSqrMagnitude() <= 0.5f) { ++currentTargetWaypointIndex; if (currentTargetWaypointIndex >= waypoints.Length) { currentTargetWaypointIndex = 0; //Recycle } } //Go chase if near enough to player if (player != null) { Transform pTransform = player.GetValueOrDefault().GetComponent(); if ((pTransform.GlobalPosition - transform.GlobalPosition).GetMagnitude() <= distanceToStartChase) { //Start the chase chaseMode = true; } } } else //Chasing { if (player != null) { Transform pTransform = player.GetValueOrDefault().GetComponent(); //Chase the player Vector3 normalisedDifference = pTransform.GlobalPosition - transform.GlobalPosition; normalisedDifference /= normalisedDifference.GetMagnitude(); //transform.GlobalPosition += normalisedDifference * moveSpeed * (float)Time.DeltaTime; //ORIGINAL INTENDED CODE /*rb.AddForce(new Vector3(normalisedDifference.x, 0.0f, normalisedDifference.z) * movementForceMultiplier); float currentSpeed = MathF.Sqrt(rb.LinearVelocity.x * rb.LinearVelocity.x + rb.LinearVelocity.z * rb.LinearVelocity.z); if (currentSpeed > chaseSpeed) { float adjustmentFactor = chaseSpeed / currentSpeed; Vector3 adjustedVelocity = rb.LinearVelocity; adjustedVelocity *= adjustmentFactor; rb.LinearVelocity = adjustedVelocity; }*/ //TODO delete this when original intended code above works with velocity being limited correctly rb.LinearVelocity = normalisedDifference * chaseSpeed; //Capture player if near enough if ((pTransform.GlobalPosition - transform.GlobalPosition).GetMagnitude() <= distanceToCapture) { player.GetValueOrDefault().GetScript().currentState = PlayerController.RaccoonStates.CAUGHT; } //End chase if too far if ((pTransform.GlobalPosition - transform.GlobalPosition).GetMagnitude() >= distanceToEndChase) { //Stop the chase chaseMode = false; //Find the nearest waypoint to go instead float nearestWaypointDistance = 99999999999999.9f; for (int i = 0; i < waypoints.Length; ++i) { if ((waypoints[i] - transform.GlobalPosition).GetSqrMagnitude() < nearestWaypointDistance) { nearestWaypointDistance = waypoints[i].GetSqrMagnitude(); currentTargetWaypointIndex = i; } } } } } } }