'BallMovement' 类型的对象已被销毁,但您仍在尝试访问它
The object of type 'BallMovement' has been destroyed but you are still trying to access it
我检查了所有 SO 但找不到有效的答案(或者至少我知道如何实施)。
我不久前才开始使用 Unity,我正在尝试制作 Pong 克隆。游戏在第一个 运行 上运行良好,但是当玩家获胜并切换到场景 2 时,您按下再次播放按钮并返回场景 1(游戏场景)我在尝试玩游戏时遇到此错误:
这是我针对有问题 class 的启动方法。
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 个小时,除此之外,我设法靠自己克服了所有障碍
您似乎删除/处理了 BallMovement
class。我认为这是因为您删除/处理了球,并且没有使用 BallMovement
class/ 脚本创建新球。
嗯,我认为你的错误可能在于这一行:
GameStateManager.PlayerScored += Start;
我猜测 GameStateManager
以某种方式在场景加载中幸存下来,无论是不会破坏的 GameObject 还是 ScriptableObject 或其他东西。
我认为正在发生的事情是您向 PlayerScored
事件添加了一个委托,然后当您更改场景时该事件没有被重置。当您第二次回到现场时,BallMovement
class 的 instance 已被删除,当该事件触发时,您会得到错误 The object of type 'BallMovement' has been destroyed but you are still trying to access it
.
我看到的另一种令人担忧的事情是,你有一个方法将自己添加到一个事件中 - 当你第一次 运行 Start
时,在 Unity Start
回调,您将自己添加到 PlayerScored
事件。
然后,当 PlayerScored
触发时,您将 Start
添加到 PlayerScored
事件 第二次 。然后第二次 PlayerScored
触发它触发 Start
两次,所以你添加它两次,第三个触发器现在有四个事件要调用。事件调用列表中允许重复,因此每次它在 PlayerScored
列表中时都会触发 Start
,并且每次调用它时都会再次添加。
解决这个问题的方法是将该功能移出开始,并在 GameObject 被销毁时从事件中删除委托。请考虑以下内容:
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;
}
// ...
我检查了所有 SO 但找不到有效的答案(或者至少我知道如何实施)。
我不久前才开始使用 Unity,我正在尝试制作 Pong 克隆。游戏在第一个 运行 上运行良好,但是当玩家获胜并切换到场景 2 时,您按下再次播放按钮并返回场景 1(游戏场景)我在尝试玩游戏时遇到此错误:
这是我针对有问题 class 的启动方法。
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 个小时,除此之外,我设法靠自己克服了所有障碍
您似乎删除/处理了 BallMovement
class。我认为这是因为您删除/处理了球,并且没有使用 BallMovement
class/ 脚本创建新球。
嗯,我认为你的错误可能在于这一行:
GameStateManager.PlayerScored += Start;
我猜测 GameStateManager
以某种方式在场景加载中幸存下来,无论是不会破坏的 GameObject 还是 ScriptableObject 或其他东西。
我认为正在发生的事情是您向 PlayerScored
事件添加了一个委托,然后当您更改场景时该事件没有被重置。当您第二次回到现场时,BallMovement
class 的 instance 已被删除,当该事件触发时,您会得到错误 The object of type 'BallMovement' has been destroyed but you are still trying to access it
.
我看到的另一种令人担忧的事情是,你有一个方法将自己添加到一个事件中 - 当你第一次 运行 Start
时,在 Unity Start
回调,您将自己添加到 PlayerScored
事件。
然后,当 PlayerScored
触发时,您将 Start
添加到 PlayerScored
事件 第二次 。然后第二次 PlayerScored
触发它触发 Start
两次,所以你添加它两次,第三个触发器现在有四个事件要调用。事件调用列表中允许重复,因此每次它在 PlayerScored
列表中时都会触发 Start
,并且每次调用它时都会再次添加。
解决这个问题的方法是将该功能移出开始,并在 GameObject 被销毁时从事件中删除委托。请考虑以下内容:
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;
}
// ...