You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TPS原型开发中StateMachine相关空引用异常问题求助

TPS原型开发中StateMachine相关空引用异常问题求助

嘿,我来帮你梳理下这两个空引用异常的问题,咱们一步步拆解排查:

第一个异常(IdleState.EnterState 第10行)

这个异常是在IdleState.EnterState里给_stateMachine.ReusableData.MovementSpeedModifier赋值时触发的,核心原因是**_stateMachine.ReusableData没有被初始化,是空对象**。

你用到的PlayerMovementStateMachine类(虽未贴出代码,但从上下文能推断它继承自StateMachine),里面的ReusableData字段需要在构造函数里实例化。你可以这样修改它的构造逻辑:

public class PlayerMovementStateMachine : StateMachine
{
    public PlayerStateReusableData ReusableData { get; private set; }
    public Player Player { get; private set; }
    public IdleState IdleState { get; private set; }
    public RunState RunState { get; private set; } // 后续切换的RunState也需提前初始化

    public PlayerMovementStateMachine(Player player)
    {
        Player = player;
        ReusableData = new PlayerStateReusableData(); // 关键:实例化ReusableData
        IdleState = new IdleState(this);
        RunState = new RunState(this); // 避免切换到RunState时再次触发空引用
    }
}

第二个异常(PlayerMovementState.GetMovementSpeed 第52行)

这个异常是在GetMovementSpeed里访问_movementData.BaseSpeed时触发的,说明**_movementData从未被赋值,是空对象**。

看PlayerMovementState的构造函数,你只接收了stateMachine参数,但没给_movementData赋值。可以通过stateMachine传递配置数据来解决:

// 先给PlayerMovementStateMachine添加GroundedData的引用
public class PlayerMovementStateMachine : StateMachine
{
    public PlayerGroundedData GroundedData { get; private set; }
    // ... 其他已有字段

    public PlayerMovementStateMachine(Player player)
    {
        // ... 其他初始化代码
        GroundedData = player.GroundedData; // 假设Player类中持有这个配置数据(比如挂载ScriptableObject)
    }
}

// 修改PlayerMovementState的构造函数,赋值_movementData
public class PlayerMovementState : PlayerBase
{
    protected PlayerMovementStateMachine _stateMachine;
    protected PlayerGroundedData _movementData;

    public PlayerMovementState(PlayerMovementStateMachine stateMachine)
    {
        _stateMachine = stateMachine;
        _movementData = stateMachine.GroundedData; // 关键:给_movementData赋值
    }
    // ... 其他已有代码
}

额外需要注意的细节

  1. Player类的Input字段未初始化:Player里的Input只定义了getter,但在Awake中没有实例化,后续ReadMovementInput访问_stateMachine.Player.Input会触发新的空引用,记得补充:
private void Awake()
{
    // ... 其他代码
    Input = GetComponent<PlayerInput>();
}
  1. GameObject.FindGameObjectWithTag的空值风险:Player的Awake里用标签查找物体,如果场景中没有对应标签的对象,也会触发空引用,建议加判断:
PlayerBody = GameObject.FindGameObjectWithTag(Tags.PlayerBody)?.GetComponent<Transform>();
if (PlayerBody == null)
{
    Debug.LogError("找不到标签为PlayerBody的物体!");
}
GroundPosition = GameObject.FindGameObjectWithTag(Tags.GroundCheck)?.GetComponent<Transform>();
if (GroundPosition == null)
{
    Debug.LogError("找不到标签为GroundCheck的物体!");
}

按这些点修改后,应该就能解决你遇到的两个空引用问题啦!

备注:内容来源于stack exchange,提问作者ultramax4528

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 15:18:01