我在统一 3d 中遇到物理问题。我希望我的球从墙上弹回并朝另一个方向移动。当球撞到墙上时,它会直接弹回来。我尝试将方向更改为与它撞墙的方向正交,但它不会改变方向。因此,球只会不断地撞到墙上并直接弹回。
其次,有时球会穿过墙壁。墙壁有盒子对撞机,而球有球对撞机。它们都具有连续动态作为碰撞检测模式。
我在统一 3d 中遇到物理问题。我希望我的球从墙上弹回并朝另一个方向移动。当球撞到墙上时,它会直接弹回来。我尝试将方向更改为与它撞墙的方向正交,但它不会改变方向。因此,球只会不断地撞到墙上并直接弹回。
其次,有时球会穿过墙壁。墙壁有盒子对撞机,而球有球对撞机。它们都具有连续动态作为碰撞检测模式。
这是一个类似线程的链接:
http://forum.unity3d.com/threads/22063-I-shot-an-arrow-up-in-the-air...?highlight=shooting+arrow
就个人而言,我会按照 GargarathSunman 在此链接中建议的那样使用 LookAt 对旋转进行编码,但是如果您想使用物理学来完成,您可能需要至少在几个部分中构建标枪,正如链接中其他人所建议的那样,并为每个部分添加不同的阻力和角度阻力值,也许还有密度。如果你在真空中投掷标枪,它永远不会落下,因为空气阻力起着如此重要的作用(无论质量如何,所有东西都以相同的速度下落,谢谢艾萨克·牛顿爵士)。要使物理引擎正确,这是一个困难的模拟。
也许尝试在你的球体和你的墙壁之间获得碰撞点,然后捕捉你的刚体速度并通过碰撞点法线恢复它。
执行此操作的脚本示例 --->(将此脚本与 collider 放在墙上)
public class WallBumper : MonoBehaviour
{
private Vector3 _revertDirection;
public int speedReflectionVector = 2;
/***********************************************
* name : OnCollisionEnter
* return type : void
* Make every gameObject with a RigidBody bounce againt this platform
* ********************************************/
void OnCollisionEnter(Collision e)
{
ContactPoint cp = e.contacts[0];
_revertDirection = Vector3.Reflect(e.rigidbody.velocity, cp.normal * -1);
e.rigidbody.velocity = (_revertDirection.normalized * speedReflectionVector);
}
}
我最近遇到了火箭通过目标的问题,由于速度的原因,即使有连续的动态碰撞检测,我也无法避免这种情况发生很多。
我使用 wiki.unity3d.com 中发布的脚本“DontGoThroughThings”解决了这个问题。这使用当前位置和先前位置之间的光线投射,然后确保帧以连接的碰撞器结束,用于消息 OnTrigger 事件。从那以后每次都有效,只需附加脚本即可,非常易于使用。
我认为物理答案是其他人建议使用具有不同阻力的多个组件,尽管通常我认为您只需要父级上的单个 RigidBody。而不是使用 transform.LookAt 的方向,您可以尝试使用来自刚体.速度的 Quaternion.LookRotation 进行计算。然后使用 Vector3.Angle 找出有多少是关闭的。角度差越大,应承受的力越大,然后使用 RigidBody.ApplyTorque。也许使用 Sin(angleDifference) * 一个常数,这样当您接近正确旋转时,施加在扭矩上的力就会更小。
这是我在火箭上使用的一些代码,尽管当我指向一个固定目标时你必须替换一些东西,并且你会想要使用你的速度。
var rotationDirection = Quaternion.LookRotation(lockedTarget.transform.position - this.transform.position);
var anglesToGo = Vector3.Angle(this.transform.rotation.eulerAngles, rotationDirection.eulerAngles);
if (anglesToGo > RotationVelocity)
{
var rotationDirectionToMake = (rotationDirection * Quaternion.Inverse(this.transform.rotation)).eulerAngles.normalized * RotationVelocity;
transform.Rotate(rotationDirectionToMake);
}