Unity3D:弹跳/反射光线投射

Posted

技术标签:

【中文标题】Unity3D:弹跳/反射光线投射【英文标题】:Unity3D: Bouncing/Reflecting Raycast 【发布时间】:2019-01-26 15:00:28 【问题描述】:

大家好,谢谢大家的帮助,

我正在尝试做的是相当直截了当,我正在尝试显示一个跟随我的弹跳/反射 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 一起工作

但我不能在实际中使用 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 连接到它就可以了!

【问题讨论】:

【参考方案1】:

我读了 2 个问题:

    我不知道如何使用vector3.reflect(“看起来Vector3.Reflect是关键,但我不知道如何正确使用它。”) 我不知道如何使用 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 在游戏视图中显示它。它只需要位置,所以没有方向。注意不要将方向与位置混为一谈。 (为某个位置添加方向以获得目的地)

【讨论】:

感谢您的帮助!那么我需要另外两个 Vector3 吗?这就是你添加 reflDirection 和 hitPosition 而不是使用位置和方向的原因吗?对不起,我的编程知识很基础,只是想学习。 伙计,我什至无法得到您发布的内容,哈哈...好吧,我已经删除了所有 Line Renderer 代码,您说得对,我以后可以担心。我已经输入了您的代码并添加了新的 Vector3,但我仍然无法使其正常工作。我会编辑我的帖子,向您展示我正在使用的内容。 你有一个很好的递归函数。源码还不错。您只需要在该函数的开头保存射线位置和方向的值,以便最终您可以使用它。很高兴你做到了。至于 linerenderer:它包含一个职位列表。为此,您需要清除 linerenderer 在laser() 上的位置,并在每个DrawReflectionPattern() 中为其添加一个位置。就这样。确保 linerenderer 对象的变换也完全重置。

以上是关于Unity3D:弹跳/反射光线投射的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D:弹跳/反射Raycast

unity3d中四种光源有啥区别

unity获取raycast的XYZ

Unity3D C#数学系列之点积

Unity3D - 使用 Raycasting 检测游戏对象。自上而下的视图

什么是(diffuse)漫反射?镜面反射?环境光?法向量?