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

Unity中使用Input System调用父类方法并引用子类变量的问题

问题解决:Input System调用父类方法时子类变量未被识别

核心原因

你在子类PlayerController中重复定义了父类已有的public GameObject projectile变量,这会隐藏父类的同名成员。当调用父类的FireProjectile方法时,方法访问的是父类中未赋值的projectile,而非子类中已赋值的同名变量,因此触发UnassignedReferenceException。

解决方案1:移除子类重复变量(推荐)

直接使用父类继承的projectile变量,不要在子类中重新定义:

修改后的子类代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : CharacterController
{
    PlayerControl playerControl;

    // 移除重复定义的projectile变量
    // public GameObject projectile;

    void Start()
    {
        // 直接给继承自父类的projectile赋值
        projectile = base.mainManager.projectiles[0];

        playerControl = new PlayerControl();
        
        playerControl.Player.Enable();
        // 直接绑定继承的方法(无需base,this可省略)
        playerControl.Player.Fire.performed += FireProjectile;
    }
}

父类代码无需修改,此时FireProjectile方法会正确访问到子类赋值的projectile变量。

解决方案2:重写父类方法(适用于特殊需求)

如果确实需要子类维护独立的projectile变量,可重写父类的FireProjectile方法,在子类方法中使用自身变量:

父类代码(保持virtual)

public virtual void FireProjectile(InputAction.CallbackContext context)
{
   if (context.performed)
    {
        Instantiate(projectile);
    }
}

子类代码

using System.Collections;
using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : CharacterController
{
    PlayerControl playerControl;

    // 子类独立的projectile变量
    public GameObject projectile;

    void Start()
    {
        projectile = base.mainManager.projectiles[0];

        playerControl = new PlayerControl();
        
        playerControl.Player.Enable();
        // 绑定子类重写后的方法
        playerControl.Player.Fire.performed += FireProjectile;
    }

    // 重写父类方法
    public override void FireProjectile(InputAction.CallbackContext context)
    {
        if (context.performed)
        {
            // 使用子类自身的projectile
            Instantiate(projectile);
        }
    }
}

关于你之前尝试的错误解释

你尝试给FireProjectile添加参数并直接调用base.FireProjectile(projectile),这不符合Input System回调的委托要求:

  • Input System的performed事件需要的是Action<InputAction.CallbackContext>类型的委托,直接调用方法会返回void,无法转换为委托类型。
  • 如果需要传递额外参数,应该用lambda表达式包裹(不推荐,因为继承变量已足够):
// 父类方法修改为带参数
public virtual void FireProjectile(InputAction.CallbackContext context, GameObject tempProjectile)
{
   if (context.performed)
    {
        Instantiate(tempProjectile);
    }
}

// 子类绑定事件时用lambda传递参数
playerControl.Player.Fire.performed += context => base.FireProjectile(context, projectile);

内容的提问来源于stack exchange,提问作者jeremy.bartlett

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 16:57:43