Added Unity project for AI

Added FSM examples
This commit is contained in:
2026-04-20 12:49:00 +02:00
parent af72eec045
commit 3e8a3a56cf
83 changed files with 8059 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 32515c7c6b5840e798779a81ce76773e
timeCreated: 1776676676
@@ -0,0 +1,67 @@
using System;
using UnityEngine;
namespace AI.FSM
{
public class ChaseStateMachine : MonoBehaviour, IFiniteStateMachine
{
[SerializeField] private Transform playerController;
private IState _currentState;
// private IdleState _idleState;
// private PlayerDetectedState _playerDetectedState;
// // ...
private void OnEnable()
{
SetState(new IdleState(gameObject, playerController, 30.0f));
// _idleState = new IdleState(gameObject, playerController, 30.0f);
// _playerDetectedState = new PlayerDetectedState(gameObject, playerController, 10.0f);
// // ...
}
private void OnDisable()
{
SetState(null);
}
public void Update()
{
_currentState?.Update(this);
}
public void SetState(IState state)
{
_currentState?.Exit(this);
_currentState = state;
_currentState?.Enter(this);
}
// public void SetState(States state)
// {
// _currentState?.Exit(this);
//
// switch (state)
// {
// case States.Idle:
// _currentState = _idleState;
// break;
// case States.Chase:
// break;
// case States.PlayerDetected:
// _currentState = _playerDetectedState;
// break;
// case States.PlayerIsClose:
// break;
// case States.PlayerIsNotClose:
// break;
// default:
// throw new ArgumentOutOfRangeException(nameof(state), state, null);
// }
//
// _currentState?.Enter(this);
// }
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9454dea900ac47458b0b0a41b50f7351
timeCreated: 1776677402
@@ -0,0 +1,8 @@
namespace AI.FSM
{
public interface IFiniteStateMachine
{
void Update();
void SetState(IState state);
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7f066c3b30b04f618676e6308a711d49
timeCreated: 1776677142
+35
View File
@@ -0,0 +1,35 @@
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,
// Chase,
// PlayerDetected,
// PlayerIsClose,
// PlayerIsNotClose
// }
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 85700a85c4e447f68001925462ee456d
timeCreated: 1776676690
+51
View File
@@ -0,0 +1,51 @@
using System;
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;
}
PlayerController playerController = hit.collider.GetComponent<PlayerController>();
if (!playerController) return;
fsm.SetState(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: ec499b32ccf74c07aa50683eedfeba0e
timeCreated: 1776677266
@@ -0,0 +1,9 @@
using UnityEngine;
namespace AI.FSM
{
public class PlayerController : MonoBehaviour
{
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f50fe6d3af684cc0b92d937ba632eb15
timeCreated: 1776678807
@@ -0,0 +1,49 @@
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");
fsm.SetState(new PlayerIsCloseState());
}
else
{
// option 2: player is too far
Debug.Log("Player is too far");
fsm.SetState(new PlayerIsNotCloseState());
}
}
public void Exit(IFiniteStateMachine fsm)
{
Debug.Log("PlayerDetectedState Exit");
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3c2361f519b644e7af095c7497a73455
timeCreated: 1776677353
@@ -0,0 +1,17 @@
namespace AI.FSM
{
public class PlayerIsCloseState : IState
{
public void Enter(IFiniteStateMachine fsm)
{
}
public void Update(IFiniteStateMachine fsm)
{
}
public void Exit(IFiniteStateMachine fsm)
{
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a26014b1a66441cdaa696ce3b5e27928
timeCreated: 1776680288
@@ -0,0 +1,17 @@
namespace AI.FSM
{
public class PlayerIsNotCloseState : IState
{
public void Enter(IFiniteStateMachine fsm)
{
}
public void Update(IFiniteStateMachine fsm)
{
}
public void Exit(IFiniteStateMachine fsm)
{
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c7a9d5990db74dfea224458065f2a5eb
timeCreated: 1776680308
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 51434a457db9d453cab883468bf60180
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,58 @@
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.SetBool(IS_EXIT, !animator.GetBool(IS_EXIT));
}
}
public override void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
Debug.Log("TestStateBehaviour OnStateMove");
}
public override void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
Debug.Log("TestStateBehaviour OnStateIK");
}
public override void OnStateMachineEnter(Animator animator, int stateMachinePathHash)
{
base.OnStateMachineEnter(animator, stateMachinePathHash);
Debug.Log("TestStateBehaviour OnStateMachineEnter");
}
public override void OnStateMachineExit(Animator animator, int stateMachinePathHash)
{
base.OnStateMachineExit(animator, stateMachinePathHash);
Debug.Log("TestStateBehaviour OnStateMachineExit");
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a6b10e8225ce4540b47737d3ad6e9391
timeCreated: 1776673990