How do I Cancel the Momentum of an Object in Unity? - c#

I have a kill zone at the bottom of my level in my 3D platformer, but when my rolling ball get respawned using transform.position I keep my momentum. How do I cancel all momentum after position is overridden?
I've tried looking around already but everyone seems to have asked the question at least 5 years ago, and when I try to change rigidbody.velocity or rigidbody.angularVelocity, it says 'Component.rigidbody' is obsolete.
Thanks in advance!

Have a look at the docs: neither Rigidbody.velocity nore Rigidbody.angularVelocity are "obsolete" ...
From a comment I saw you actually mean the Component.rigidbody which is obsolete -> You have to get it using GetComponent as any other component.
so simply go ahead and use
var rigidbody = GetComponent<Rigidbody>();
// or in case you get it from another object or component
//var rigidbody = otherObjectOrComponent.GetComponent<Rigidbody>();
rigidbody.velocity = Vector3.zero;
rigidbody.angularVelocity = Vector3.zero;
btw you should also set the position not via the Transform component but rather using Rigidbody.position

You can cancel momentum via velocity. It is not obselete:
Rigidbody rb = GetComponent<RigidBody>();
rb.velocity = Vector3.zero;

Setting the velocity to Vector3.zero after the collision will work. If you want to completely reset the ball, I would consider destroying the old ball and instantiating a new ball prefab.

Related

Rigidbody falling speed resets when moving midair

So my rigidbody controller has a speed limiter with the following code:
Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
// limit velocity if needed
if (flatVel.magnitude > moveSpeed)
{
Vector3 limitedVel = flatVel.normalized * moveSpeed;
rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
}
but for some reason that last line of code:
rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
causes my character's falling speed to reset when moving in midair, when it reaches about -50 units of speed. I've tried modifiying rb.velocity.x and rb.velocity.z seperately, but Unity doesn't allow that. Is there any other way to cap rigidbody speeds without using rb.velocity?
According to the Unity documentation here.
In most cases you should not modify the velocity directly, as this can result in unrealistic behaviour - use AddForce instead Do not set the velocity of an object every physics step, this will lead to unrealistic physics simulation. A typical usage is where you would change the velocity is when jumping in a first person shooter, because you want an immediate change in velocity.
I'd say this is the reason you are encountering the behaviour that you are.
A Unity forum post, found here, suggests the correct way to do this is:
The 'proper' way would be to apply a force in the opposite direction of the rigidbody's velocity. The amount of force should be proportional to the extent to which the rigidbody is exceeding its speed limit.
Another Unity forum post suggests to make use of the ClampMagnitude method, the post can be found here.
private void FixedUpdate()
{
var force = new Vector3(input.x, 0f, input.y) * acceleration;
var velocity = playerRigidbody.velocity + force;
playerRigidbody.velocity = Vector3.ClampMagnitude(velocity, maxSpeed);
}
Hope this helps.

jump pad that uses characterController instead of rigidbody

now, ive ben searching for I while, and I cant seem to find a simple answer. what is a simple way to make a jump pad that uses a character controller and not a rigidbody? (written in C#) I want my character to get boosted into the air when he collides with a specific game object. the script my character is using already has gravity so all I need is an upward boost. does anyone know how to do this? I dont have any code I dont know where to start, so please help!
Did you try Dotween functions? or did you try to change transform.position in Update using your skills.first I would try Dotween functions like Dojump or DoMove, Secondly I would try this ; transform.position + = Vector3.up * Time.deltaTime;
So, you have a player, he has movement and you want him to jump when he touchs a jump pad. So you need to have a CollisionScript for the player as well as a Impulse on the jump pad. My simplistic way to this, is...
Before you use this script you need to create a tag called probably jumpPad and then add it to your jump pad in the scene.
Then I would do the Collision Script, that will detect the collision when the player collides with the jump pad. And get the impulse towards y-axis on collision.
Collision Script:
public Rigidbody playerRb;
public float jumpForce = 10f;
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("jumpPad"))
{
playerRb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
}
Then you just need to drag the player Rigidbody for the CollisionScript.
It will look like this

Make a projectile to rotate

