Newbie to Unity, physics issue (solved)

Ok, I don’t fully know where all Unity’s settings are, but here is my problem:

I have a game with a ball that collides with the floor(on collision, it sets a value to a positive value, and moves based on value*DeltaTime).

On my fast PC, it collides fine, but on the slower PC, I am getting errors where the ball will suddenly fall through the floor preriodically. There is also a major hang on the graphical framerate when the ball hits the floor. In other words, it’s as if the OnCollisionEnter function isn’t catching the collisions properly, or is proving to be too much for the PC to process.

The odd thing is that my Processor actually clocks much slower then the other PC. The only real difference is that the ‘slower’ PC has only a Nvidia 5200 while I have a Nivida 8600.

I’m guessing there is a setting somewhere to give priority to certain objects, or somehow tell the program that my ball physics are more important then rendering it to the screen, or otherwise fix this performance problem. However, being new to Unity, I don’t know what all the settings do. It’s hard to look stuff up in the manual when I don’t know what I am looking for.

Any advice or settings you know of that might make this work better on lower end PCs?

Well, if the ball is moving fast when it goes through the floor, that actually tends to happen pretty often. It’s moving fast enough that the colliders skip over each other when the frame updates and no collision registers. In that case, check this script out, it works pretty well. http://www.unifycommunity.com/wiki/index.php?title=DontGoThroughThings

Another thought… is the floor a flat plane? If so, you will get better results using a thin box collider rather than the default mesh collider for the floor. If it’s not a flat plane, you might be able to improve things if you can add a bottom side to the mesh so that it encloses a volume completely.

The collision is between a ball (2.76 unity units according to the import transform scale) falling at a rate of (when reaching the bottom of the bounce) 40*DeltaTime. The “floor” is built out of a bunch of 2.54 by x by x cubes(width and depth vary to allow different floor shapes to be built from the cubes). So, the ball is basically colliding with a 2.54 thick floor, nearly as thick as the ball itself. I don’t know why it would not be able to collide, but somewhere on slower PCs it’s losing the collision.

On that script you posted, do I add it into my own script functions, or do I simply make an additional script and attach it? I’m no expert on scripting, nor a programmer, so it’s hard for me to wrap my mind around all these functions and what they look like as objects bouncing around the program. :sweat_smile:

Also, which function does my code go in? The manual says to put “game logic” into Update() and “physics” into FixedUpdate(), but doesn’t fully define what is considered “game logic” or “physics logic”.

Currently I have my gravity subtraction(just altering the variable for gravity, not actually moving anything) in Update(). I have my actual physical movement(based on variables set by Update) taking place in FixedUpdate(). And I have a seperate function OnCollisionEnter() to set the ball speed variable to 40 when fired. Is this the way the code is supposed to be divided into “game logic” and “physics logic”? I’m wondering if the function OnCollisionEnter is supposed to be placed in the FixedUpdate() function, because it needs to be run with physics, but the manual examples seem to imply otherwise.

Tried adding that script as a seperate component, both before and after the main ball physics script I wrote. It made no difference with the problem I get if Fixed Timestep is set greater then 0.02. (I’m using fixed timestep to test ‘dropping physics loops’, since setting it higher then 0.02 gives me the same results I get when the exe is run on the slower computer. I don’t have full access to the other computer all day to test proper, as it’s my sisters computer and she uses it for other things.)

I may simply be using the script wrong, or it might need to be added inside my own code. Can someone explain how you all properly setup that script in your own projects to get the “better collision” result? I’m not seeing any difference when I use it.

After pouring over the manual all day, I think what I need to do is a raytrace, but I’ve never dealt with coding anything like that before. So I have no clue how to apply what the manual is telling me to the situation(needing to raytrace estimate the floor collisions).

I also don’t know if the raytrace will collide with things that don’t have colliders. I currently have a ball graphical object that follows my invisible “ball”(without mesh collider, but with ridged body for positioning and rotation.) The purpose is to be able to swap the graphical object or rotate it without messing up the “physics” I have the other ball tracing. Since I don’t know what that code you linked to does, I don’t know if that is messing up the code from working properly.

Can you post the script you are using to control the ball?

