繁体   English   中英

Unity3D:弹跳/反射光线投射

[英]Unity3D: Bouncing/Reflecting Raycast

大家好 谢谢大家的帮助

我想要做的是相当直截了当,我试图显示一个跟随我的弹跳/反射 Raycast 的 Line Renderer。

这是我到目前为止所拥有的。

 private LineRenderer lr;

public int maxReflectionCount = 3;
public float maxStepDistance = 200f;


void Start()
{
    lr = GetComponent<LineRenderer>();
}


void Update()
{
    RaycastHit hit;

    if (Physics.Raycast(transform.position, transform.forward, out hit))
    {
        if (hit.collider)
        {
            lr.SetPosition(1, new Vector3(0, 0, hit.distance));

            Reflect(this.transform.position + this.transform.forward * 0.75f, this.transform.forward, maxReflectionCount);


        }
    }
    else
    {
        lr.SetPosition(1, new Vector3(0, 0, 2000));

    }

}


private void Reflect(Vector3 position, Vector3 direction, int reflectionsRemaining)
{

    if (reflectionsRemaining == 0)
    {
        return;
    }


    Vector3 startingPosition = position;


    Ray ray = new Ray(position, direction);
    RaycastHit hit2;
    if (Physics.Raycast(ray, out hit2, maxStepDistance))
    {
        direction = Vector3.Reflect(direction, hit2.normal);
        position = hit2.point;
    }
    else
    {
        position += direction * maxStepDistance;
    }



    Debug.DrawRay(startingPosition, position, Color.green);


    Reflect(position, direction, reflectionsRemaining - 1);


}

看起来 Vector3.Reflect 是关键,但我不太清楚如何正确使用它。

我已经让它与 Gizmos 一起工作了

线反弹 w Gizmos

但我不能在真实的东西中使用 Gizmos,而且我无法让它与 LineRenderer 一起使用。 我什至尝试使用 Debug.DrawRay 但无济于事。

我真的只是想用它来展示事物会以什么角度反弹。 关于如何让这个工作的任何想法?

我很感激任何帮助!

编辑 1:所以我已经删除了所有 Line Renderer 的东西,因为我可以稍后再担心,我一直在研究 Hacky 的建议。 我仍然无法让它正常工作,但这是它目前的样子。

//private LineRenderer lr;

public int maxReflectionCount = 3;
public float maxStepDistance = 200f;

Vector3 reflDirection;
Vector3 hitPosition;


void Start()
{
    //lr = GetComponent<LineRenderer>();
}


void Update()
{
    RaycastHit hit;

    if (Physics.Raycast(transform.position, transform.forward, out hit))
    {
        if (hit.collider)
        {
            //lr.SetPosition(1, new Vector3(0, 0, hit.distance));

            Reflect(this.transform.position + this.transform.forward * 0.75f, this.transform.forward, maxReflectionCount);
        }
    }
    else
    {
        //lr.SetPosition(1, new Vector3(0, 0, 2000));
    }

}


private void Reflect(Vector3 position, Vector3 direction, int reflectionsRemaining)
{

    if (reflectionsRemaining == 0)
    {
        return;
    }


    Vector3 startingPosition = position;


    Ray ray = new Ray(position, direction);
    RaycastHit hit2;
    if (Physics.Raycast(ray, out hit2, maxStepDistance))
    {
        reflDirection = Vector3.Reflect(direction, hit2.normal);
        hitPosition = hit2.point;
    }
    else
    {
        position += reflDirection * maxStepDistance;
    }

    Debug.DrawRay(startingPosition, reflDirection, Color.green, 1);

    //Debug.DrawLine(startingPosition, position, Color.blue);


    Reflect(position, direction, reflectionsRemaining - 1);

}

编辑 2(大进步!):好的,所以我得到了 Raycasting Reflection 工作......而且它的光荣。

这是它的样子:

 public int maxReflectionCount = 5;
public float maxStepDistance = 200f;