in the game that I'm producing, the player can shoot and I'd like to make the projectile rotates continuously when the player shoot it. Each player have an empty gameobject called SpawBala which instantiates the projectile.
I'm using these lines of code to instantiate it, but the rotation is not working:
//instantiates the bullet
GameObject tiro = Instantiate(projetil, SpawBala.transform.position, SpawBala.transform.rotation);
Rigidbody BalaRigid = tiro.GetComponent<Rigidbody>();
if (SpawBala.tag == "Bala1" && gameManager.playerTurn == 1)
{
BalaRigid.AddForce(Vector3.forward * ProjetilVeloc);
BalaRigid.transform.Rotate(new Vector3(Bulletspeed * Time.deltaTime, 0, 0));
gameManager.PontoAcaop1--;
}
How could I solve it?
Your call to Rotate only happens exactly once and rotates the object about a given amount.
Anyway since there is a Rigidbody in play you shouldn't set transforms via the transform component at all because it breaks the physics.
Rather always go through the Rigidbody component.
I actually would not use AddForce and for rotation btw AddTorque when spawning a bullet. You would have to calculate the required forces depending on the bullet's weight in order to get the desired velocity(s).
Instead rather set a fix initial velocity and for the rotation angularVelocity.
Also note that currently you are always shooting in global World-Space Z direction no matter how your SpawnBala object is oriented in space. You should rather use SpawnBala.transform.forward as direction vector:
BalaRigid.velocity = SpawnBala.transform.forward * ProjetilVeloc;
// Note that your variable names are confusing
// You should probably rename it to BulletRotationSpeed e.g.
BalaRigid.angularVelocity = SpawnBala.transform.right * Bulletspeed;

Accelerate object towards a certain direction

I am trying to make a game by myself and I encountered a difficulty.
I have this object and I need it to accelerate towards a vector 3 point.
I tried using the Vector3.MoveTowards command, but the object moves with a constant velocity and stops at the destination.
What I need to do is have the object accelerate from 0 velocity towards a vector 3 point and not stop at the point, but continue at the same direction after it went through the point.
Does anyone know how to do this?
Thank you!
Perform these steps in a method that is called in the Update or FixedUpdate method. FixedUpdate is recommended if you are using rigid bodies.
First, you need to find the direction from your position to the point, and define a velocity instance variable in your script if not using Rigid Bodies. If you are using a Rigidbody, use rigidbody.velocity instead. target is the Vector3 position that you want to accelerate towards.
// Use rigidbody.velocity instead of velocity if using a Rigidbody
private Vector3 velocity; // Only if you are NOT using a RigidBody
Vector3 direction = (target - transform.position).normalized;
Then you need to check if we have already passed the target or not. This check makes sure that the velocity remains the same
// If our velocity and the direction point in different directions
// we have already passed the target, return
if(Vector3.Dot(velocity, direction) < 0)
return;
Once we have done this we need to accelerate our Transform or Rigidbody.
// If you do NOT use rigidbodies
// Perform Euler integration
velocity += (accelMagnitude * direction) * Time.deltaTime;
transform.position += velocity * Time.deltaTime;
// If you DO use rigidbodies
// Simply add a force to the rigidbody
// We scale the acceleration by the mass to cancel it out
rigidbody.AddForce(rigidbody.mass * (accelMagnitude * direction));
I recommend that you use a Rigidbody since it makes much more sense when doing something like this.

how do i do something every second after Collision

I am currently working on a football game(American) and im working on a tackle mechanic. Now just having 2 things bumping into each-other did not work because the character would continue to move after being forced sideways on the ground. To make the character stop after making contact with the other rigid body, I thought the best way would be to use Time.Timescale = 0; . However the problem with this is the fact that the 2 rigid body's then just go through each-other.to solve this I think the best way would be to set time scale to 0 after 1 second of collision. How can I do this?
Feedback is always appreciated ;)
to invoke a method delayed within unity presuming it is a monobehaviour.
the Invoke method apears to be what you are after
http://docs.unity3d.com/ScriptReference/MonoBehaviour.Invoke.html
however please be aware that Time.Timescale effects everything and is not local and would more than likely not get the effect you are after. setting the Velocity of the gameObject to zero should get the desired outcome.
var rb = GetComponent<Rigidbody>();
rb.velocity = Vector3.zero;
Time.Timescale would effect your whole game.
Actually Time.Timsescale is
The scale at which the time is passing. This can be used for slow motion effects.
When timeScale is 1.0 the time is passing as fast as realtime. When timeScale is 0.5 the time is passing 2x slower than realtime.
When timeScale is set to zero the game is basically paused if all your functions are frame rate independent.
From Unity Documentation
Well, what you can do is,
In script attached to Rigidbody's GameObject you can implement OnCollisionEnter.
Rigidbody _rb;
void Start()
{
_rb = GetComponent<Rigidbody>();
}
void OnCollisionEnter(Collision col){
_rb.velocity = Vector3.zero;
}
It will stop your player even after collision with ground. :)
So you can further modify collision condition like if body strikes to some specific object, you can detect it by tag or some other properties.
void OnCollisionEnter(Collision col){
if (col.gameObject.tag == "TAG_OF_SPECIFIC_OBJECT")
_rb.velocity = Vector3.zero;
}

Categories