Sure.

//Bouncy Fun Ball Main Ball Logic Script
//By Gawain Doell for Smiley Games - Monday, March 01, 2010
//
//To be attached to the main virtual Ball object.

//global values
var ballSize = 1.0;
var footBounce = 1;
var Bounce = 4;
var bigBounce = 3;

var ballMode = 1;
var ballPosition : Transform;

var ballZspeed = 40;
var ballZgrav = 1;

function Update () {
//physics code goes here

//gravity calculation
ballZspeed = ballZspeed - ballZgrav;
}

function FixedUpdate () {
//set x and y to BallControlPoint postion
var BallControlPoint = GameObject.Find("BallControlPoint");
var x = BallControlPoint.transform.position.x;
var z = BallControlPoint.transform.position.z;

transform.position.x = x;
transform.position.z = z;
transform.Translate(0,0,ballZspeed*Time.deltaTime);
}

function OnCollisionEnter() {
ballZspeed = 40;
Debug.Log("collision detected");
}

That code is attached to the main ball, the ‘virtual ball’ the real graphical ball follows.

The physical ball just has a script to position itself at this object(just a constant transform.position=position of physics ball).

There is also a BallControlPoint object, just a blank transform point in space, with this code:

//Ball Control Point Script
//By Gawain Doell for Smiley Games
//Tuesday, March 02, 2010

//To be attached to the Ball Control Point
//Ball should follow this object, camera is parented to it.

var movespeed = 1.0;

function Update () {
	var x = Input.GetAxis("Horizontal") * Time.deltaTime * movespeed;
	var z = Input.GetAxis("Vertical") * Time.deltaTime * movespeed;
	transform.Translate(x, 0, z);
}

All it really does is move the BallControlPoint around on the x and z axis as the player moves around. Eventually, it would also check for wall collisions to keep from moving into stuff. But first I need the floor collision to work properly.

The only objects with colliders are the geometry of the level, and the Virtual Ball object, so that all the graphical ball objects don’t cause collisions when positioned at the virtual ball.

Hmm, does anyone have a good, basic tutorial or example how to get around Unity dropping Physics Frames? I can’t seem to wrap my mind around how that code you linked to is supposed to help. Just dropping it into the engine and attaching it to an object doesn’t improve performance or make it behave better at all. I probably just don’t know how to use it. :sweat_smile:

Anyway, my ball bounces on my PC fine, and still falls through the floor when any physics frames are skipped on lower computers.

For now, I’m just moving on to add in other things, since I have no clue how to fix the problem. But I will need a better way for this game to work if I plan on selling it later, or my target audience(casual gamers) is going to have a lot of frustration. :frowning:

I could also use a tutorial on checking for collisions inside the movement code. I need to basically seperate the X, Y, and Z movement of my objects, becuase behavior is different for all the directions.

X and Y require simply undoing the X or Y movement(without touching the other direction), while Z needs to set the physics to bounce upwards at a steady rate determined by the value of ballZBounce.

Currently, all I know how to do is use OnEnterCollision() to make the ball bounce upwards. I don’t know how to check for the direction of a collision, or what the engine will do when two walls(say, a wall and a floor) are hit. Any tutorials on this subject?

The documentation seems to assume I know how all these vector and raytrace stuff work, since it’s only examples are a debug trace and then a really complicated looking grenade effect. The latter isn’t even explained very well for those new to 3d maths. :?

You don’t generally get correct results if you use transform.Translate to move a rigidbody object. You should add forces to the rigidbody (see the AddForce function) to move it in a way the physics engine can track easily.

The problem I had with that was when I used the default physics, I couldn’t seperate the collisions for the 3 axis movement I need.

I need the ball to be controllable on the XZ plain like an action hero from a 3rd person adventure game, but bounce up and down. Furthermore, collisions with the floor(and ONLY the floor) need to “reset” it’s bounce so that it is always getting the same consistant height.

I just don’t see how the default physics will help make this movement, because the default physics, are, well, physics. I don’t need realistic collisions or accurate wall bounces in all three axis, I need a more arcadelike control over the ball’s movement. The only tutorial I saw in the manual for using the physics engine and ridgedbody system was for things that actually would behave like real life objects. In other words, like I said before, I need full control over the 3 axis, with SEPERATE collisions on all three movement events.