void Start()
{


}


void Update()
{

    Laser();
}


void Laser()
{
    DrawReflectionPattern(this.transform.position + this.transform.forward * 0.75f, this.transform.forward, maxReflectionCount);
}

private void DrawReflectionPattern(Vector3 position, Vector3 direction, int reflectionsRemaining)
{
    if (reflectionsRemaining == 0)
    {
        return;
    }

    Vector3 startingPosition = position;

    Ray ray = new Ray(position, direction);
    RaycastHit hit;
    if (Physics.Raycast(ray, out hit, maxStepDistance))
    {
        direction = Vector3.Reflect(direction, hit.normal);
        position = hit.point;
    }
    else
    {
        position += direction * maxStepDistance;
    }

    //Gizmos.color = Color.yellow;
    //Gizmos.DrawLine(startingPosition, position);

    Debug.DrawLine(startingPosition, position, Color.blue);

    DrawReflectionPattern(position, direction, reflectionsRemaining - 1);


}

现在我只需要弄清楚如何将 Line Renderer 连接到它,我们就开始做生意了!

我读了2个问题:

  1. 我不知道如何使用 vector3.reflect (“看起来 Vector3.Reflect 是关键,但我不知道如何正确使用它。”)
  2. 我不知道如何使用 linerenderer(“我无法让它与 LineRenderer 一起使用”)

我将在这里尝试回答这些问题:您使用 Vector3.Reflect 的方式是正确的。 请参阅统一文档中的示例:https ://docs.unity3d.com/ScriptReference/RaycastHit-normal.html

首先使用 Debug.DrawRay(start,dir,color, duration) 或 Debug.drawline 可视化方程的结果。 使用 1 的持续时间,以便它在场景中保持可见一秒钟并且不会立即消失。 在您的 Debug.DrawRay 中出现错误:Debug.DrawRay 的第二个参数是您拥有位置的方向。 您也不会保存光线的起始位置,因此它应该是:

Ray ray = new Ray(position, direction);
RaycastHit hit2;
if (Physics.Raycast(ray, out hit2, maxStepDistance))
{
    reflDirection = Vector3.Reflect(direction, hit2.normal);
    hitPosition = hit2.point;
}
else
{
    position += reflDirection * maxStepDistance;
}

Debug.DrawRay(hitPosition, reflDirection, Color.green);

当它工作时,使用 linerenderer 在游戏视图中显示它。 它只需要位置,所以没有方向。 注意不要将方向与位置混为一谈。 (为某个位置添加方向以获取目的地)

我想在其中添加一些内容,以帮助遇到它的其他人。 另外,我想向 OP 提供一个友好的提醒,让他们接受 Hacky 的回答作为答案,毕竟它确实回答了这个问题。

对于我的输入,我只想指出,应尽可能避免递归函数,因为对函数的每次调用都会复制所有作为参数传递给它的值类型,并且它可能会保留所有先前调用的变量,直到最后当每个函数最终可以终止时调用。 不要在最后一部分引用我的话。 我会为此推荐一个循环,它可以轻松地完成您最终所做的事情,同时使您免于调用函数的任何开销以及每次都需要复制的值。 这是我对您的“DrawReflectionPattern”功能的看法:

private void TraceReflection(Vector3 startPosition, Vector3 direction, int reflectionsRemaining) {
    for (Vector3 endPosition; (reflectionsRemaining>0); reflectionsRemaining--, startPosition = endPosition) {  
        if (Physics.Raycast(startPosition, direction, out RaycastHit hit, maxStepDistance)) {
            direction = Vector3.Reflect(direction, hit.normal);
            endPosition = hit.point;
        } else {
            endPosition = startPosition + (direction * maxStepDistance);
        }
        Debug.DrawLine(startPosition, endPosition, Color.blue);
    }
}

您还可以做一些事情来使它变得更好,比如在 for 循环之前定义 hit 变量,但我认为这仍然说明了如何使用循环而不是递归函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM