143 lines
4.2 KiB
C#
143 lines
4.2 KiB
C#
|
|
using System;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Reflection;
|
||
|
|
using System.Runtime.CompilerServices;
|
||
|
|
using System.Threading;
|
||
|
|
using AlicizaX;
|
||
|
|
using AlicizaX.Fsm;
|
||
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
|
||
|
|
public enum PlayerState
|
||
|
|
{
|
||
|
|
Idle,
|
||
|
|
Move,
|
||
|
|
Jump,
|
||
|
|
Dead
|
||
|
|
}
|
||
|
|
|
||
|
|
public sealed class PlayerBlackBoard : IMemory
|
||
|
|
{
|
||
|
|
public float Hp;
|
||
|
|
public bool Grounded;
|
||
|
|
public Vector3 Pos;
|
||
|
|
public Vector3 Vel;
|
||
|
|
|
||
|
|
public void Clear()
|
||
|
|
{
|
||
|
|
Hp = 100f;
|
||
|
|
Grounded = true;
|
||
|
|
Pos = Vector3.zero;
|
||
|
|
Vel = Vector3.zero;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static class PlayerFSM
|
||
|
|
{
|
||
|
|
public static readonly StateFunc<PlayerBlackBoard>[] Funcs;
|
||
|
|
public static readonly Transition<PlayerBlackBoard>[] Trans;
|
||
|
|
|
||
|
|
static PlayerFSM()
|
||
|
|
{
|
||
|
|
Funcs = new StateFunc<PlayerBlackBoard>[3];
|
||
|
|
|
||
|
|
Funcs[(int)PlayerState.Idle] = StateFunc<PlayerBlackBoard>.Make(
|
||
|
|
(PlayerBlackBoard b) => { },
|
||
|
|
(PlayerBlackBoard b) =>
|
||
|
|
{
|
||
|
|
var h = Input.GetAxisRaw("Horizontal");
|
||
|
|
var v = Input.GetAxisRaw("Vertical");
|
||
|
|
if (h != 0 || v != 0) return (int)PlayerState.Move;
|
||
|
|
if (Input.GetKeyDown(KeyCode.Space) && b.Grounded) return (int)PlayerState.Jump;
|
||
|
|
return -1;
|
||
|
|
},
|
||
|
|
(PlayerBlackBoard b) => { }
|
||
|
|
);
|
||
|
|
|
||
|
|
Funcs[(int)PlayerState.Move] = StateFunc<PlayerBlackBoard>.Make(
|
||
|
|
(PlayerBlackBoard b) => { },
|
||
|
|
(PlayerBlackBoard b) =>
|
||
|
|
{
|
||
|
|
var move = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
|
||
|
|
if (move.sqrMagnitude < 0.001f) return (int)PlayerState.Idle;
|
||
|
|
b.Pos += move.normalized * 5f * Time.deltaTime;
|
||
|
|
if (Input.GetKeyDown(KeyCode.Space) && b.Grounded) return (int)PlayerState.Jump;
|
||
|
|
return -1;
|
||
|
|
},
|
||
|
|
(PlayerBlackBoard b) => { }
|
||
|
|
);
|
||
|
|
|
||
|
|
Funcs[(int)PlayerState.Jump] = StateFunc<PlayerBlackBoard>.Make(
|
||
|
|
(PlayerBlackBoard b) =>
|
||
|
|
{
|
||
|
|
b.Grounded = false;
|
||
|
|
b.Vel = Vector3.up * 5f;
|
||
|
|
},
|
||
|
|
(PlayerBlackBoard b) =>
|
||
|
|
{
|
||
|
|
b.Vel += Physics.gravity * Time.deltaTime;
|
||
|
|
b.Pos += b.Vel * Time.deltaTime;
|
||
|
|
if (b.Pos.y <= 0f)
|
||
|
|
{
|
||
|
|
b.Pos = new Vector3(b.Pos.x, 0f, b.Pos.z);
|
||
|
|
b.Grounded = true;
|
||
|
|
return (int)PlayerState.Idle;
|
||
|
|
}
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
},
|
||
|
|
(PlayerBlackBoard b) => { }
|
||
|
|
);
|
||
|
|
|
||
|
|
Trans = new Transition<PlayerBlackBoard>[]
|
||
|
|
{
|
||
|
|
new Transition<PlayerBlackBoard>((int)PlayerState.Idle, (int)PlayerState.Dead, (PlayerBlackBoard b) => b.Hp <= 0f, priority: -10),
|
||
|
|
new Transition<PlayerBlackBoard>((int)PlayerState.Move, (int)PlayerState.Dead, (PlayerBlackBoard b) => b.Hp <= 0f, priority: -10),
|
||
|
|
new Transition<PlayerBlackBoard>((int)PlayerState.Jump, (int)PlayerState.Dead, (PlayerBlackBoard b) => b.Hp <= 0f, priority: -10),
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
public static FsmConfig<PlayerBlackBoard> CreateConfig(PlayerState defaultState = PlayerState.Idle)
|
||
|
|
{
|
||
|
|
return new FsmConfig<PlayerBlackBoard>(Funcs, Trans, (int)defaultState);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public class PlayerController : MonoBehaviour
|
||
|
|
{
|
||
|
|
private Fsm<PlayerBlackBoard> _fsm;
|
||
|
|
|
||
|
|
void Awake()
|
||
|
|
{
|
||
|
|
// Use pooled blackboard and manager-created FSM (auto debug bind in Editor)
|
||
|
|
var cfg = PlayerFSM.CreateConfig();
|
||
|
|
_fsm = GameApp.Fsm.Create(cfg, owner: this, stateNameGetter: i => ((PlayerState)i).ToString());
|
||
|
|
_fsm.Blackboard.Clear(); // ensure default values on start
|
||
|
|
}
|
||
|
|
|
||
|
|
void Update()
|
||
|
|
{
|
||
|
|
if (Input.GetKeyDown(KeyCode.H))
|
||
|
|
{
|
||
|
|
_fsm.Blackboard.Hp -= 50f;
|
||
|
|
Debug.Log("HP: " + _fsm.Blackboard.Hp);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (Input.GetKeyDown(KeyCode.P))
|
||
|
|
{
|
||
|
|
_fsm.Blackboard.Hp = 100f;
|
||
|
|
_fsm.Reset((int)PlayerState.Idle);
|
||
|
|
Debug.Log("Revived");
|
||
|
|
}
|
||
|
|
|
||
|
|
transform.position = _fsm.Blackboard.Pos;
|
||
|
|
}
|
||
|
|
|
||
|
|
void OnDestroy()
|
||
|
|
{
|
||
|
|
// Return both FSM and BB to their pools via manager helper
|
||
|
|
GameApp.Fsm.DestroyFsm(_fsm);
|
||
|
|
_fsm = null;
|
||
|
|
}
|
||
|
|
}
|