Added Unity project for AI
Added FSM examples
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85700a85c4e447f68001925462ee456d
|
||||
timeCreated: 1776676690
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user