- Home /
Weird results when using Vector3.Reflect and RaycastHit.normal?
I'm having a problem where my sphere sometimes just goes through an object, bounces back as if the velocity was inverted, and sometimes also reflects it, but mirrored?
Not sure how I should explain, so here's a -video-.
My code for the reflecting and stuff is here :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
private Rigidbody m_bulletRigidbody;
private RaycastHit m_rayHit;
private bool m_raycastDidHit;
private void Start()
{
m_bulletRigidbody = GetComponent<Rigidbody>();
}
private void Update()
{
Debug.DrawRay(transform.position, m_bulletRigidbody.velocity.normalized, Color.red);
m_raycastDidHit = Physics.Raycast(transform.position, m_bulletRigidbody.velocity.normalized, out m_rayHit);
}
private void OnTriggerEnter(Collider other)
{
if (m_raycastDidHit)
{
if (other.gameObject.tag != "Player" && other.gameObject.tag != "LocalPlayer" && other.gameObject.tag != "Bullet")
{
if (m_rayHit.transform.gameObject.tag != "Bullet" && m_rayHit.transform.gameObject.tag != "LocalPlayer" && m_rayHit.transform.gameObject.tag != "Player")
{
Vector3 reflected = Vector3.Reflect(m_bulletRigidbody.velocity.normalized, m_rayHit.normal);
reflected.x *= m_bulletRigidbody.velocity.x;
reflected.y *= m_bulletRigidbody.velocity.y;
reflected.z *= m_bulletRigidbody.velocity.z;
m_bulletRigidbody.velocity = reflected;
}
}
}
}
}
Anyone who can explain why this is happening? :o
Answer by Jinkata · Jul 10, 2017 at 06:03 PM
I'm guessing this is moving fairly quickly considering it's a bullet and if that's the case then the physics loop to check for collisions may be missing some things. One thing you can do is keep track of the last position each frame and shoot a raycast from the last position to the new position to handle collisions that way instead of relying on the physics engine.
If you need to clarification just let me know.
Alright so as far as I can see, the suggestion which you had seems to be working when it comes to physics. None of them seem to be ignored, and all of them seem to be detecting a "broken ray / collision".
However, some of the bullets still go through, but I'm pretty sure it's a Vector3.Reflect problem since when I walk to the other side of the same object, it suddenly bounces off.
And I still seem to have the problem where the bullets bounce off surfaces unrealistically.
Here's a video of what happens now.
And here's my attempt at implementing what you suggested :
private void Update()
{
m_raycastDidHit = Physics.Raycast(transform.position, m_bulletRigidbody.velocity.normalized, out m_rayHit);
if (m_raycastDidHit && m_rayHit.distance <= Vector3.Distance(transform.position, m_lastPos))
{
Debug.DrawLine(transform.position, m_rayHit.transform.position, Color.red);
if (m_rayHit.transform.gameObject.tag != "Player" && m_rayHit.transform.gameObject.tag != "LocalPlayer" && m_rayHit.transform.gameObject.tag != "Bullet")
{
if (m_rayHit.transform.gameObject.tag != "Bullet" && m_rayHit.transform.gameObject.tag != "LocalPlayer" && m_rayHit.transform.gameObject.tag != "Player")
{
Vector3 reflected = Vector3.Reflect(m_bulletRigidbody.velocity.normalized, m_rayHit.normal);
reflected.x *= m_bulletRigidbody.velocity.x;
reflected.y *= m_bulletRigidbody.velocity.y;
reflected.z *= m_bulletRigidbody.velocity.z;
m_bulletRigidbody.velocity = reflected;
}
}
}
}
I need to test tonight, but I think I may have an idea what's going on. Not sure though. I'll see if I can't reproduce your results, or if this is a project you're willing to share so I can download it I would be more than willing to try it from there too.
I made a little line drawing function that doesn't clear the lines right away like Debug.DrawLine does, and I can now say 100% that the problem where my bullets go through the walls are not physics related, since the physics does detect a collision and the reflection code is called. So I'm pretty sure it's an issue with my reflection code.
Ins$$anonymous$$d of this:
Vector3 reflected = Vector3.Reflect(m_bulletRigidbody.velocity.normalized, m_rayHit.normal);
reflected.x *= m_bulletRigidbody.velocity.x;
reflected.y *= m_bulletRigidbody.velocity.y;
reflected.z *= m_bulletRigidbody.velocity.z;
m_bulletRigidbody.velocity = reflected;
Try this:
Vector3 reflected = Vector3.Reflect(m_bulletRigidbody.velocity.normalized, m_rayHit.normal) * Vector3.magnitude(m_bulletRigidbody.velocity);
m_bulletRigidbody.velocity = reflected;
$$anonymous$$ight need to wrap that Vector3.magnitude
in a $$anonymous$$athf.Abs
to make sure it's not a negative number.
Alright, so I tried that and the results are much better, however still not perfect. I noticed that sometimes some bullets would still go straight through a wall, no matter how big the wall was, so I did some more testing, and I noticed that it only seemed to happen when I fired many bullets at once. When I tried using a auto rifle ins$$anonymous$$d of a shotgun the bullets worked just as expected. Could it somehow be that the bullets from the shotgun "spray" are "obstructing" each other's raycasts? I can't figure why they would if they do, but I can't think of any other reason to why it would do this. And also, Vector3.magnitute
should have an uppercase $$anonymous$$, Vector3.$$anonymous$$agnitude
:]
And also, where should I upload the project files, if you still need them?
And I also noticed that the bullets always go through an object on their 3rd or 4th bounce.
This is so confusing o.O