c# - Unity3D : Find Raycasthit direction

标签 c# unity-game-engine vector angle raycasting

我正在尝试制作台球游戏,我想计算母球(白球)击中另一个球后的移动方向。

Visuals

正如你所看到的,我想计算光线击中球的角度/方向以及光线转换将改变其方向的角度/方向。我需要将角度显示为 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);
  }

最佳答案

让我们一点一点地来看这个。首先,这是一个经典的物理 101 问题。 2 个台球撞击时形成的角度是完美的 90 度角。请注意下图中的绿色和蓝色矢量如何形成直角:

Physics of a pool ball

现在,您还应该注意到,从接触点到两个球的中心都垂直于两个球的表面。这意味着在统一中,我们可以使用 hit.normal 来获取我们击打的球的行进方向。我们只需要通过执行以下操作来反转它: -1 * hit.normal

现在,为了获得母球行进的方向,我们只需将之前的向量旋转 90 度即可。我们可以用四元数来做到这一点。我们通过执行以下操作创建围绕向上方向(或与台球 table 垂直的任何方向)的 90 度旋转:Quaternion.AngleAxis(-90, Vector3.up)

然后,我们可以通过执行 Vector3.Angle(-1 *cue.up,rotate90 *hit.normal) 来计算原始行进向量与母球行进角度之间的角度

让我们看看我的测试场景中的这个视觉示例:

Unity pool table

我对向量进行统一颜色编码以匹配上图。您可能注意到的唯一区别是黑色向量,它代表我们的 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);
        }
    }
}

希望这足以帮助您朝着正确的方向开始,但如果您有疑问,请告诉我,我将添加更多解释。

关于c# - Unity3D : Find Raycasthit direction,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39083830/

相关文章:

c++ - 为什么我的输出在到达代码的这一部分时卡住了?

c# - WCF - 在 CMS 中使用 Web 控制的客户端安全

C++ vector - 访问在结构中声明的结构类型 vector 的大小

c# - 使用 .NET(控制台应用程序)发布多个文件和表单值

unity-game-engine - 为什么协程继承自IEnumerator?

android - Unity HTML5(WebGL) 导出的项目无法在手机/平板电脑上运行

c# - 在 C# 脚本中使用 Translate.translate 2d sprite 速度太快(unity)

c++ - vector 的错误内存分配 C++

C#文件关联的正确方法

c# - 将进度保存到文本文件 C#