我想让一个弹丸通过更新它的位置来移动(这里不想使用物理学),使它从墙上弹起。
所以我现在要做的是检测碰撞,然后用一个raycast得到墙的法线,然后用vector3.reflect知道新的方向。据我所知,我不能使用碰撞法线,因为它是对象的法线,而不是墙的法线,对吗?
代码看起来是这样的。
point = collision.contacts[0].point;
dir = bullet.transform.forward;
point -= dir; // to step back a bit, for the raycast
// this raycast is represented by the blue gizmo lines in the image below
if (Physics.Raycast(point, dir, out RaycastHit hitInfo, 10f, ~LayerMask.GetMask("EnemyBullet", "PlayerBullet"))) {
// this is the collider surface normal
// it's represented by the red lines in the image below
var normal = hitInfo.normal;
// this part is not important, what matters is finding out why the normal above is going up, and not away from the wall.
Vector3 reflect = Vector3.Reflect(-bullet.transform.forward, normal).Y(bullet.transform.position.y);
Debug.Log(reflect);
return reflect;
}
return Vector3.zero;
(这里是Raycast和法线的放大版) https:/i.imgur.comTBSy4vb.png?1。)
而这里有一个问题的视频。https:/www.youtube.comwatch?v=zq5jL2-I1Kg
白色的Gizmo线是墙体的法线,从玩家对墙体的射线广播中获得。它是作为一个参考,一个调试工具。如你所见,它的方向是正确的。
蓝色的线条代表我从上面的代码中做的射线广播(Physics.Raycast(point, dir
). 它们似乎可以穿墙而过。
现在的问题是:红色的线是我从 var normal = hitInfo.normal;
在上面的代码中。我本以为它们会和白色的小精灵线在同一个方向......
你能看出上面的代码有明显的错误吗?如果你需要更多信息,就问吧。
(对不起,我不能评论,我的答案可能是错误的)我几乎可以肯定是下面的代码有问题。
point = collision.contacts[0].point;
dir = bullet.transform.forward;
point -= dir; // to step back a bit, for the raycast
你真的确定你退后了一点吗?我觉得有时候会后退一步,有时候会前进一步。
试试这个。
point = collision.contacts[0].point;
dir = -info.contacts[0].normal;
point -= dir;
它应该正确地后退,然后你的射线广播应该有一个正确的方向,我从: 碰撞,得到正常的也许有帮助。
我找到了问题所在。
1 - Vector3.Reflect(bullet.transform.forward, normal).Y(bullet.transform.position.y)
. 我应该将y位置设置为0,而不是子弹变换的y位置。
2 - 在我的代码中,我使用的是 Vector3.Reflect
与 transform.lookAt(vector)
而我应该用 transform.rotation = Quaternion.LookRotation(newDirection)
但总体上我简化了不少代码,似乎还能用。我只是在弹丸碰撞时,向弹丸的前进方向进行射线投射,就能正常工作。