Added AI Unity project

Added FSM examples
This commit is contained in:
2026-04-20 18:37:00 +02:00
parent cc260fa480
commit 10f61fd5d9
79 changed files with 7891 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 56fc2f02d4ab4791bde4f722fee08efb
timeCreated: 1776697249
@@ -0,0 +1,68 @@
using System;
using UnityEngine;
namespace AI.FSM
{
public class ChaseStateMachine : MonoBehaviour, IFiniteStateMachine
{
[SerializeField] private Transform player;
private IState _currentState;
// private IdleState _idleState;
// private PlayerDetectedState _playerDetectedState;
// // ...
// private void Awake()
// {
// _idleState = new IdleState();
// _playerDetectedState = new PlayerDetectedState();
// // ...
// }
private void OnEnable()
{
ChangeState(new IdleState(gameObject, player, 30.0f));
}
private void OnDisable()
{
ChangeState(null);
}
public void Update()
{
_currentState?.Update(this);
}
public void ChangeState(IState state)
{
_currentState?.Exit(this);
_currentState = state;
_currentState?.Enter(this);
}
// public void ChangeState(States state)
// {
// _currentState?.Exit(this);
//
// switch (state)
// {
// case States.Idle:
// _currentState = _idleState;
// break;
// case States.PlayerDetected:
// _currentState = _playerDetectedState;
// break;
// case States.PlayerInRange:
// break;
// case States.PlayerOutOfRange:
// break;
// default:
// throw new ArgumentOutOfRangeException(nameof(state), state, null);
// }
//
// _currentState?.Enter(this);
// }
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ae3ec7f7728d4494b82e7015fbd8acf1
timeCreated: 1776698095
@@ -0,0 +1,8 @@
namespace AI.FSM
{
public interface IFiniteStateMachine
{
void Update();
void ChangeState(IState state);
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f9e861b70812436e89dd524cf8fcc4a3
timeCreated: 1776697808
+34
View File
@@ -0,0 +1,34 @@
namespace AI.FSM
{
public interface IState
{
void Enter(IFiniteStateMachine fsm);
void Update(IFiniteStateMachine fsm);
void Exit(IFiniteStateMachine fsm);
}
// alternative
// public interface IStateEnter
// {
// void Enter(IFiniteStateMachine fsm);
// }
//
// public interface IStateUpdate
// {
// void Update(IFiniteStateMachine fsm);
// }
//
// public interface IStateExit
// {
// void Exit(IFiniteStateMachine fsm);
// }
// works, but not recommended
// public enum States
// {
// Idle,
// PlayerDetected,
// PlayerInRange,
// PlayerOutOfRange,
// }
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 45a2f94152b641d3b7fc7794129c3587
timeCreated: 1776697265
+47
View File
@@ -0,0 +1,47 @@
using DefaultNamespace;
using UnityEngine;
namespace AI.FSM
{
public class IdleState : IState
{
private GameObject _owner;
private Transform _player;
private float _viewAngle;
public IdleState(GameObject owner, Transform player, float viewAngle)
{
_owner = owner;
_player = player;
_viewAngle = viewAngle;
}
public void Enter(IFiniteStateMachine fsm)
{
Debug.Log("IdleState Enter");
}
public void Update(IFiniteStateMachine fsm)
{
Debug.Log("IdleState Update");
// view angle
float angle = Vector3.Angle(_owner.transform.forward, _player.position - _owner.transform.position);
if (angle > _viewAngle) return;
// raycast
RaycastHit hit;
if (!Physics.Raycast(_owner.transform.position, _player.position - _owner.transform.position, out hit, 100f)) return;
// if (hit.collider.transform != _player) return;
PlayerController playerController = hit.collider.GetComponent<PlayerController>();
if (!playerController) return;
fsm.ChangeState(new PlayerDetectedState(_owner, _player, 10.0f));
}
public void Exit(IFiniteStateMachine fsm)
{
Debug.Log("IdleState Exit");
}
}
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 86d17057fea140a980c38a99b7530ff3
timeCreated: 1776697917
@@ -0,0 +1,55 @@
using UnityEngine;
namespace AI.FSM
{
public class PlayerDetectedState : IState
{
private GameObject _owner;
private Transform _player;
private float _radius;
public PlayerDetectedState(GameObject owner, Transform player, float radius)
{
_owner = owner;
_player = player;
_radius = radius;
}
public void Enter(IFiniteStateMachine fsm)
{
Debug.Log("PlayerDetectedState Enter");
}
public void Update(IFiniteStateMachine fsm)
{
Debug.Log("PlayerDetectedState Update");
// distance to player
float distance = Vector3.Distance(_owner.transform.position, _player.position);
if (distance < _radius)
{
// option 1: player is close enough
Debug.Log("Player is close enough");
}
else
{
// option 2: player is too far
Debug.Log("Player is too far");
fsm.ChangeState(new IdleState(_owner, _player, 30.0f));
}
}
public void Exit(IFiniteStateMachine fsm)
{
Debug.Log("PlayerDetectedState Exit");
}
}
}
public static class GameValues
{
public static float PlayerDetectionRadius = 10.0f;
public static float EnemyViewAngle = 30.0f;
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d66d99bf8277449cb294cd607e028a6a
timeCreated: 1776697940
+9
View File
@@ -0,0 +1,9 @@
using UnityEngine;
namespace DefaultNamespace
{
public class PlayerController : MonoBehaviour
{
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b1786c74662e44c5b7780327d5aab49c
timeCreated: 1776701975
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c42c41ac08c4445c4bb2f134ba80d1c5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,54 @@
using UnityEngine;
using UnityEngine.InputSystem;
namespace AI.StateMachineBehaviours
{
public class TestStateBehaviour : StateMachineBehaviour
{
private static readonly int IS_EXIT = Animator.StringToHash("IsExit");
[SerializeField] private InputActionReference inputAction;
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
Debug.Log("TestStateBehaviour OnStateEnter");
inputAction.action.Enable();
}
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
Debug.Log("TestStateBehaviour OnStateExit");
inputAction.action.Disable();
}
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
Debug.Log("TestStateBehaviour OnStateUpdate");
if (inputAction.action.triggered)
{
animator.SetTrigger(IS_EXIT);
}
}
public override void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
Debug.Log("TestStateBehaviour OnStateIK");
}
public override void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
Debug.Log("TestStateBehaviour OnStateMove");
}
public override void OnStateMachineEnter(Animator animator, int stateMachinePathHash)
{
Debug.Log("TestStateBehaviour OnStateMachineEnter");
}
public override void OnStateMachineExit(Animator animator, int stateMachinePathHash)
{
Debug.Log("TestStateBehaviour OnStateMachineExit");
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1d8920bea0824f22b41a06397cd8dd49
timeCreated: 1776694487