1
votes

I'm having trouble with physics in unity 3d. I'm wanting my ball to bounce off of walls and go another direction. When the ball hits the wall it just bounces straight back. I have tried changing the direction to be orthogonal to the direction it hits the wall but it doesn't change direction. Due to this, the ball just keeps hitting the wall and bouncing straight back.

Secondly, sometimes the ball goes through the wall. The walls have box colliders while the ball has a sphere collider. They all have continuous dynamic as the collision detection mode.

3
How are you 'moving' the ball? What kind of physics material does the ball use?Tony Abrams
I'm moving it using AddForce. It is a sphere, rigidbody with bouncy material.Chris McKnight
Check that the colliders match the geo? It's been awhile but I remember when you select the rigidbody I think, it brings up the UI gizmo ( bounding box) which you resize. Perhaps you accidentally resized it different.RJ Thompson

3 Answers

1
votes

Here's a link to a similar thread:

http://forum.unity3d.com/threads/22063-I-shot-an-arrow-up-in-the-air...?highlight=shooting+arrow

Personally, I would code the rotation using LookAt as GargarathSunman suggests in this link, but if you want to do it with physics, you'll probably need to build the javelin in at least a couple of parts, as the others suggest in the link, and add different drag and angular drag values to each part,perhaps density as well. If you threw a javelin in a vacuum, it would never land point down because air drag plays such an important part (all things fall at the same rate regardless of mass, thank you Sir Isaac Newton). It's a difficult simulation for the physics engine to get right.

1
votes

Maybe try to get the collider point between your sphere and your wall then catch your rigidbody velocity and revert it by the collision point normal.

an example of a script to do that ---> (put this script on a wall with collider )

C# script:

public class WallBumper : MonoBehaviour
{
    private Vector3 _revertDirection;
    public int speedReflectionVector = 2;
    /***********************************************
    * name : OnCollisionEnter
    * return type : void
    * Make every gameObject with a RigidBody bounce againt this platform
    * ********************************************/
    void OnCollisionEnter(Collision e)
    {
        ContactPoint cp = e.contacts[0];
        _revertDirection = Vector3.Reflect(e.rigidbody.velocity, cp.normal * -1);
        e.rigidbody.velocity = (_revertDirection.normalized * speedReflectionVector);
    }
}
0
votes

I recently has an issue with a rocket going through targets due to speed and even with continuous dynamic collision detection I couldn't keep this from happening a lot.

I solved this using a script "DontGoThroughThings" posted in wiki.unity3d.com. This uses raycasting between current and previous positions and then ensures the frame ends with the colliders connected for messages an OnTrigger event. Has worked everytime since and it's just a matter of attaching the script so super easy to use.

I think the physics answer is as others have suggested to use multiple components with different drag although typically I think you only want a single RigidBody on the parent. Instead of direction using transform.LookAt you could try and calculate using Quaternion.LookRotation from the rigidbody.velocity. Then use Vector3.Angle to find out how much are are off. The greater the angle diference the more force should be experienced and then use RigidBody.ApplyTorque. Maybe use the Sin(angleDifference) * a constant so less force is applied to torque as you approach proper rotation.

Here is some code I used on my rocket although you'll have to substitute some things as I was pointing toward a fixed target and you'll want to use your velocity.

var rotationDirection = Quaternion.LookRotation(lockedTarget.transform.position - this.transform.position);
var anglesToGo = Vector3.Angle(this.transform.rotation.eulerAngles, rotationDirection.eulerAngles);

if (anglesToGo > RotationVelocity)
{
    var rotationDirectionToMake = (rotationDirection * Quaternion.Inverse(this.transform.rotation)).eulerAngles.normalized * RotationVelocity;

    transform.Rotate(rotationDirectionToMake);
}