AlicizaX/Client/Assets/PlayerController.cs

143 lines
4.2 KiB
C#
Raw Normal View History

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;
}
}