我检查了所有内容,但找不到有效的答案(或者至少我了解如何实现)。
我不久前刚刚开始使用 Unity,正在尝试制作 Pong 克隆。游戏在第一次运行时运行良好,但是当玩家获胜并切换到场景 2 时,然后您按下“再次玩”按钮并返回到场景 1(游戏场景),我在尝试玩游戏时收到此错误:
这是我针对有问题的类的 Start 方法。
public class BallMovement : MonoBehaviour
{
Rigidbody2D ball;
Vector2 vel;
// Start is called before the first frame update
void Start()
{
float posY = Random.Range(-150, 150);
ball = GameObject.FindGameObjectWithTag("Ball").GetComponent<Rigidbody2D>();
transform.localPosition = new Vector2(-19, posY);
vel.x = 250;
vel.y = -150;
ball.velocity = vel;
GameStateManager.PlayerScored += Start;
}
...
很抱歉问了这样一个愚蠢/模糊的问题,但我被严重卡住了,我已经在这个 pong 克隆上工作了 8 个小时,除了这个之外,我还设法自己克服了所有障碍
最佳答案
嗯,我认为你的错误可能就在这一行:
GameStateManager.PlayerScored += Start;
我猜测 GameStateManager
会以某种方式在场景加载中幸存下来,无论是不会破坏的 GameObject 还是 ScriptableObject 或其他东西。
我认为发生的情况是,您将委托(delegate)添加到您的 PlayerScored
事件中,然后当您更改场景时该事件不会重置。当您第二次返回场景时,BallMovement
类的实例已被删除,当该事件触发时,您会收到错误 The object of类型“BallMovement”已被销毁,但您仍在尝试访问它
。
我看到的另一种令人担忧的事情是,您有一个方法将自身添加到事件中 - 当您第一次在 Unity Start
上运行 Start
时code> 回调,您将自己添加到 PlayerScored
事件中。
然后,当 PlayerScored
触发时,您将 Start
添加到 PlayerScored
事件第二次。然后,第二次 PlayerScored
触发时,它会触发 Start
两次,因此您将其添加两次,第三个触发器现在有四个事件要调用。事件调用列表中允许重复,因此每次它出现在 PlayerScored
列表中时,您都会触发 Start
,并且每次调用它时,它都会再次添加自身。
解决这个问题的方法是将该功能移出启动位置,并在游戏对象被销毁时从事件中删除委托(delegate)。请考虑以下问题:
public class BallMovement : MonoBehaviour
{
Rigidbody2D ball;
Vector2 vel;
// Start is called before the first frame update
void Start()
{
GameStateManager.PlayerScored += OnPlayerScored;
OnPlayerScored(); // Fire this once on Start to get everything setup!
}
void OnPlayerScored()
{
float posY = Random.Range(-150, 150);
ball = GameObject.FindGameObjectWithTag("Ball").GetComponent<Rigidbody2D>();
transform.localPosition = new Vector2(-19, posY);
vel.x = 250;
vel.y = -150;
ball.velocity = vel;
}
void OnDestroy()
{
GameStateManager.PlayerScored -= OnPlayerScored;
}
// ...
关于c# - 类型 'BallMovement'的对象已被销毁,但您仍在尝试访问它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72323533/