Weird behavior from Projectile after Reflect Collision


I’m building a game where you can shoot arrows, and depending on the gameobject’s tag, the character / arrow will behave differently. The mechanic I’m currently building out is a “bounce”, where the arrow will bounce off of the object using Vector3.reflect, and continue on to collide with a different object.

However when the arrow collides with an object tagged Bounce it behaves really bizarrely. The arrow moves away from the object which caused the reflection, only until the arrow stops “going up”. When the arrow reaches it’s zenith and begins to come back down, it then returns in the direction towards the object which caused the reflection.

Arrow Behavior on "Bounce"

What I have tried:

  • After collision I try to adjust the object’s rotation to match it’s velocity ( direction it should be flying). Seemingly no affect.

  • Delete Arrow and spawn an entirely new arrow in it’s location, one that is facing the reflection direction. I didn’t really explore this option a whole lot as it’s just isn’t the type of design I want to go with

  • Turning isTrigger = True for the arrow object, I know this makes absolutely no sense, but when I do this the arrow actually behaves the way I want it to. But this is obviously undesirable as I want the arrow to collide with another object after it’s first collision.

The code I’m using is below:

if ( objectCollider.gameObject.CompareTag("Bounce") )
    var new_direction = Vector3.Reflect(
            myRigidbody.velocity, collisionInfo.contacts[0].normal ).normalized;
    myRigidbody.velocity = new_direction * speed;

speed is defined elsewhere in the script, it just represents the current speed of the arrow.

Any advice is appreciated, I’ve tried a ton of what I like to call “hare-brained” solutions of just reading forums and copy/pasting code. I’m just not sure if I have the knowledge to be able to debug this properly.

Thank you!!

UPDATE ( 230104 ):

I included a Debug.Log( $"New Direction: {new_direction}" ); in my “Bounce” statement and I uncovered the source of the issue here.

My new_direction vector has no x value. It only has a y value in the response from Debug.log.

I’ve tried to add a value to new_direction by hardcoding:

myRigidbody.velocity = ( new_direction + new Vector3(-2f, 0f, 0f) );

This test has shown me something extremely close to what I would call “expected result”


But now this begs the question - Why are my x-values in my new_direction vector always 0.

Since it works as intended when you set isTrigger = true, it feels like maybe the arrow collides with something else, maybe some gameobject without a sprite?

Have you checked if the reflection code is run again when the arrow turns, for example through Debug.Log?

I was able to work out the issue.

Because I was setting new_direction AFTER the collision, I was using myRigidbody.velocity which had no X value due to the fact that object was hitting a wall and wasn’t moving.

I instead set a variable lastVelocity and only set it in the Update() loop. I passed this variable to the Reflect() function as the first parameter to get the intended result.

Thank you to @ojaoweir for the input, apologies that it ended up being an ‘obvious’ solution - really appreciate your help.