objects randomly pass through colliders

Hello folks,

I have an issue which seems to be gameobjects (small spheres) passing through box colliders at random times/places.

I’ve attached a screen shot of my scene for reference: A game board not un-like a picture frame with spheres bouncing around inside the inset of the the frame.

The balls are restricted on the z plane. I don’t use anything besides Physics to allow movement with the exception of a velocity limiter. (screen shot of settings also attached.).

While playing the game the balls noticeably fly off the screen ignoring the box colliders which I’ve stretched out to ensure there is enough collider there and they can’t pass “through”.

any suggestions are very appreciated!

Thanks.

playable demo where you can see the effects. The top right side seems worse then the rest. Almost like there are holes in the collider. http://www.bordereastcreative.com/reactions/

what powers the balls? (makes them move)

This is what I’m currently using.

private Vector3 speed = new Vector3(Random.Range(-15,35),Random.Range(-15,35),0);
rigidbody.velocity = speed;

I had previously used rigidbody.AddForce() and can’t remember why I switched now.

Of course this code, if applied every frame, will force it through walls.

Example: the ball hits the wall. the resulting collision changes rigidbody.velocity to point away from the wall. But then the next frame, you’re setting it to random again, and it will pass through the wall. Random numbers will be the same each time you run it, so it will happen as though the holes are in the same place.

Do not set rigidbody.velocity directly for this sort of simulation, instead, use addforce to the velocity.

And is this code in fixedupdate?

Hippocoder,

This code is in the start() method of each ball instance.

The only code I have running in the update is a check to see if balls are outside the walls where I destroy the objects. Once force is added, no “more” force is being added. The only other influence is a Velocity Limiter script I found in the unity forums or wiki.

Looking at you demo the balls that vanish appear back again, are you destroying or moving them?
If thats in the start(() it shouldnt cause a problem but would be better to use addforce.
Is there any other code in the ball script?

@Bug5532 yeah, I was toying with the idea of reversing direction once they passed the frame border… :slight_smile:

Here is the whole class file

using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {

	public AudioClip hit;
	private Vector3 speed = new Vector3(Random.Range(-15,35),Random.Range(-15,35),0);
	// Use this for initialization
	private bool playclip = false;
	private bool destroyAfterSound = false;
	void Start () {
		rigidbody.velocity = speed;
		GameScript.actualNumBalls += 1;
		
	}
	
	// Update is called once per frame
	void Update () {
		
		if (rigidbody.position.y > GameScript.frameTopY) {
			if((GameScript.frameTopY - rigidbody.position.y) > 20 )
				Destroy(gameObject);

		} else if (rigidbody.position.y < GameScript.frameBottomY){
			if((rigidbody.position.y - GameScript.frameBottomY ) < -20 )
				Destroy(gameObject);
		}
		
		if (rigidbody.position.x < GameScript.frameLeftX) {
			if((rigidbody.position.x - GameScript.frameLeftX ) < -20 )
				Destroy(gameObject);

		} else if (rigidbody.position.x > GameScript.frameRightX){
			if((GameScript.frameRightX - rigidbody.position.x) > 20 )
				Destroy(gameObject);
			debugPosition(rigidbody.position);
			Vector3 speed = rigidbody.velocity;
			speed.x *= -1;
			transform.Translate(speed);
		}
		
		if(destroyAfterSound  !audio.isPlaying)
			Destroy(gameObject);
	}
	
	void debugPosition(Vector3 pos){
		Debug.Log("==========BALL==OUT====================");
		Debug.Log("Ball X = " + pos.x + "    Ball Y = " + pos.y);
		Debug.Log("");
		Debug.Log(" Frame Corners T,R,B,L = " + GameScript.frameTopY + "," + GameScript.frameRightX + "," + GameScript.frameBottomY + "," + GameScript.frameLeftX);
		Debug.Log("=======================================");
	}
	
	 void OnCollisionEnter(Collision collision) {
		//Debug.Log(collision.gameObject.tag);
        if(collision.gameObject.tag=="Player"  !destroyAfterSound){
			audio.clip = hit;
			audio.loop = false;
			audio.Play();
			Vector3 v = transform.position;
			var player = Instantiate(FrameHandler.obj, v, Quaternion.identity);
			GameScript.currentHits++;	// increase hit counter
			//GameScript.score += GameScript.hitWorth; // increase score
		//	Destroy(gameObject);
			destroyAfterSound = true;
			renderer.enabled = false;
		}
    }
}

Not really sure whats going wrong, I would try creating a tempball script with just the start() bits. Also you can freeze rotation in the x and y axis as well. doubt thats the problem though.
are the balls being created in the correct place on the z-axis?

I have a static variable for the Z value which I use when instantiating. I’ll try the tempball script and use AddForce.

Looks like you’re performing physics in update. As above, I said you can only perform physics in FixedUpdate() - thats just how physics work. Let me know if it improves the behaviour.

In addition to this, once it’s running pause unity and select the object with the colliders in it. Fly around and see if the colliders are actually matching your geometry. Make sure gizmos is turned on in the game view before switching to scene view (the colliders will show up as green) - then fly around and check they’re high enough and so on. You can also pause the behaviour just before a bad event and step through frame by frame.

  1. place code in fixedupdate. it’s physics code and its only stable in fixedupdate.

  2. raise damping so you cap their maximum speed, so they don’t accelerate after collisions to a briefly huge amount of energy (they can do and this will break physics).

Thanks guys, I appreciate the help.

Slowing things down seems to stop the collider issue.

The FixedUpdate() tip seems to have fixed another issue as well, where my CPU usage was pretty high for a rather simple game.

Cheers!

There’s no reason you can’t make the walls a lot thicker if using box colliders. The only way physics can break is if it steps past the wall in one frame. Continous option prevents that if they have to be thin.