Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Unity3D:查找光线投射命中方向_C#_Unity3d_Vector_Angle_Raycasting - Fatal编程技术网

C# Unity3D:查找光线投射命中方向

C# Unity3D:查找光线投射命中方向,c#,unity3d,vector,angle,raycasting,C#,Unity3d,Vector,Angle,Raycasting,我想做一个台球游戏,我想计算主球(白球)在击中另一个球后移动的方向 如你所见,我想计算光线击中球的角度/方向,以及光线投射将改变方向的角度/方向。我需要将角度显示为Vector3变量,以便在linerenderer(3)上使用它 我已经计算了被击中的球的移动方向 如果你能在这方面帮助我,那就太好了 当前代码: RaycastHit hitz; if (Physics.SphereCast(transform.position, 0.8f, location - transform.positi

我想做一个台球游戏,我想计算主球(白球)在击中另一个球后移动的方向

如你所见,我想计算光线击中球的角度/方向,以及光线投射将改变方向的角度/方向。我需要将角度显示为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(linerender3)
{
anglelel=矢量3.角度(hitz.法线,hitz.点);
向量3交叉=向量3交叉(hitz.normal,hitz.point);
如果(交叉y>0)
{
tzt=四元数角度轴(90f,hitz.normal)*realStick.transform.forward;
}
if(横截面y<0)
{
anglelel=-anglelel;
tzt=四元数角度轴(270f,hitz.normal)*realStick.transform.forward;
}
矢量3 start2=hitz.点;
矢量3 end2=起始点2+((tzt)*5f);
LineRender3.设置位置(0,hitz.点);
LineRender3.设置位置(1,end2);
}

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

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

现在,为了得到主球移动的方向,我们只需要将之前的向量旋转90度。我们可以用四元数来做。我们通过执行以下操作来创建一个90度的向上旋转方向(或与池表垂直的任何方向):
Quaternion.AngleAxis(-90,Vector3.up)

然后,我们可以通过执行
Vector3.angle(-1*cue.up,rotate90*hit.normal)

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

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

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

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

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

现在,为了得到主球移动的方向,我们只需要将之前的向量旋转90度。我们可以用四元数来做。我们通过执行以下操作来创建一个90度的向上旋转方向(或与池表垂直的任何方向):
Quaternion.AngleAxis(-90,Vector3.up)

然后,我们可以通过执行
Vector3.angle(-1*cue.up,rotate90*hit.normal)

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

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

希望这足以帮助您从正确的方向开始,但如果您有问题,请告诉我,我会补充一些解释。

这更像是一个物理问题,而不是严格意义上的游戏编码问题。如果您试图可视化在主球上的该点施加力的结果,则需要使用其物理属性执行计算,而不仅仅是像面法线这样的东西。这是一个让你开始学习的概念——你需要把它翻译成代码:不完全是我想要的。他们讨论的问题是2D空间,而我的游戏是3D。你的游戏是3D渲染的,但除非你的台球桌不是平面的,否则所有的物理都可以简化为2D,因为它们都将保留在XZ平面上。只是好奇,phsyx引擎对你来说是否不能正常工作?还是你在尝试制作某种类型的可视化工具?@XanderLuciano基于他对线渲染器的使用,他可能试图提供预测球轨迹的可视化。这与其说是一个游戏编码问题,不如说是一个物理问题。如果您试图可视化在主球上的该点施加力的结果,则需要使用其物理属性执行计算,而不仅仅是像面法线这样的东西。这是一个让你开始学习的概念——你需要把它翻译成代码:不完全是我想要的。他们讨论的问题是2D空间,而我的游戏是3D。你的游戏是3D渲染的,但除非你的台球桌不是平面的,否则所有的物理都可以简化为2D,因为它们都将保留在XZ平面上。只是好奇,phsyx引擎对你来说是否不能正常工作?还是你在尝试制作某种类型的可视化工具?@XanderLuciano基于他对线渲染器的使用,他可能试图提供预测球轨迹的可视化。
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);
        }
    }
}