Bug - Ball triggers Game Over, but never moves there - help

Need help please,

Had no issue with the previous lectures, but I’m getting a bug on this one… or I’m doing something wrong… and I don’t know how to fix it. I also went back to follow Rick’s steps and refactored my code to look more like his… but it’s still happening.

The issue is that, when I implemented the Ball following the Paddle - with the “position + offset” it’s nicely following the Paddle… for a couple seconds… after which it triggers the Game Over collider trigger… although the Ball never goes below the Paddle. So I can’t really figure our how it can trigger something it never touched. Please help.

I’m sending my scripts and screenshot in which you can see Ball, Trigger Collider, and Debug Message. I noticed this since it would keep sending me into the Game Over scene… that’s why it’s commented out currently with the Debug.Log messege added.

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

public class Paddle : MonoBehaviour
{
	[SerializeField]
	private float screenWidthInUnits = 11.7f;

    void Update()
    {
        UpdatePaddlePosition();
    }

	public void UpdatePaddlePosition() {
        float mousePositionInUnits = Input.mousePosition.x / Screen.width * screenWidthInUnits;
        Vector2 currentPosition = new Vector2(transform.position.x, transform.position.y);
		currentPosition.x = Mathf.Clamp(mousePositionInUnits, 0f, screenWidthInUnits);
        transform.position = currentPosition; 
    }
} 
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class LoseCollider : MonoBehaviour
{
	private void OnTriggerEnter2D(Collider2D collision) {
		Debug.Log("GameOver");
		Debug.Log(collision);
		//SceneManager.LoadScene("GameOver"); 
	}

}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BallBehaviour : MonoBehaviour
{
	[SerializeField] Paddle paddle1;
	private Vector2 paddleToBallVector;

	private void Start() {
		CalculateOffsetToPaddle();
	}

	private void Update() {
		FollowPaddle();
	}

	private void CalculateOffsetToPaddle() {
		paddleToBallVector = transform.position - paddle1.transform.position;
	}

	private void FollowPaddle() {
		Vector2 paddlePos = new Vector2(paddle1.transform.position.x, paddle1.transform.position.y);
		transform.position = paddlePos + paddleToBallVector;
	}
	  
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneLoader : MonoBehaviour
{
	public void LoadNextScene () {
		int sceneIndex = SceneManager.GetActiveScene().buildIndex;
		SceneManager.LoadScene(sceneIndex + 1);
	}

	public void LoadMenuScene() {
		SceneManager.LoadScene(0); 
	}

	public void QuitApplication() {
		Application.Quit();
	}
}
1 Like

…is it possible that this issue is a conflict between the script trying to control the position of the ball and the dynamic property of the rigidbody trying to make it fall / bounce?

This idea came to mind since… if I set the ball to be kinematic while it’s being moved with the paddle, the bug does not appear anymore.

Thanks,

…to fix this I did 2 things:

  1. Set my Ball Prefab default Rigidbody Body Type to Kinematic
  2. OnBallLaunch simply changed the type to Dynamic before giving it force
	private void LaunchOnMouseClick() {
		if (Input.GetMouseButtonDown(0)) {
			_hasBeenLaunched = true;
			GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Dynamic;
			GetComponent<Rigidbody2D>().velocity = new Vector2(_xPushForce, _yPushForce);
		}
	}

Hope this workaround is going to prevent phantom collisions.

Let me know what you think of my change.

Thanks

Hi nynox,

Does your solution work? If so, it’s fine. :slight_smile:


Unity’s physic engine is highly optimised meaning it checks the position of a collider occasionally only. You could try to set the Collision Detection mode of the ball’s Rigidbody2D to “Continuous”. In most cases, that fixes the problem.

In our particular case, the problem is that we manipulate the transform.position via code and override the calculated values of the physics engine. It is likely that the position of the ball does not match the position of the collider anymore.

A better solution would be to disable the physics simulation for the ball while manipulating the position via code.

void Start ()
{
  paddleToBallVector = transform.position - paddle1.transform.position;
  myAudioSource = GetComponent&lt;AudioSource&gt;();
  myRigidBody2D = GetComponent&lt;Rigidbody2D&gt;();
  myRigidBody2D.simulated = false; // <-------- add this
}
 
private void LaunchOnMouseClick()
{
  if (Input.GetMouseButtonDown(0))
  {
    hasStarted = true;
    myRigidBody2D.velocity = new Vector2(xPush, yPush);
    myRigidBody2D.simulated = true; // <-------- add this
  }
}

I hope that makes sense. :slight_smile:


See also:

1 Like

Hi Nina,

Did not have it happen again since I added Dynamic / Kinetic switch. But it’s nice to know there are more options… as well as always nice to learn how to do things with another approach.

Many thanks for your swift and educational answer. Much appreciated.

:smiley:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms