【问题标题】:Assignment referring to wrong object指代错误对象的赋值
【发布时间】:2026-02-10 14:35:01
【问题描述】:

我正在使用 制作游戏并尝试使用控制器管理器来管理用户输入。

我创建了一个类ControllerManager 来执行此操作。因为我试图从 2 个控制器获取输入,所以我创建了三个 ControllerManager 实例:controllerManagercontroller1Managercontroller2Manager

现在,在我的播放器对象中,我有一个局部变量 localManager,我需要将其分配给 controller1Managercontroller2Manager,具体取决于它是哪个播放器。

我一直在尝试这样分配它:

this.localManager = Controller1Manager;

这导致localManager 变量被设置为controllerManager

那么有人知道我做错了吗?除了可能与指针/引用/单例有关之外,我不知道,但我已经检查了组件列表并且每个单独的管理器都在其中。

编辑: 根据要求,这里是构造函数、类创建以及我尝试更改值的位置

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using GDApp;

namespace GDLibrary
{
public class ControllerManager : GameComponent, IService
{
    public GamePadState newState, oldState;
    public PlayerIndex player;

    public ControllerManager(Main game, PlayerIndex index)
        : base(game)
    {
        this.player = index;
    }
    public override void Update(GameTime gameTime)
    {
        oldState = newState;
        newState = GamePad.GetState(player);
        base.Update(gameTime);
    }
    public bool IsFirstButtonPress(Buttons button)
    {
        if (oldState.IsButtonUp(button) && newState.IsButtonDown(button))
            return true;

        return false;
    }

    public bool IsButtonDown(Buttons button)
    {
        return newState.IsButtonDown(button);
    }

    public bool IsButtonUp(Buttons button)
    {
        return newState.IsButtonUp(button);
    }

    #region Thumbsticks

    //Right

    //Magnitude of right stick in right direction
    public float RightStickRight()
    {
        if (newState.ThumbSticks.Right.X <= 0)
            return 0;
        else
            return newState.ThumbSticks.Right.X;
    }

    //Magnitude of right stick in left direction
    public float RightStickLeft()
    {
        if (newState.ThumbSticks.Right.X >= 0)
            return 0;
        else
            return System.Math.Abs(newState.ThumbSticks.Right.X);
    }

    //Magnitude of right stick in upward direction
    public float RightStickUp()
    {
        if (newState.ThumbSticks.Right.Y >= 0)
            return 0;
        else
            return System.Math.Abs(newState.ThumbSticks.Right.Y);
    }

    //Magnitude or right stick in downward direction
    public float RightStickDown()
    {
        if (newState.ThumbSticks.Right.Y <= 0)
            return 0;
        else
            return newState.ThumbSticks.Right.Y;
    }


    //Left

    //Magnitude of left stick in right direction
    public float LeftStickRight()
    {
        if (newState.ThumbSticks.Left.X <= 0)
            return 0;
        else
            return newState.ThumbSticks.Left.X;
    }

    //Magnitude of left stick in left direction
    public float LeftStickLeft()
    {
        if (newState.ThumbSticks.Left.X >= 0)
            return 0;
        else
            return System.Math.Abs(newState.ThumbSticks.Left.X);
    }

    //Magnitude of left stick in upward direction
    public float LeftStickUp()
    {
        if (newState.ThumbSticks.Left.Y >= 0)
            return 0;
        else
            return System.Math.Abs(newState.ThumbSticks.Left.Y);
    }

    //Magnitude or right stick in downward direction
    public float LeftStickDown()
    {
        if (newState.ThumbSticks.Left.Y <= 0)
            return 0;
        else
            return newState.ThumbSticks.Left.Y;
    }

    #endregion

    public bool RightStickCentered()
    {
        if (newState.ThumbSticks.Right.X.Equals(0) && newState.ThumbSticks.Right.Y.Equals(0))
        {
            return true;
        }
        return false;
    }

    public bool LeftStickCentered()
    {
        if (newState.ThumbSticks.Left.X.Equals(0) && newState.ThumbSticks.Left.Y.Equals(0))
        {
            return true;
        }
        return false;
    }

    public Vector2 RightStick()
    {
        return this.newState.ThumbSticks.Right;
    }

    public Vector2 LeftStick()
    {
        return this.newState.ThumbSticks.Left;
    }

    public bool LeftStickMoved()
    {
        if (!oldState.ThumbSticks.Left.X.Equals(newState.ThumbSticks.Left.X) || !oldState.ThumbSticks.Left.Y.Equals(newState.ThumbSticks.Left.Y))
        {
            return true;
        }

        return false;
    }

    public bool RightStickMoved()
    {
        if (!oldState.ThumbSticks.Right.X.Equals(newState.ThumbSticks.Right.X) || !oldState.ThumbSticks.Right.Y.Equals(newState.ThumbSticks.Right.Y))
        {
            return true;
        }

        return false;
    }
}
}

创建经理:

this.controller1Manager = new ControllerManager(this, PlayerIndex.One);
Components.Add(controller1Manager);
IServiceContainer.AddService(typeof(ControllerManager), controller1Manager);

this.controller2Manager = new ControllerManager(this, PlayerIndex.Two);
Components.Add(controller2Manager);
IServiceContainer.AddService(typeof(ControllerManager), controller2Manager);

改变值:

if (this.index.Equals(PlayerIndex.One))
    {
        this.localManager = Controller1Manager;
    }
else if (this.index.Equals(PlayerIndex.Two))
    {
        this.localManager = Controller2Manager;
        Controller2Manager.player = index;
    }

【问题讨论】:

  • 你确定 Controller1Manager 之前没有分配给 ControllerManager 吗?
  • 您确定您发布的代码已被处理吗?如果您发布整个代码会更好。
  • 它似乎一被实例化就被分配给了ControllerManager。使用以下内容: this.controller1Manager = new ControllerManager(this, PlayerIndex.One); System.Console.WriteLine("我已被分配" + controller1Manager);打印 GDLibrary.ControllerManager
  • 我相信是的,我一直在使用 Console.WriteLine 来测试值,这样我就可以看到它何时从 null 分配给了错误的值。 @LPs 你想看整个类还是只看构造函数?
  • 当您写出controller1Manager 时,您在评论中的WriteLine 只是写出变量的类型。 ControllerManager 类是否覆盖 ToString 方法?你能写出控制器管理器的某些特定属性的值来确认哪些对象是哪些吗?例如,您能写出类似Console.WriteLine(controller1Manager.ID) 的内容吗(假设 ID 是有效属性)?

标签: monogame c# monogame assign


【解决方案1】:

这个问题已经通过将 ControllerManager 传递给 PlayerObject 来代替 PlayerIndex 得到解决。所有 controllerManager 的变量似乎都立即更改的原因是它们包含在上面编辑中显示的 IServiceContainer 中。 IServiceContainer 仅存储给定类型的一个实例(它是字典),因此仅保存最近添加的内容。

【讨论】: