Vector3.reflect makes a strange rotation

(my apology for my bad english )

Hello, for my little shooter game, I wanted to make the bullets bounces on the wall but I encountered some problems and I didn’t find any answers on the forum.

I used the Vector3.reflect in the OnCollisionEnter2d to find the direction and when I apply the result, the bounce is correct but my bullet is always facing to the top. I found that the transform.forward of my bullet don’t change even after bounce and all my bullet have the same transform.forward (0,0,1). Not sure if that can help but I’m a beginner and the doc is not clear

Vector3 dir = Vector3.Reflect(transform.forward,collision.contacts[0].normal);
transform.forward = dir;

Thx for your answer.

Hi,
I think you could reflect the last velocity of your bullet object. Here’s some pseudo-code:

Vector3 direction = Vector3.Reflect(lastVelocity, collisionNormal);
rb.velocity = direction;

P.S. Maybe you could fix your code tags, they are a bit messed up. And what’s up with that double semicolon there on the last line?

1 Like

Thank you for your reply.
It doesn’t seems to work. The bullet keeps going on the wall instead of bouncing. I will continue to see what’s wrong because I saw nobody with my problem on this forum.

Can you show your code so far? It’s hard to guess what you might have done wrong.

Hi @Antoop1 ,

why do you equalize trasform.forward to reflected direction? You can add force after reflecting direction of object. I have a piece of codes that can help you to understand how it’d work…

using UnityEngine;

public class MyMovement : MonoBehaviour
{
    public float enemyThrust;
    private Rigidbody enemyRB;
    private Vector3 enemyDirection;

    private void Awake()
    {
        enemyRB = GetComponent<Rigidbody>();
    }

    private void Start()
    {
        enemyDirection = transform.forward;
    }

    private void Update()
    {
        enemyRB.velocity = enemyDirection * enemyThrust;
    }

    private void OnCollisionEnter(Collision collision)
    {
        ContactPoint contact = collision.GetContact(0);

        if (collision.gameObject.tag == "Wall")
        {
            enemyDirection = Vector3.Reflect(enemyDirection, contact.normal);
        }
    }
}
1 Like

Hi @CoolCosmos .
Your post was really helpfull but I have a problem with the transform.forward ( or I don’t understand the functionnality). If I use your code the bullet will not move because transform.forward is always equal to (0,0,1). I don’t know if the problem is on the instantiate but there is my code:

When the player shoot:

private void Shoot()
{
        GameObject bullet = Instantiate(bulletPrefab,firePoint.position,transform.rotation);
}

The actual bullet script :

public class Bullet : MonoBehaviour
{
    private Rigidbody2D rb;
    public float thrust = 20;
    private Vector3 direction;


    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        direction = transform.forward;
    }

    void Update()
    {
        rb.velocity = direction * thrust;
    }


    private void OnCollisionEnter2D(Collision2D collision)
    {

        ContactPoint2D contact = collision.GetContact(0);

        if (collision.gameObject.tag == "Wall")
        {
            direction = Vector3.Reflect(direction, contact.normal);

        }
    }
}

Edit: If I put

direction = transform.up;

instead of transform.forward (on the start method), the bullet will reflect well but the bullet does not rotate in the direction it is going

I keep shearching. Thank you to take time to help beginners :slight_smile:

Antoop1

Edit: Nevermind, I found a solution.

I use the vector “direction” to find a angle and apply it to the bullet:
in the update method :

float rotationz = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, rotationz - 90);

Like I said before, in the start method i used transform.up instead of transform.forward.

Here is the working code:

 void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        direction = transform.up;


    }

    // Update is called once per frame
    void Update()
    {
        rb.velocity = direction * thrust;
        float rotationz = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
        transform.rotation = Quaternion.Euler(0f, 0f, rotationz - 90);
    }


    private void OnCollisionEnter2D(Collision2D collision)
    {

        ContactPoint2D contact = collision.GetContact(0);

        if (collision.gameObject.tag == "Wall")
        {
            direction = Vector3.Reflect(direction, contact.normal);

        }
}
}

Thank you for your really helpfull answers.

Antoop1

3 Likes