I made a rigidbody character with the goal to have it "bounce" off of certain objects (basically deflect based on the angle of incidence and gravity). Someone on the forums gave me a small code to apply to the bounce object (a plane), which is as follows:
var player : Transform;
var bounceForce : float = 10;
function OnCollisionEnter(other : Collision)
player.rigidbody.AddRelativeForce(Vector3.up * 10, ForceMode.VelocityChange);
I noticed my character would be reflected only vertically, no matter what angle the object is. From some testing, I think the issue is that my character has rigidbody.FreezeRotation turned on, for obvious reasons.
Could anyone explain a way around this issue, either fixing the character end (rigidbody.FreezeRotation) or the bounce script? I have thought about using vector-based physics formulas to calculate the angle of reflection, velocity, etc. but at the moment I am not familiar enough to implement such a bounce script.
Why aren't you just leaving the physics to Unity instead of coding it yourself?
What do you mean? The rigidbody.FreezeRotation? Or just using a rigidbody for the character in general? The latter is because it works better with other things such as moving platforms and pushing objects.
The code you have says to thrust UP whenever you hit something. Where it says "Vector3.up" really means up. You could look at other.contacts.normal and thrust that way. But, easier to just add a physics material, set bouncy=1 and combine=max.
Any of it. Unity can do all the bouncing you need just fine, you don't need to implement bouncing manually, just set the collider physics materials correctly.
Answer by jesseoffy
Jun 29, 2011 at 12:46 AM
Edit 2: Solved with the kind help of [yakoma44]. Instead of moving the character using velocity and AddForce, I used MovePosition. So far, I haven't found any problems and the character doesn't seem to be doing any funky physics behaviors (fingers crossed). Here are the code changes sampled from my character script:
var velocity = rigidbody.velocity;
var velocityChange = (targetVelocity - velocity);
velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
velocityChange.y = 0;
rigidbody.MovePosition(rigidbody.position + targetVelocity * Time.deltaTime);
The actual bounce force is applied on the bouncing collider: var bounceForce : float = 10;
function OnCollisionEnter(other : Collision)
other.rigidbody.velocity = transform.up * bounceForce;
Nota bene: AddForce or AddRelativeForce also work in the OnCollisionEnter, though the above is the shortest to write out. : http://www.youtube.com/user/yakoma44[yakoma44]
whats the targetVelocity? its not defined as a variable
Answer by aldonaletto
Jun 22, 2011 at 02:43 AM
I tried a rigidbody with freezed rotation and collider material set to Bouncy. When falling on some rigidbody, it didn't bounce at all. If falling on a collider without rigidbody, however, it bounced so endlessly that I had to define a damping factor in its script:
var damping:float = 0.7;
rigidbody.velocity.y *= damping;
It worked fine - at least for the bouncing effect. Hope it can solve your problem ;)
EDITED: Applied damping only to the Y velocity component. This allows easy control of how much the player bounce in different objects by altering the damping factor.
NOTE: damping is actually an energy conservation factor - it ranges from 0 (total damping) to 1 (no damping at all).
Collision results depend on the settings of BOTH colliders. Check them.
Why freeze rotation? If it's just for a visual reason then you can do that by tracking a visual object to an invisible physical object.
By collider material, you mean physic material, correct? I have played around with the physic materials, but those don't give me the control over the physics that I desire - being able to alter the amount of force that certain objects push up on the character. I have a few different techniques to test with - if I find a solution, I'll post it.
Yes, I was talking about the physic material. I tried some combinations too, but the only one which made the character bounce like a crazy flea was Bouncy (character) + no rigidbody (platform). Other combinations gave results far away from what I expected. With the "damping" factor, I was able to control how much it bounced, but I have not tested other characteristics, like linear movement, collision with walls etc.
I also tried the brute force alternative, calculating it myself. I simply did this in the OnCollisionEnter event:
rigidbody.velocity = Vector3.Reflect(rigidbody.velocity,hit.contacts.normal);
which should emulate a real bouncing, but it also gave strange results - maybe due to interaction with the physics engine.
I admit it's late and I've spent hours staring at the screen trying to come up with other solutions (including returning to a CharacterController), and I think that somehow my controller stops the character from being able to "bounce" away from the object. It can only move vertically after it leaves the surface of the object. Edit: scripts removed.
Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.
The best place to ask and answer questions about development with Unity.
If you are a new user, check out our FAQ for more information.
If you are a moderator, see our Moderator Guidelines page.
We are making improvements to UA, see the list of changes.
For troubleshooting common problems with Unity 5.x Editor (including Win 10).
To help users post good questions and use the site effectively we have posted a user guide. Please check it out.
Answers and Comments
5 People are following this question.
Bounce Balls within Borders
How to make objects non-penetrable, inelastic
Rigidbody bounce to a place without physics material.