Is there a good tutorial that would cover how to build a custom movement from the ground up? In other words, one axis at a time, without any generalization of “collides with something in wherever we are moving” involved? I just can’t wrap my head around how to use the physics and ridgedbody system to “lock” movements to just one axis per code logic, especally when I apparently have to run all my collision code in a OnEnterCollision() function that only fires once every physics frame, not in between each movement I do.

I used to use MultiMediaFusion, where I could have “events” like follows:

-Move the object down.
-Test for a collision, if true, move it back up.

That would allow me to make several of these “code” setups for all the different directions. As such, I never got how I would do such code if I can only use one single “yes a collision happened this frame” loop.

You could try using the CharacterController component on the ball. This registers collisions with other objects, but does not have realistic physical motion. However, this means that you have to handle gravity, bouncing, etc, yourself.

Ooh, that looks like it might be just what I need, especally with the collisions check for above, below, and sides already built into the object’s flags. I’ll give it a whirl. Thanks!

I do think Unity’s introduction documentation could use a bit more explaining different methods of moving stuff around and such. Currently after following the “beginner tutorial”, the “scripting tutorial”, and reading the introductions, I thought the only way stuff could move is with a ridgedbody attachment. But I guess that’s why I should take some time to read the whole manual cover to cover.

Is there a printable version of the scripting and components manual anywhere? I couldn’t find one in my quick search through the online documentation.

Indeed, that object works like a charm. No more messy physics interfering with the ball movement, or balls falling through the floor randomly. I just need to rewrite the collision codes, and it should be all set. And simpler too! :slight_smile:

I think I understand how this 3d stuff works now. :smile: It appears that I just add up my “seperate” movement vectors to get a single direction to push the ball in. Then I use If statements to check all possible collisions(so walls, floors, spikes, ect.)

It’s very different from the single “one at a time” event system used in Multimedia Fusion, but it also seems much more effective, since the collisions don’t have to be checked for every possible axis movement of the object, and all my collision code is in one place. 8)

Thanks for all your help!

In the Documentation folder (in the folder along with the Unity application), there is a file called printable.html - this has the user manual contents all in one long page.

You didn’t say whether you were using mesh or box colliders for your imported models. Box colliders are what you want, and you want to make them rather thick.

Thick enough along your Y-axis that there’s no way that the object can move past it in a single iteration of the physics engine. If your object is moving at 40 units a second, that’s around 90mph if modeled to real world scales. It’s not beyond believe to imagine such an object moving faster than 1-2 units in a frame on a slow machine.

Try doubling or even tripling the thickness of your box collider in the y direction and it should make a big difference. The colliders aren’t rendered so don’t be shy. Make them thicker than you -think- you need.

There’s also an issue you have when importing 3d models into Unity. When you go about attaching a primitive collider to it, the position, rotation or even the size can be totally off kilter.

You can see this visually in the inspector. So verify that your box colliders are as thick as you think they are and in the right place. If they’re not then fix them inside your 3d app by baking/freezing the rotation, position and pivot points.

Another step tweaking things for high velocities is increasing the physics rate. Running it twice as fast means the object is less likely to miss the box collider. That also will impact how much you can do visually on the slow machines you mentioned.

The last thing I would mention is that PhysX seems to have issues with tiny scales. When you start going below 1 Unity unit such as a primitive sphere scaled down to .039 to act as a marble in real world dimensions, colliders start missing seemingly randomly.

At those scales I can drop the marble on a table and it will sometimes go right through. Speedy movement exacerbates the problem. Here’s what I generally do with physics.

Take the smallest object in your game.

If it’s a one inch ball like the physics controlled marble, I’ll define that as 1 Unity unit and then scale everything up around that. So a one square meter play-area inside unity would then be modeled as 39.3 meters square inside modo.

I then scale up gravity accordingly. That would be -385.53 in the Y direction in the above case.

PhysX just seem to work so much better when you define 1 Unity unit as the lower limit on rigidbody size. I can’t quite claim to to fully understand exactly why. It’s just my experience.