https://github.com/doprez/doprez.stride.ai
a Library meant to be used to handle AI in Stride games
https://github.com/doprez/doprez.stride.ai
stride3d
Last synced: 7 months ago
JSON representation
a Library meant to be used to handle AI in Stride games
- Host: GitHub
- URL: https://github.com/doprez/doprez.stride.ai
- Owner: Doprez
- License: mit
- Created: 2023-02-01T17:46:57.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2024-10-28T01:31:30.000Z (over 1 year ago)
- Last Synced: 2025-06-20T01:06:04.603Z (12 months ago)
- Topics: stride3d
- Language: C#
- Homepage:
- Size: 76.2 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Doprez.Stride
AI libraries to be used within [Stride3d](https://www.stride3d.net/) games
# Build Status
[](https://dl.circleci.com/status-badge/redirect/gh/Doprez/Doprez.Stride.AI/tree/master)
# Examples
## FSM Example
### We can start by inheriting from the FSM and implementing the base methods
```
using Doprez.Stride.AI.FiniteStateMachine;
public class BasicEnemyFSM : SyncScript
{
public FSM FiniteStateMachine { get; set; }
public override void Update()
{
FiniteStateMachine.ExecuteState();
}
}
```
### Create the State and needed methods
```
public class IdleState : FSMState
{
public IdleState(FSM fsm)
{
// set the FSM to access the methods within the running state
FiniteStateMachine = fsm;
// add this state to the FSM for other states to see this state
FiniteStateMachine.States.Add(0, this);
}
public override void EnterState()
{
// activate needed events or variables when this state is started
}
public override void ExitState()
{
// deactivate needed events or variables when this state is finished
}
public override void ExecuteState()
{
// this runs in the Update method of Stride per frame
}
}
```
## A more complete example
you can add the Doprez.Stride nuget package if some of the references are missing
### the FSM to initialize the state and allow per frame updates
```
using System;
using Doprez.Stride.AI.FiniteStateMachine;
using Stride.Core;
using Stride.Engine;
using StridePlatformer.States;
using Navigation;
public class BasicEnemyFSM : FSM
{
[Display("Player Entity")]
[DataMember(0)]
public Entity Player{get;set;}
[Display("Player Seen Trigger")]
[DataMember(2)]
public PhysicsComponent PlayerSeenTrigger;
[Display("Animation Component")]
[DataMember(20)]
public AnimationComponent AnimationComponent { get; set; }
//States
//private MoveToState _moveTo;
private IdleState _idle;
public override void Start()
{
InitializeStates();
SetCurrentState(_idle);
}
private void InitializeStates()
{
_idle = new IdleState(this, AnimationComponent);// ", _moveTo" add this if you added a moveTo state
_idle.PlayerSeenTrigger = PlayerSeenTrigger;
}
public override void ExecuteState()
{
// add some logic here if needed but it can just be blank
}
}
```
### An example Idle state with comments on how to change to another state
```
using System.Collections.Specialized;
using System.Threading.Tasks;
using Doprez.Stride.AI.FiniteStateMachine;
using Stride.Core.Collections;
using Stride.Engine;
using Stride.Physics;
public class IdleState : FSMState
{
public PhysicsComponent PlayerSeenTrigger;
private readonly AnimationComponent _animationComponent;
//add a state for you to change to like the example below
//private readonly MoveToState _moveTo;
public IdleState(FSM fsm, AnimationComponent animationComponent)// , MoveToState moveTo
{
FiniteStateMachine = fsm;
_animationComponent = animationComponent;
//_moveTo = moveTo;
FiniteStateMachine.States.Add((int)EnemyStates.Idle, this);
}
public override void EnterState()
{
//Only activate this trigger while the state is running
PlayerSeenTrigger.Enabled = true;
PlayerSeenTrigger.Collisions.CollectionChanged += CollisionsChanged;
//run the idle anim if you have one
//_animationComponent.Play("Idle");
}
public override void ExitState()
{
// stop using the trigger when the state isnt running
PlayerSeenTrigger.Enabled = false;
PlayerSeenTrigger.Collisions.CollectionChanged -= CollisionsChanged;
}
public override void ExecuteState()
{
}
private void CollisionsChanged(object sender, TrackingCollectionChangedEventArgs args)
{
// Cast the argument 'Item' to a collision object
var collision = (Collision)args.Item;
// We need to make sure which collision object is not the Trigger collider
// We perform a little check to find the ballCollider
var playerCollider = PlayerSeenTrigger == collision.ColliderA ? collision.ColliderB : collision.ColliderA;
if (args.Action == NotifyCollectionChangedAction.Add)
{
// When a collision has been added to the collision collection, we know an object has 'entered' our trigger
if (playerCollider.Entity.Name == "PlayerCharacter")
{
//get the entity that entered the trigger
var entitycollided = playerCollider.Entity;
//you can change the state by direct reference or the dictionary Id
//_moveTo.Target = entitycollided;
// change to a direct reference
//FiniteStateMachine.SetCurrentState(_moveTo);
// change based on a dictionary reference I would recommend setting up and Enum for readability
//FiniteStateMachine.SetCurrentState(1);
}
}
}
}
```
## GOAP example
TBD