add unity project

add example for FSM
This commit is contained in:
2025-04-08 13:03:11 +02:00
parent 7e484e4831
commit 19a08085fe
81 changed files with 7741 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
using System;
using UnityEngine;
namespace DefaultNamespace.FSM
{
public class ChaseSystem : MonoBehaviour, IFiniteStateMachine
{
[SerializeField] private PlayerController _playerController;
private IState _currentState = null;
private void OnEnable()
{
_currentState = new IdleState(gameObject, _playerController, 60.0f);
}
private void OnDisable()
{
_currentState = null;
}
public void Update()
{
if (_currentState == null) return;
_currentState.Update(this);
}
public void SetState(IState state)
{
_currentState.Exit(this);
_currentState = state;
_currentState.Enter(this);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 57f3192b52a14940bca9ed3e3f3cc9e0
timeCreated: 1744104642
@@ -0,0 +1,8 @@
namespace DefaultNamespace.FSM
{
public interface IFiniteStateMachine
{
void Update();
void SetState(IState state);
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e982c7f159f6462bbeb1aa9af73e9d66
timeCreated: 1744104811
+25
View File
@@ -0,0 +1,25 @@
namespace DefaultNamespace.FSM
{
public interface IState
{
void Enter(IFiniteStateMachine ctx);
void Update(IFiniteStateMachine ctx);
void Exit(IFiniteStateMachine ctx);
}
// alternative
// public interface IStateEnter
// {
// void Enter(IFiniteStateMachine ctx);
// }
//
// public interface IStateUpdate
// {
// void Update(IFiniteStateMachine ctx);
// }
//
// public interface IStateExit
// {
// void Exit(IFiniteStateMachine ctx);
// }
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b4320145c61c4b1b8536b19aa2a76317
timeCreated: 1744104656
+53
View File
@@ -0,0 +1,53 @@
using System;
using UnityEngine;
namespace DefaultNamespace.FSM
{
public class IdleState : IState
{
private GameObject _owner;
private PlayerController _playerController;
private float _viewAngle;
private float _cosViewAngle;
public IdleState(GameObject owner, PlayerController player, float viewAngle)
{
_owner = owner;
_playerController = player;
_viewAngle = viewAngle;
_cosViewAngle = Mathf.Cos(_viewAngle * Mathf.Deg2Rad);
}
public void Enter(IFiniteStateMachine ctx)
{
Debug.Log("Enter");
}
public void Update(IFiniteStateMachine ctx)
{
Debug.Log("Update");
// option 1 view angle
float angle = Vector3.Angle(_owner.transform.forward, _playerController.transform.position - _owner.transform.position);
if (angle > _viewAngle) return;
// option 2 trigger
// option 3 Physics.SphereCast, Physics.BoxCast, ...
if (Physics.Raycast(_owner.transform.position, _owner.transform.forward, out RaycastHit hit, 1000))
{
if (hit.transform.GetComponent<PlayerController>() == _playerController)
{
ctx.SetState(new PlayerDetectedState(_owner, _playerController, 10.0f));
}
}
}
public void Exit(IFiniteStateMachine ctx)
{
Debug.Log("Exit");
}
}
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d2248dcdef8641fc8d5b039bbdd90c97
timeCreated: 1744105354
@@ -0,0 +1,49 @@
using System;
using UnityEngine;
namespace DefaultNamespace.FSM
{
[Serializable]
public class PlayerDetectedState : IState
{
[SerializeField] private float _radius;
private GameObject _owner;
private PlayerController _playerController;
public PlayerDetectedState(GameObject owner, PlayerController player, float radius)
{
_owner = owner;
_playerController = player;
_radius = radius;
}
public void Enter(IFiniteStateMachine ctx)
{
}
public void Update(IFiniteStateMachine ctx)
{
// get distance to player
float distance = Vector3.Distance(_owner.transform.position, _playerController.transform.position);
// compare to radius
if (distance < _radius)
{
// set to is in range state
Debug.Log("Player is in range");
}
else
{
// set to is out of range state
Debug.Log("Player is out of range");
}
}
public void Exit(IFiniteStateMachine ctx)
{
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8d3a019ee7544f4da35a5179ac4828a8
timeCreated: 1744105868