ashby-games/Unity/CarsDash/Assets/Scripts/AI/AICarController.cs
Ashby Issac c466e28d6c AI FSM changes.
- Protoyped on the AI movement, found solutions for turns and
   moving after impacting the player.
- Created a full base for AI state machine.
- Worked on binding the core AI logic with the finite state machine.
2026-01-07 19:38:03 +05:30

164 lines
4.3 KiB
C#
Executable File

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AICarController : MonoBehaviour, ICar
{
#region Fields
private float speed;
private float speedMax = 35f;
private float speedMin = -25f;
private float acceleration = 10f;
private float brakeSpeed = 50f;
private float reverseSpeed = 15f;
private float idleSlowdown = 5f;
private float turnSpeed;
private float turnSpeedMax = 150f;
private float turnSpeedAcceleration = 150f;
private float turnIdleSlowdown = 250f;
private float forwardAmount;
private float turnAmount;
private Rigidbody carRigidbody;
public GameplayManager GameplayManager
{
get;
private set;
}
#endregion
private void Awake()
{
carRigidbody = GetComponent<Rigidbody>();
}
public void Init(GameplayManager gameplayManager)
{
this.GameplayManager = gameplayManager;
}
private void Update()
{
CalculateAccelaration();
if (speed < 0)
{
// Going backwards, invert wheels
// turnAmount = turnAmount * -1f;
}
if (turnAmount > 0 || turnAmount < 0)
{
// Turning
if ((turnSpeed > 0 && turnAmount < 0) || (turnSpeed < 0 && turnAmount > 0))
{
// Changing turn direction
float minTurnAmount = 20f;
turnSpeed = turnAmount * minTurnAmount;
}
turnSpeed += turnAmount * turnSpeedAcceleration * Time.deltaTime;
}
else
{
// Not turning
if (turnSpeed > 0)
{
turnSpeed -= turnIdleSlowdown * Time.deltaTime;
}
if (turnSpeed < 0)
{
turnSpeed += turnIdleSlowdown * Time.deltaTime;
}
if (turnSpeed > -1f && turnSpeed < +1f) {
// Stop rotating
turnSpeed = 0f;
}
}
float speedNormalized = speed / speedMax;
float invertSpeedNormalized = Mathf.Clamp(1 - speedNormalized, .75f, 1f);
turnSpeed = Mathf.Clamp(turnSpeed, -turnSpeedMax, turnSpeedMax);
carRigidbody.angularVelocity = new Vector3(0, turnSpeed * (invertSpeedNormalized * 1f) * Mathf.Deg2Rad, 0);
if (transform.eulerAngles.x > 2 || transform.eulerAngles.x < -2 || transform.eulerAngles.z > 2 || transform.eulerAngles.z < -2)
{
transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, 0);
}
}
private void CalculateAccelaration()
{
if (forwardAmount > 0)
{
// Accelerating
speed += acceleration * Time.deltaTime;
}
else if (forwardAmount < 0)
{
if (speed > 0)
{
// Braking
speed += forwardAmount * brakeSpeed * Time.deltaTime;
}
else
{
// Reversing
speed += forwardAmount * reverseSpeed * Time.deltaTime;
}
}
else
{
// Not accelerating or braking
if (speed > 0)
{
speed -= idleSlowdown * Time.deltaTime;
}
if (speed < 0)
{
speed += idleSlowdown * Time.deltaTime;
}
}
speed = Mathf.Clamp(speed, speedMin, speedMax);
carRigidbody.velocity = transform.forward * speed;
}
public void SetInputs(float forwardAmount, float turnAmount) {
this.forwardAmount = forwardAmount;
this.turnAmount = turnAmount;
}
public void ClearTurnSpeed() {
turnSpeed = 0f;
}
public float GetSpeed() {
return speed;
}
public void SetSpeedMax(float speedMax) {
this.speedMax = speedMax;
}
public void SetTurnSpeedMax(float turnSpeedMax) {
this.turnSpeedMax = turnSpeedMax;
}
public void SetTurnSpeedAcceleration(float turnSpeedAcceleration) {
this.turnSpeedAcceleration = turnSpeedAcceleration;
}
public void StopCompletely() {
speed = 0f;
turnSpeed = 0f;
}
}