i want to make an object not really bounce but in fact more like go in the opposite direction with the same velocity.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ballmove : MonoBehaviour
{
private Rigidbody rb;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
rb.AddForce(Vector3.forward * 0.02f, ForceMode.VelocityChange);
}
void OnCollisionEnter(Collision collision)
{
{
// Check if collision is with a wall
if (collision.collider.CompareTag("Wall"))
{
// Calculate the reflection vector
Vector3 reflection = Vector3.Reflect(rb.velocity, collision.contacts[0].normal);
// Apply the reflection vector as a force
rb.AddForce(reflection, ForceMode.VelocityChange);
}
}
}
this is what i have for the object right now.
so far it just moves forward until it collides with the wall where it looks like it stops but if i look at the numbers its actually moving along the x and y direction. why? i don really know honestly. might be because the wall is not actually aligned properly with the object. which i hope is the reason so that the reason is simple.
but basically it doesnt actually reflect back in the other direction.
one reason i thought of is that because its in the update event where it constantly moves forward. but in the other hand i dont know how to fix it either.
if thats not the problem… then well im stumped.
You need to first understand what your code is actually doing.
Update - each frame you AddForce to Rigidbody in forward direction (all the time).
You hit on something, you check if its Wall and…? You make short burst in oposite direction.
Now you have loop. Each Update frame you push forward, and hit the Wall making weak bump back, and push again forward and bump back etc.
You dont turn force in oposite direction.
Try this, I wrote it without editor so could be error, but maybe idea will be more clear.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ballmove : MonoBehaviour
{
Rigidbody rb;
Vector3 direction;
void Start()
{
rb = GetComponent<Rigidbody>();
// Ball direction at start
direction = Vector3.forward * 0.02f;
}
void Update()
{
// Each frame you push in that direction
rb.AddForce(direction, ForceMode.VelocityChange);
}
void OnCollisionEnter(Collision collision)
{
if (collision.collider.CompareTag("Wall"))
{
// You reflect direction
direction = Vector3.Reflect(rb.velocity, collision.contacts[0].normal);
}
}
}
In my opinion better use velocity if you plan to do something like Pong Ball. Method AddForce is more like holding the gas pedal in car (or space ship with drive on). Can be used also for impulse jump of character and gravity get him back to ground.
sorry for the late reply…
ok so unfortunately while i do understand what is going on. it still doesn’t work…
i said this in the first question
so far it just moves forward until it collides with the wall where it looks like it stops but if i look at the numbers its actually moving along the x and y direction.
i hope that doesnt really change anything right…? since reflect should be in the completely other direction?
basically what happens now is this
No, because you’re pushing the object forward in one direction every frame. Just because you’ve done some calculations elsewhere doesn’t mean you’ve broken the Update method loop.
The method always pushes the object forward because you have set Vector3.forward to a fixed position. Move the code to Start if you want to do it one time.
ok im getting more and more confused by the second somehow.
anyways from what i understand… i tried to move the addforce to start event, whilst i add another addforce to when collision
void Start()
{
rb = GetComponent<Rigidbody>();
// Ball direction at start
direction = Vector3.forward * 2f;
rb.AddForce(direction, ForceMode.VelocityChange);
}
void OnCollisionEnter(Collision collision)
{
if (collision.collider.CompareTag("Wall"))
{
// You reflect direction
direction = Vector3.Reflect(rb.velocity, collision.contacts[0].normal);
rb.AddForce(direction, ForceMode.VelocityChange);
}
}
i hope you can see where im coming from and maybe what im misunderstanding here.
unfortunately after trying this, it also does not work.
i noticed that you said this in the previous reply which i missed. so i also wanted to ask how you can change the code to “use velocity” in this scenario, because i saw the code that you gave in the first reply, and you didnt actually touch any of the things related to the velocity if im not wrong.
edit: after looking into it abit more. theres something i realized. when the box touches the wall,
the rotation of the box became from all 0 to x:-0.87,y:0.218,z:0.009
I got up this morning, had my coffee, read what I wrote to you earlier and noticed that I wrote nonsense. I wrote a simple script with comments, maybe this will be more helpful.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
// Drag and drop Rigidbody in Inspector
public Rigidbody rb;
public Vector3 velocity;
void Start()
{
// Add force once at start
rb.AddForce(Vector3.forward * 3.0f, ForceMode.VelocityChange);
}
void Update()
{
// Track velocity, it holds magnitude and direction (for collision math)
velocity = rb.velocity;
}
void OnCollisionEnter(Collision collision)
{
// Magnitude of the velocity vector is speed of the object (we will use it for constant speed so object never stop)
float speed = velocity.magnitude;
// Reflect params must be normalized so we get new direction
Vector3 direction = Vector3.Reflect(velocity.normalized, collision.contacts[0].normal);
// Like earlier wrote: velocity vector is magnitude (speed) and direction (a new one)
rb.velocity = direction * speed;
}
}
hi, im so sorry for the late reply. good news. It works now! thank you so much. just a few last question. since right now when it bounces off, the rotation changes. does that affect the next bounce direction? because as of now it doesnt look like it does when it bounces against another wall opposite it. the x position does move veryyy slightly though. is there a way to make it like pong where u start off going straight and it somehow goes to the side completely. should i like multiply the rotation when on collision or something?
secondly for some reason when it knocks against my player it slows down alot. it might have been because the player was barely tall enough to even touch the ball, but when i made the player taller, for the most part it bounced back at a normal speed. but i somehow replicated the slow down once with the taller character.
edit: wait hang on what do u mean a…physical engine
and when i started this project i randomly followed another tutorial which might complicate things i think so now my player is using character controller while my ball is using rigidbody…i dont think i should have made it so complicated for my first project.
in fact if my player is going to be as simple as moving left and right and detecting collision against the ball. will using rigid body be actually easier then…
In such situation, you just put on your Rigidbody (drag and drop) Physical Material with high bounciness. It’s the simplest explanation how to use Physical Materials I had found.
hi! im back. i have a very simple question which I’m sure is something quite stupid. but I followed the physics material tutorial. and I’m wondering if I put the bounce there will the ball lose any velocity? because it sure looks like it. but at the same time I’ve already made dynamic and static friction to 0. I’m assuming the rigid body has nothing to do with this as the drag and gravity are both 0? does it have some thing to do with this line?
rb.AddForce(Vector3.forward * 5.0f, ForceMode.VelocityChange);
btw this was done in the start event.
i created a new script for this new ball i made to test out physic materials. so yea