using System.Collections; using System.Collections.Generic; using UnityEngine; public class AIController : MonoBehaviour { public GameObject ball; public Transform targetGoal; public Vector3 inputVector; public float turnRadius = 1; public float destinationOffset; public float distanceToTarget; public float angleToDestination; public float angleToBall; public float distanceToBall; private Vector3 destination; private Vector3 directionVector; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { Vector3 ballPosition = this.ball.transform.position; Vector3 goalDirection = ballPosition - this.targetGoal.position; this.destination = ballPosition + goalDirection.normalized * this.destinationOffset; this.directionVector = this.destination - this.transform.position; //Use "right" to offset the angle by 90 deg. This gives us a positive/negative value // depending on the direction we have to rotate this.angleToDestination = Vector3.Dot(this.transform.right, this.directionVector.normalized); this.angleToBall = Mathf.Acos(Vector3.Dot((ballPosition - this.transform.position).normalized, this.transform.forward)) * Mathf.Rad2Deg; this.angleToBall = this.Angle360(transform.position, ballPosition, Vector3.right); this.distanceToTarget = Vector3.Distance(this.transform.position, this.destination); this.distanceToBall = Vector3.Distance(this.transform.position, ballPosition); } float Angle360(Vector3 from, Vector3 to, Vector3 right) { float angle = Vector3.Angle(from, to); return (Vector3.Angle(right, to) > 90f) ? 360f - angle : angle; } private void OnDrawGizmos() { Debug.DrawLine(this.transform.position, this.destination, Color.yellow, 0f, false); Debug.DrawLine(this.targetGoal.position, this.destination, Color.yellow, 0f, false); Gizmos.DrawSphere(this.destination, 1); Debug.DrawRay(transform.position, this.transform.forward * 10, Color.green); Debug.DrawRay(transform.position, this.directionVector.normalized * 10, Color.red); } public float[] GetInputs() { float[] inputs = new float[3]; inputs[AiInputs.VERTICAL] = 0; inputs[AiInputs.BOOST] = 0; if (this.distanceToTarget > 4) { inputs[AiInputs.VERTICAL] = 1; } inputs[AiInputs.HORIZONTAL] = Mathf.Floor(this.angleToDestination * 10) / 10; if (this.distanceToTarget < this.turnRadius) { inputs[AiInputs.HORIZONTAL] = Mathf.Floor(-this.angleToBall * 10) / 10; Debug.DrawRay(transform.position, transform.TransformDirection(-Vector3.forward) * 10, Color.magenta, 0,false); if (Physics.Raycast(transform.position, transform.TransformDirection(-Vector3.forward), 10)) { inputs[AiInputs.BOOST] = 1; } } if (this.distanceToBall < this.turnRadius) { RaycastHit hit; inputs[AiInputs.HORIZONTAL] = Mathf.Floor(-this.angleToBall * 10) / 10; if (Physics.Raycast(transform.position, this.directionVector, out hit, 5)) { if(hit.transform.tag == "Ball") { inputs[AiInputs.BOOST] = 1; } } } this.inputVector = new Vector3(inputs[AiInputs.HORIZONTAL], inputs[AiInputs.VERTICAL], inputs[AiInputs.BOOST]); //Left/Right, Fwd/Bkwd, Boost return inputs; } } public static class AiInputs { public const int HORIZONTAL = 0; public const int VERTICAL = 1; public const int BOOST = 2; }