我试图制作一个台球游戏,我想计算一下Cue Ball(白球)击中另一个球后的方向。
正如你所看到的,我想计算射线击中球的角度/方向以及射线投射将改变其方向的角度/方向。我需要将角度显示为Vector3变量,以便我可以在linerenderer(3)上使用它。
我已经计算了被击中球的方向。
如果你能帮助我,那就太棒了!
当前代码:
RaycastHit hitz;
if (Physics.SphereCast(transform.position, 0.8f, location - transform.position, out hitz, Mathf.Infinity, lmm2))
{
lineRenderer2 = hitz.collider.GetComponentInChildren<LineRenderer>();
lineRenderer2.SetVertexCount(2);
if (!Input.GetKey(KeyCode.Mouse0))
lineRenderer2.SetPosition(0, hitz.point);
if (!Input.GetKey(KeyCode.Mouse0))
{
Vector3 start = hitz.point;
Vector3 end = start + (-hitz.normal * 4);
if (lineRenderer2)
{
if (!Input.GetKey(KeyCode.Mouse0))
lineRenderer2.SetPosition(1, end);
}
if(lineRenderer3)
{
anglelel = Vector3.Angle(hitz.normal, hitz.point);
Vector3 cross = Vector3.Cross(hitz.normal, hitz.point);
if(cross.y > 0)
{
tzt = Quaternion.AngleAxis(90f, hitz.normal) *realStick.transform.forward;
}
if (cross.y < 0)
{
anglelel = -anglelel;
tzt = Quaternion.AngleAxis(270f, hitz.normal) * realStick.transform.forward;
}
Vector3 start2 = hitz.point;
Vector3 end2 = start2 + ((tzt) * 5f);
lineRenderer3.SetPosition(0, hitz.point);
lineRenderer3.SetPosition(1, end2);
}
}
}
感谢您的时间。
编辑:
这部分代码已经改为这一部分,目前已经取得了一些进展,但仍然不够好。 前
if(lineRenderer3)
{
Vector3 start2 = hitz.point;
//THIS IS WHERE I'M CURRENTLY STUCK AT
Vector3 end2 = start2 + (hitz.point * 0.7f);
lineRenderer3.SetPosition(0, hitz.point);
lineRenderer3.SetPosition(1, end2);
}
在
if(lineRenderer3)
{
anglelel = Vector3.Angle(hitz.normal, hitz.point);
Vector3 cross = Vector3.Cross(hitz.normal, hitz.point);
if(cross.y > 0)
{
tzt = Quaternion.AngleAxis(90f, hitz.normal) *realStick.transform.forward;
}
if (cross.y < 0)
{
anglelel = -anglelel;
tzt = Quaternion.AngleAxis(270f, hitz.normal) * realStick.transform.forward;
}
Vector3 start2 = hitz.point;
Vector3 end2 = start2 + ((tzt) * 5f);
lineRenderer3.SetPosition(0, hitz.point);
lineRenderer3.SetPosition(1, end2);
}
答案 0 :(得分:3)
让我们一块一块。首先,这是一个经典的物理101问题。角度2台球在撞击时是一个完美的90度角。请注意下图中的绿色和蓝色矢量如何成直角:
现在,您还应该注意到从两个球的中心接触点垂直于两个球的表面。这意味着在统一中,我们可以使用hit.normal
来获得我们击中的球的行进方向。我们只需要执行以下操作来反转它:-1 * hit.normal
现在,为了获得母球移动的方向,我们只需要将前一个矢量旋转90度。我们可以用四元数做到这一点。我们通过执行以下操作创建关于向上方向(或与池表正常的任何方向)的90度旋转:Quaternion.AngleAxis(-90, Vector3.up)
然后,我们可以通过Vector3.Angle(-1 * cue.up, rotate90 * hit.normal)
让我们看看测试场景中的这个视觉示例:
我对矢量进行了颜色编码,以匹配上图。您可能会注意到的唯一区别是黑色矢量,它代表我们的hit.normal
。
以下是代码:
public class Main : MonoBehaviour {
public Transform cue,cueBallPostHit;
public int dist = 10;
public Color red,green,blue;
RaycastHit hit;
float scale,ballAngle;
Quaternion rotate90;
Vector3 cueBallHitPosition;
void Start () {
rotate90 = Quaternion.AngleAxis(-90, Vector3.up);
}
void FixedUpdate () {
if(Physics.SphereCast(cue.position, .5f, cue.up, out hit, dist))
{
// Calculate variables
cueBallHitPosition = hit.point + (.5f * hit.normal);
scale = (cue.position - hit.point).magnitude;
ballAngle = Vector3.Angle(-1 * cue.up, rotate90 * hit.normal);
print(ballAngle);
// Cue Ball Direction and normal
Debug.DrawLine(cue.position, cueBallHitPosition, red);
Debug.DrawRay(cueBallHitPosition, hit.normal, Color.black);
// Ball direction
Debug.DrawRay(hit.point + (-.5f * hit.normal), -1 * hit.normal * scale, blue);
// Cue Ball Direction
Debug.DrawRay(cueBallHitPosition, rotate90 * hit.normal * scale, green);
// Visual for where the ball will hit
cueBallPostHit.position = cueBallHitPosition;
}
else
{
Debug.DrawRay(cue.position, cue.up * dist, blue);
cueBallPostHit.position = cue.position + (2 * cue.up);
}
}
}
希望这应该足以帮助您开始朝着正确的方向前进,但如果您有任何疑问,请告诉我,我会再添加一些解释。