- 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.
143 lines
4.4 KiB
C#
Executable File
143 lines
4.4 KiB
C#
Executable File
using System;
|
|
using DG.Tweening;
|
|
using Unity.VisualScripting;
|
|
using UnityEditor.Callbacks;
|
|
using UnityEngine;
|
|
|
|
public class AICarDriver : MonoBehaviour
|
|
{
|
|
|
|
[SerializeField] private Transform targetPositionTranform;
|
|
|
|
private AICarController carDriver;
|
|
private Vector3 targetPosition;
|
|
|
|
private void Awake()
|
|
{
|
|
carDriver = GetComponent<AICarController>();
|
|
impactTimer = new TimerSystem();
|
|
|
|
// SetImpactTimer();
|
|
}
|
|
|
|
private TimerSystem impactTimer;
|
|
private float forwardAmount = 0f;
|
|
private float turnAmount = 0f;
|
|
|
|
public void UpdateMovement(Action onComplete = null)
|
|
{
|
|
// provide a roamPoint
|
|
SetTargetPosition(targetPositionTranform.position);
|
|
|
|
float targetDistReach = 2f;
|
|
float distanceToTarget = Vector3.Distance(transform.position, targetPosition);
|
|
|
|
Debug.Log($"distanceToTarget :: {distanceToTarget}");
|
|
|
|
if (distanceToTarget > targetDistReach)
|
|
{
|
|
// Still too far, keep going
|
|
Vector3 dirToMovePosition = (targetPosition - transform.position).normalized;
|
|
float dot = Vector3.Dot(transform.forward, dirToMovePosition);
|
|
|
|
if (dot > 0)
|
|
{
|
|
// Target in front
|
|
forwardAmount = 1f;
|
|
|
|
float stoppingDistance = 2f;
|
|
float stoppingSpeed = 5f;
|
|
|
|
// if (onImpact)
|
|
// {
|
|
// the target location should be set to next roam point or to another enemy/player
|
|
// and then DoReverse()
|
|
// DoReverse();
|
|
// }
|
|
// else if (canCheck)
|
|
// {
|
|
if (distanceToTarget < stoppingDistance && carDriver.GetSpeed() > stoppingSpeed)
|
|
{
|
|
// Within stopping distance and moving forward too fast
|
|
forwardAmount = -1f;
|
|
}
|
|
// }
|
|
|
|
// after impact reverse for about 0.5 seconds
|
|
}
|
|
else
|
|
{
|
|
// Target behind
|
|
float reverseDistance = 25f;
|
|
if (distanceToTarget > reverseDistance)
|
|
{
|
|
// Too far to reverse
|
|
forwardAmount = 1f;
|
|
// if (onImpact)
|
|
// {
|
|
// the target location should be set to next roam point or to another enemy/player
|
|
// and then DoReverse()
|
|
// DoReverse();
|
|
// }
|
|
}
|
|
else
|
|
{
|
|
forwardAmount = -1f;
|
|
// Check if DoReverse can be called instead
|
|
}
|
|
}
|
|
|
|
turnAmount = FindTurnAmt();
|
|
}
|
|
else
|
|
{
|
|
// Reached target
|
|
Debug.Log($"Target reached: {forwardAmount}");
|
|
if (forwardAmount == 1)
|
|
onComplete?.Invoke();
|
|
|
|
forwardAmount = carDriver.GetSpeed() > 15f ? -1f : 0f;
|
|
turnAmount = 0f;
|
|
}
|
|
|
|
carDriver.SetInputs(forwardAmount, turnAmount);
|
|
}
|
|
|
|
public void DoReverse(Action onComplete)
|
|
{
|
|
// TODO :: Set target position before doing reverse
|
|
|
|
Debug.Log($"CarDriverAI :: onImpact");
|
|
|
|
if (impactTimer.IsTimerComplete)
|
|
{
|
|
impactTimer.Init(0.5f, onComplete: () =>
|
|
{
|
|
Debug.Log($"ImpactTimer :: OnTimerComplete");
|
|
|
|
forwardAmount = 1f;
|
|
turnAmount = FindTurnAmt();
|
|
carDriver.SetInputs(forwardAmount, turnAmount);
|
|
onComplete?.Invoke();
|
|
});
|
|
}
|
|
|
|
impactTimer.UpdateTimer(Time.deltaTime);
|
|
forwardAmount = -1f;
|
|
turnAmount = FindTurnAmt();
|
|
carDriver.SetInputs(forwardAmount, turnAmount);
|
|
}
|
|
|
|
private float FindTurnAmt()
|
|
{
|
|
Vector3 dirToMovePosition = (targetPosition - transform.position).normalized;
|
|
float angleToDir = Vector3.SignedAngle(transform.forward, dirToMovePosition, Vector3.up);
|
|
return angleToDir > 0 ? 1f : -1f;
|
|
}
|
|
|
|
public void SetTargetPosition(Vector3 targetPosition)
|
|
{
|
|
this.targetPosition = targetPosition;
|
|
}
|
|
}
|