- Home /
ball loses momentum
hi guys i'm creating a "block breaker" game and i have this one issues that the ball is losing momentum when its hitting the wall and blocks although the paddle giving you a starting momentum and and also when it hits it again
but still the ball is losing momentum to almost a complete stop
What are you using to give the ball momentum? Rigidbody with AddForce? It is hard to give you a solution if you don't give the details of how you are perfor$$anonymous$$g the action. All you have mentioned is what you expect to happen, but I want to give you an option that will jive with what you have already...
I could say, whenever the ball hits something, apply whatever you are applying to the ball when it hits the paddle, but maybe this makes it gain speed as it may carry over some risidual magnitude from before the collision. Then you may want to ensure it never gets past a certain magnitude with a little algorithmic formula. Hope that points you in the right direction
Lock the rotation, create a physics material without friction and with bounce factor of 1. Apply to all objects. Ensure there is no drag on the rigidbody.
Answer by br.glen23 · Dec 26, 2013 at 01:15 AM
Not sure how you are moving the ball, but you could probably save the vector that the ball is moving on right before the collision, then apply it to the new direction of the ball, like follows(assuming you are using rigidbodies with addForce):
/save the magnitude of the ball's vector
lastMagnituide = ballVector.magnituide();
//Change direction of ball
//sets magnituide to 1
ballVector = ballVector.Normalize();
//sets the new vector to the old vector's magnitude
ballVector = ballVector * lastMagnituide;
If you are using AddForce to move the ball, the amount of force is the magnitude of the vector, and this saves it before the collision and applies it after, to keep the same velocity.
Answer by Styxer · Dec 26, 2013 at 02:15 AM
thanks for your answers here i uploaded the game i did so you can see for yourself and also i uploaded my paddle script so you can see(btw my paddle isnt a rigidbody) paddle script
using UnityEngine;
using System.Collections;
public class PadleScript : $$anonymous$$onoBehaviour {
public float peddlespeed = 10f;
public GameObject ballPrefab;
GameObject attachedBall = null;
GUIText guiLives;
int lives=3;
int score=0;
public GUISkin scoreBoardSkin;
// Use this for initialization
void Start ()
{
DontDestroyOnLoad (gameObject);
DontDestroyOnLoad (GameObject.Find ("GuiLifes"));
guiLives = GameObject.Find ("GuiLifes").GetComponent<GUIText> ();
guiLives.text = "Lives: " + lives;
spawnball ();
}
public void OnLevelWasLoaded(int lvl)
{
spawnball ();
}
public void spawnball()
{
if (ballPrefab == null)
return;
attachedBall = (GameObject) Instantiate (ballPrefab,transform.position + new Vector3 (0, 0.75f, 0),Quaternion.identity);
}
public void AddPoints(int v){
score += v;
}
public void LoseLife()
{
lives--;
guiLives.text = "lives: " + lives;
if (lives > 0)
spawnball ();
else
{
Destroy(gameObject);
Application.LoadLevel("GameOver");
}
}
void OnGUI()
{
GUI.skin = scoreBoardSkin;
GUI.Label (new Rect (0, 0, 300, 100), "score: " + score);
}
// Update is called once per frame
void Update ()
{
transform.Translate (peddlespeed * Time.deltaTime * Input.GetAxis ("Horizontal"), 0, 0);
if (transform.position.x > 7.5f)
transform.position = new Vector3 (7.5f, transform.position.y, transform.position.z);
if (transform.position.x < -7.5f)
transform.position = new Vector3 (-7.5f, transform.position.y, transform.position.z);
if (attachedBall)
{
Rigidbody ballRigidBody = attachedBall.rigidbody;
ballRigidBody.position = transform.position + new Vector3 (0, 0.75f, 0);
if(Input.GetButtonDown("Jump"))
{
ballRigidBody.is$$anonymous$$inematic = false;
ballRigidBody.AddForce(300*Input.GetAxis ("Horizontal"),450f,0);
attachedBall=null;
}
}
}
void OnCollisionEnter (Collision col)
{
foreach (ContactPoint Contact in col.contacts)
{
if ( Contact.thisCollider==collider)
{
float english = Contact.point.x - transform.position.x;
Contact.otherCollider.rigidbody.AddForce(300f*english,0,0);
}
}
}
}
Answer by highpockets · Dec 29, 2013 at 09:28 PM
I think you should have:
A separate script attached to your ball. That is, if you don't already have one.
Add a tag in the editor for the ball when it becomes active after you press space.. Like "Active Ball", for example.
After you initially AddForce with the spacebar, on line 81 of the code that you have attached above, add this line of code:
attachedBall.tag = "Active Ball";
Within the script that is now attached to the ball, do something like this:
float targetSqrMag = 500.0f; // This is just a guess, find your happy speed with this number
void Update ()
{ if( gameObject.tag == "Active Ball" ) { Vector3 dir = rigidbody.velocity; float curSqrMag = gameObject.rigidbody.velocity.sqrMagnitude; if( curSqrMag < targetSqrMag ) { gameObject.rigidbody.AddForce( dir * 450f ) } if( curSqrMag > targetSqrMag ) { gameObject.rigidbody.AddForce( -dir * 450f ) } } }
I didn't try this code out, but I think it should do the trick. Let me know if you're still having troubles.
thanks i shall try it But wheres sqr$$anonymous$$agnitude is initialized? (or did u mean targetSqr$$anonymous$$ag>?) and another thing isn't it the first "IF"(line 5) isn't necessary i mean if isn't equal it mean that something fundamental is wrong.
P.s i attached this to my right/left/top and prefab's bricks and it seems to work(but still sometimes the ball moving too fast)
i p
sqr$$anonymous$$agnitude is in the rigidbody component. You're just getting the square magnitude of the velocity vector within the rigidbody component and storing it in curSqr$$anonymous$$ag so you can find out its relationship with your targetSqr$$anonymous$$ag.
The "if" on line 5 was to prevent the code from running before you pressed space, added force and released the ball in the other script. I thought you wanted to have the ball inactive till you did so.
You may want to play around with the max magnitude on my script, the drag on the rigidbody and the physics material to find something that works in harmony with each component involved.
Answer by MagneticDustin · Mar 30, 2015 at 09:23 AM
If you apply a force to the ball at the beginning (or at pressing space bar...) and then make all items which it will contact frictionless and bouncy, then it will never lose velocity. To do this, simply create a physics material with no friction and with a bounciness of 1 and apply it to all items (or prefabs) which the ball will contact. I tested this by doing it myself and it worked as expected.
hi..can anyone plz tell me how to convert this line in above code to use for 2d rigidbody? above script is provided by someone in tutorial in youtube.. need help with converting below to 2d..i am learning..would really appreciate..thanks.
ballRigidBody.AddForce(300*Input.GetAxis ("Horizontal"),450f,0);
and
foreach (ContactPoint Contact in col.contacts) { if ( Contact.thisCollider==collider) { float english = Contact.point.x - transform.position.x; Contact.otherCollider.rigidbody.AddForce(300f*english,0,0); } }