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