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.
This commit is contained in:
parent
90172daae5
commit
c466e28d6c
@ -22,4 +22,4 @@ MonoBehaviour:
|
||||
rotationSpeed: 2
|
||||
tireRotationAngle: 20
|
||||
speedValue: 50
|
||||
accelSpeed: 50
|
||||
accelSpeed: 100
|
||||
|
||||
8
Unity/CarsDash/Assets/Scenes/Main.meta
Normal file
8
Unity/CarsDash/Assets/Scenes/Main.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2190dc59a173e463f81234566cee14be
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
BIN
Unity/CarsDash/Assets/Scenes/Main/NavMesh.asset
Normal file
BIN
Unity/CarsDash/Assets/Scenes/Main/NavMesh.asset
Normal file
Binary file not shown.
8
Unity/CarsDash/Assets/Scenes/Main/NavMesh.asset.meta
Normal file
8
Unity/CarsDash/Assets/Scenes/Main/NavMesh.asset.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ccc494c7b34894ebdb6ab672fa47804d
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 23800000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Unity/CarsDash/Assets/Scripts/AI.meta
Normal file
8
Unity/CarsDash/Assets/Scripts/AI.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36d3513c3c72245678185ccd17a13c64
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
163
Unity/CarsDash/Assets/Scripts/AI/AICarController.cs
Executable file
163
Unity/CarsDash/Assets/Scripts/AI/AICarController.cs
Executable file
@ -0,0 +1,163 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
11
Unity/CarsDash/Assets/Scripts/AI/AICarController.cs.meta
Executable file
11
Unity/CarsDash/Assets/Scripts/AI/AICarController.cs.meta
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0fca7c6ea6b2be241844f325ebfca4c7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
142
Unity/CarsDash/Assets/Scripts/AI/AICarDriver.cs
Executable file
142
Unity/CarsDash/Assets/Scripts/AI/AICarDriver.cs
Executable file
@ -0,0 +1,142 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
11
Unity/CarsDash/Assets/Scripts/AI/AICarDriver.cs.meta
Executable file
11
Unity/CarsDash/Assets/Scripts/AI/AICarDriver.cs.meta
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb59b9c1ad3c8e34999f1b2e07b5774f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
5
Unity/CarsDash/Assets/Scripts/Abstraction/Car/ICar.cs
Normal file
5
Unity/CarsDash/Assets/Scripts/Abstraction/Car/ICar.cs
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
public interface ICar
|
||||
{
|
||||
void Init(GameplayManager gameplayManager);
|
||||
}
|
||||
11
Unity/CarsDash/Assets/Scripts/Abstraction/Car/ICar.cs.meta
Normal file
11
Unity/CarsDash/Assets/Scripts/Abstraction/Car/ICar.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a269c48eac634e32be15927f5f67a83
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,19 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
|
||||
public class AIController : MonoBehaviour
|
||||
{
|
||||
private BaseState currentState;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
currentState = new IdleState();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
currentState = currentState.ProcessStates();
|
||||
}
|
||||
}
|
||||
25
Unity/CarsDash/Assets/Scripts/FSM/AIStateProcesser.cs
Normal file
25
Unity/CarsDash/Assets/Scripts/FSM/AIStateProcesser.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class AIStateProcesser : MonoBehaviour
|
||||
{
|
||||
private BaseState currentState;
|
||||
private AICarDriver carDriverAI;
|
||||
private AICarController aiCarController;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
carDriverAI = GetComponent<AICarDriver>();
|
||||
aiCarController = GetComponent<AICarController>();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
currentState = new IdleState(carDriverAI, aiCarController.GameplayManager);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
currentState = currentState.ProcessStates();
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@ using UnityEngine;
|
||||
|
||||
public class AcquireTargetState : BaseState
|
||||
{
|
||||
public AcquireTargetState() : base()
|
||||
public AcquireTargetState(AICarDriver aiCarDriver, GameplayManager gameplayManager) : base(aiCarDriver, gameplayManager)
|
||||
{
|
||||
Debug.Log($"### {this} constructor");
|
||||
}
|
||||
@ -19,6 +19,14 @@ public class AcquireTargetState : BaseState
|
||||
base.Update();
|
||||
|
||||
Debug.Log($"### {this} Update STAGE");
|
||||
|
||||
// while it's roaming check for targets
|
||||
// Find the target and once the target is found then charge toward that specific target
|
||||
if (HasFoundTarget())
|
||||
{
|
||||
base.Exit();
|
||||
nextState = new ChargeState(aiCarDriver, gameplayManager);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Exit()
|
||||
@ -27,4 +35,10 @@ public class AcquireTargetState : BaseState
|
||||
|
||||
Debug.Log($"### {this} Exit STAGE");
|
||||
}
|
||||
|
||||
public bool HasFoundTarget()
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,20 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
public class BaseState
|
||||
{
|
||||
protected STAGE stage;
|
||||
protected BaseState nextState;
|
||||
protected Transform currentTarget;
|
||||
protected AICarDriver aiCarDriver;
|
||||
protected GameplayManager gameplayManager;
|
||||
|
||||
public BaseState()
|
||||
public BaseState(AICarDriver aiCarDriver, GameplayManager gameplayManager)
|
||||
{
|
||||
stage = STAGE.Enter;
|
||||
|
||||
this.aiCarDriver = aiCarDriver;
|
||||
this.gameplayManager = gameplayManager;
|
||||
}
|
||||
|
||||
protected virtual void Enter() => stage = STAGE.Update;
|
||||
|
||||
@ -2,7 +2,7 @@ using UnityEngine;
|
||||
|
||||
public class ChargeState : BaseState
|
||||
{
|
||||
public ChargeState() : base()
|
||||
public ChargeState(AICarDriver aiCarDriver, GameplayManager gameplayManager) : base(aiCarDriver, gameplayManager)
|
||||
{
|
||||
Debug.Log($"### {this} constructor");
|
||||
}
|
||||
@ -12,6 +12,7 @@ public class ChargeState : BaseState
|
||||
base.Enter();
|
||||
|
||||
Debug.Log($"### {this} Enter STAGE");
|
||||
// update the values for charging
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
@ -19,6 +20,11 @@ public class ChargeState : BaseState
|
||||
base.Update();
|
||||
|
||||
Debug.Log($"### {this} Update STAGE");
|
||||
aiCarDriver.UpdateMovement(() =>
|
||||
{
|
||||
base.Exit();
|
||||
nextState = new ImpactState(aiCarDriver, gameplayManager);
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Exit()
|
||||
|
||||
@ -3,7 +3,7 @@ using UnityEngine;
|
||||
|
||||
public class IdleState : BaseState
|
||||
{
|
||||
public IdleState() : base()
|
||||
public IdleState(AICarDriver aiCarDriver, GameplayManager gameplayManager) : base(aiCarDriver, gameplayManager)
|
||||
{
|
||||
Debug.Log($"### {this} constructor");
|
||||
}
|
||||
@ -20,7 +20,9 @@ public class IdleState : BaseState
|
||||
base.Update();
|
||||
|
||||
// use a mod timer system and when timer completes then move onto the next state (RoamState)
|
||||
nextState = new RoamState();
|
||||
base.Exit();
|
||||
|
||||
nextState = new AcquireTargetState(aiCarDriver, gameplayManager);
|
||||
Debug.Log($"### {this} Update STAGE");
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ using UnityEngine;
|
||||
|
||||
public class ImpactState : BaseState
|
||||
{
|
||||
public ImpactState() : base()
|
||||
public ImpactState(AICarDriver aiCarDriver, GameplayManager gameplayManager) : base(aiCarDriver, gameplayManager)
|
||||
{
|
||||
Debug.Log($"### {this} constructor");
|
||||
}
|
||||
@ -19,6 +19,10 @@ public class ImpactState : BaseState
|
||||
base.Update();
|
||||
|
||||
Debug.Log($"### {this} Update STAGE");
|
||||
|
||||
// do actions when an impact happens
|
||||
base.Exit();
|
||||
nextState = new RecoverState(aiCarDriver, gameplayManager);
|
||||
}
|
||||
|
||||
protected override void Exit()
|
||||
|
||||
@ -2,7 +2,7 @@ using UnityEngine;
|
||||
|
||||
public class RecoverState : BaseState
|
||||
{
|
||||
public RecoverState() : base()
|
||||
public RecoverState(AICarDriver aiCarDriver, GameplayManager gameplayManager) : base(aiCarDriver, gameplayManager)
|
||||
{
|
||||
Debug.Log($"### {this} constructor");
|
||||
}
|
||||
@ -19,6 +19,11 @@ public class RecoverState : BaseState
|
||||
base.Update();
|
||||
|
||||
Debug.Log($"### {this} Update STAGE");
|
||||
aiCarDriver.DoReverse(() =>
|
||||
{
|
||||
base.Exit();
|
||||
nextState = new RoamState(aiCarDriver, gameplayManager);
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Exit()
|
||||
|
||||
@ -2,7 +2,13 @@ using UnityEngine;
|
||||
|
||||
public class RoamState : BaseState
|
||||
{
|
||||
public RoamState() : base()
|
||||
private bool hasCompletedRoaming = false;
|
||||
private float roamDuration = 2f;
|
||||
|
||||
private Vector3 currentRoamingPoint = Vector3.zero;
|
||||
private TimerSystem roamTimerSystem = null;
|
||||
|
||||
public RoamState(AICarDriver aiCarDriver, GameplayManager gameplayManager) : base(aiCarDriver, gameplayManager)
|
||||
{
|
||||
Debug.Log($"### {this} constructor");
|
||||
}
|
||||
@ -14,20 +20,39 @@ public class RoamState : BaseState
|
||||
Debug.Log($"### {this} Enter STAGE");
|
||||
|
||||
// get the target point
|
||||
currentRoamingPoint = gameplayManager.GetRoamingPoint();
|
||||
aiCarDriver.SetTargetPosition(currentRoamingPoint);
|
||||
|
||||
roamTimerSystem = new TimerSystem();
|
||||
hasCompletedRoaming = false;
|
||||
roamTimerSystem.Init(roamDuration, onComplete: () => hasCompletedRoaming = true);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
// keeping roaming for a specific duration
|
||||
// keep roaming for a specific duration
|
||||
|
||||
// use a set of target points which would be placed on the arena,
|
||||
// get one of the target point and then start roaming towards that point.
|
||||
// if an enemy/player is found within a specific radius and in front of-
|
||||
// -the player then go to the next state after acquiring the target-
|
||||
// -the AI then go to the next state after acquiring the target-
|
||||
// -(next state could be ChargeState)
|
||||
|
||||
// Set Target location
|
||||
|
||||
if (!hasCompletedRoaming)
|
||||
{
|
||||
roamTimerSystem.UpdateTimer(Time.deltaTime);
|
||||
aiCarDriver.UpdateMovement();
|
||||
}
|
||||
else
|
||||
{
|
||||
base.Exit();
|
||||
nextState = new AcquireTargetState(aiCarDriver, gameplayManager);
|
||||
}
|
||||
|
||||
Debug.Log($"### {this} Update STAGE");
|
||||
}
|
||||
|
||||
|
||||
@ -4,10 +4,8 @@ using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.EventSystems;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
public class CarController : MonoBehaviour
|
||||
public class PlayerCarController : MonoBehaviour, ICar
|
||||
{
|
||||
[SerializeField] private bool isDebugTest = false;
|
||||
|
||||
@ -17,7 +15,7 @@ public class CarController : MonoBehaviour
|
||||
|
||||
[SerializeField] private Rigidbody carRigidbody;
|
||||
|
||||
[SerializeField] private CarSpecs carSpecs;
|
||||
[SerializeField] private PlayerCarSpecs carSpecs;
|
||||
[SerializeField] private Vector3 customCenterOfMass;
|
||||
[SerializeField] private AnimationCurve steerLeftAnimCurve;
|
||||
[SerializeField] private AnimationCurve steerRightAnimCurve;
|
||||
@ -33,7 +31,7 @@ public class CarController : MonoBehaviour
|
||||
private float tiresInGround = 0f;
|
||||
|
||||
[Category("Script-Object-Refs.")]
|
||||
private CarSystem carSystem;
|
||||
private PlayerCarSystem carSystem;
|
||||
private TimerSystem timerSystem;
|
||||
|
||||
[Category("Tags.")]
|
||||
@ -50,14 +48,22 @@ public class CarController : MonoBehaviour
|
||||
public Action<float> OnCarRotate;
|
||||
public Action<string> OnGameOver;
|
||||
|
||||
public void Init()
|
||||
public GameplayManager GameplayManager
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public void Init(GameplayManager gameplayManager)
|
||||
{
|
||||
this.GameplayManager = gameplayManager;
|
||||
|
||||
isGameOver = false;
|
||||
tiresCount = tireTransforms.Length;
|
||||
|
||||
timerSystem = new TimerSystem();
|
||||
remTime = timerSystem.Timer;
|
||||
carSystem = new CarSystem(this, carRigidbody, carSpecs, frontTireTransforms, steerLeftAnimCurve: steerLeftAnimCurve, steerRightAnimCurve: steerRightAnimCurve, accelAnimCurve: accelAnimCurve);
|
||||
// remTime = timerSystem.Timer;
|
||||
carSystem = new PlayerCarSystem(this, carRigidbody, carSpecs, frontTireTransforms, steerLeftAnimCurve: steerLeftAnimCurve, steerRightAnimCurve: steerRightAnimCurve, accelAnimCurve: accelAnimCurve);
|
||||
}
|
||||
|
||||
private void EnableGameOverState()
|
||||
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[CreateAssetMenu(fileName = "CarSpecs", menuName = "CarSpecs", order = 1)]
|
||||
public class CarSpecs : ScriptableObject
|
||||
public class PlayerCarSpecs : ScriptableObject
|
||||
{
|
||||
public float dampingForce = 50;
|
||||
public float strength = 500;
|
||||
@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using UnityEngine;
|
||||
|
||||
public class CarSystem : ICarComponents
|
||||
public class PlayerCarSystem : ICarComponents
|
||||
{
|
||||
[Category("Global Attributes")] private Rigidbody carRigidbody;
|
||||
private CarSpecs carSpecs;
|
||||
private PlayerCarSpecs carSpecs;
|
||||
|
||||
[Category("Animation Curves")] private AnimationCurve steerLeftAnimCurve;
|
||||
[Category("Animation Curves")] private AnimationCurve steerRightAnimCurve;
|
||||
@ -29,9 +29,9 @@ public class CarSystem : ICarComponents
|
||||
private Vector3 accelForce;
|
||||
|
||||
private Transform[] frontTireTransforms;
|
||||
private CarController gameplayControllerInst;
|
||||
private PlayerCarController gameplayControllerInst;
|
||||
|
||||
public CarSystem(CarController gameplayController, Rigidbody carRigidbody = null, CarSpecs carSpecs = null, Transform[] frontTireTransforms = null,
|
||||
public PlayerCarSystem(PlayerCarController gameplayController, Rigidbody carRigidbody = null, PlayerCarSpecs carSpecs = null, Transform[] frontTireTransforms = null,
|
||||
AnimationCurve steerLeftAnimCurve = null, AnimationCurve steerRightAnimCurve = null, AnimationCurve accelAnimCurve = null)
|
||||
{
|
||||
gameplayControllerInst = gameplayController;
|
||||
@ -1,12 +1,17 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
{
|
||||
[SerializeField] private CarController carController;
|
||||
[SerializeField] private GameObject[] allCarsInScene; // contains enemy cars and player car
|
||||
[]
|
||||
[SerializeField] private PlayerCarController playerCarController; // TODO :: initialize roamPoints here
|
||||
|
||||
public CarController CarController => carController;
|
||||
[SerializeField] private List<Transform> roamPoints; // TODO :: initialize roamPoints here
|
||||
|
||||
public PlayerCarController CarController => playerCarController;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
@ -15,6 +20,21 @@ public class GameplayManager : MonoBehaviour, IBase, IBootLoader, IDataLoader
|
||||
|
||||
public void InitializeData()
|
||||
{
|
||||
carController.Init();
|
||||
foreach (var car in allCarsInScene)
|
||||
{
|
||||
car.GetComponent<ICar>().Init(this);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 GetRoamingPoint()
|
||||
{
|
||||
var randomIndex = Random.Range(0, roamPoints.Count);
|
||||
return roamPoints[randomIndex].position;
|
||||
}
|
||||
|
||||
public Transform GetTargetToAttack()
|
||||
{
|
||||
var randomIdx = Random.Range(0, allCarsInScene.Length);
|
||||
return allCarsInScene[randomIdx].transform;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,29 +1,50 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class TimerSystem
|
||||
{
|
||||
private float timer = 10f;
|
||||
private float timerIncrement = 5f;
|
||||
private float timeRem;
|
||||
private float maxTimeAvail;
|
||||
|
||||
public float Timer => timer;
|
||||
|
||||
public float TimerIncrement = 5f;
|
||||
|
||||
public TimerSystem()
|
||||
private Action onTimerComplete = null;
|
||||
private Action onTimerInProgress = null;
|
||||
public bool IsTimerComplete
|
||||
{
|
||||
CarController.OnCheckpointReached += UpdateTimer;
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
private void IncreaseTimer()
|
||||
public bool IsInitialized
|
||||
{
|
||||
timer += timerIncrement;
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public void UpdateTimer(float remTime)
|
||||
public void Init(float maxTimeAvail, Action onComplete = null, Action inProgress = null, Action onStart = null)
|
||||
{
|
||||
timer = remTime;
|
||||
IncreaseTimer();
|
||||
timeRem = 0;
|
||||
IsTimerComplete = false;
|
||||
IsInitialized = true;
|
||||
|
||||
this.maxTimeAvail = maxTimeAvail;
|
||||
this.onTimerComplete = onComplete;
|
||||
this.onTimerInProgress = inProgress;
|
||||
}
|
||||
|
||||
public void UpdateTimer(float deltaTime)
|
||||
{
|
||||
if (timeRem < maxTimeAvail)
|
||||
{
|
||||
timeRem += deltaTime;
|
||||
onTimerInProgress?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
timeRem = 0;
|
||||
onTimerComplete?.Invoke();
|
||||
IsTimerComplete = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ NavMeshProjectSettings:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
m_LastAgentTypeID: -887442657
|
||||
m_LastAgentTypeID: -1372625422
|
||||
m_Settings:
|
||||
- serializedVersion: 2
|
||||
agentTypeID: 0
|
||||
@ -85,7 +85,28 @@ NavMeshProjectSettings:
|
||||
manualTileSize: 0
|
||||
tileSize: 256
|
||||
accuratePlacement: 0
|
||||
maxJobWorkers: 0
|
||||
preserveTilesOutsideBounds: 0
|
||||
debug:
|
||||
m_Flags: 0
|
||||
- serializedVersion: 2
|
||||
agentTypeID: -1372625422
|
||||
agentRadius: 0.5
|
||||
agentHeight: 1.2
|
||||
agentSlope: 45
|
||||
agentClimb: 0.4
|
||||
ledgeDropHeight: 0
|
||||
maxJumpAcrossDistance: 0
|
||||
minRegionArea: 2
|
||||
manualCellSize: 0
|
||||
cellSize: 0.16666667
|
||||
manualTileSize: 0
|
||||
tileSize: 256
|
||||
accuratePlacement: 0
|
||||
maxJobWorkers: 0
|
||||
preserveTilesOutsideBounds: 0
|
||||
debug:
|
||||
m_Flags: 0
|
||||
m_SettingNames:
|
||||
- Humanoid
|
||||
- New Agent
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user