首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >反射StackOverflowException时Raycast2D

反射StackOverflowException时Raycast2D
EN

Stack Overflow用户
提问于 2021-06-09 09:00:54
回答 2查看 176关注 0票数 0

我试图为一个简单的拼图系统,一个游戏涉及光束和镜子在统一。光束是使用一个空的GameObject创建的,该Raycast2D转换为Raycast2D,并使用LineRenderer来显示光束。当光束与镜像物体碰撞时,我只需使用Vector2.Reflect计算新的方向。

当镜像是静态的时,实现可以正常工作。当我试图在游戏中移动它们时,它会导致随机堆栈溢出错误,而且似乎没有一个模式。下面是一个工作镜像设置的示例:

当我移动一面镜子时,会发生这样的事情:

我猜这是由于镜子将光束反射回来并导致无限反射循环,但我不知道为什么会发生这种情况。

相关守则:

代码语言:javascript
复制
public class LightBeam
{
    Vector2 position;
    Vector2 direction;

    GameObject lightBeam;
    LineRenderer lightRender;

    List<Vector2> lightPoints = new List<Vector2>();

    // A new LightBeam object is created every update
    public LightBeam(Vector2 startPos, Vector2 dir, Material material)
    {
        this.lightRender = new LineRenderer();
        this.lightBeam = new GameObject();
        this.lightBeam.name = "LightBeam";

        this.position = startPos;
        this.direction = dir;

        this.lightRender = this.lightBeam.AddComponent(typeof(LineRenderer)) as LineRenderer;
        this.lightRender.startWidth = 0.1f;
        this.lightRender.endWidth = 0.1f;
        this.lightRender.material = material;
        this.lightRender.startColor = Color.white;
        this.lightRender.endColor = Color.white;

        this.lightRender.sortingLayerName = "Foreground";

        CastRay(startPos, dir, lightRender);
    }

    void CastRay(Vector2 pos, Vector2 dir, LineRenderer beam)
    {

        lightPoints.Add(pos);

        // Source of the error
        RaycastHit2D hit = Physics2D.Raycast(pos, dir, 10, LayerMask.GetMask("Solid"));

        if(hit)
        {
            CheckHit(hit, dir, lightRender);
        }
        else
        {
            lightPoints.Add(lightPoints[lightPoints.Count-1] + dir * 10);
        }

        UpdateBeam();
    }

    void UpdateBeam()
    {
        lightRender.positionCount = lightPoints.Count;

        for(int i = 0; i < lightPoints.Count; i++)
        {
            lightRender.SetPosition(i, lightPoints[i]);
        }
    }

    void CheckHit(RaycastHit2D hit, Vector2 dir, LineRenderer beam)
    {
        if(hit.collider.gameObject.tag == "Mirror")
        {
            Vector2 pos = hit.point;
            Vector2 newDir = Vector2.Reflect(dir, hit.normal);

            CastRay(pos, newDir, beam);
        }
        else
        {
            lightPoints.Add(hit.point);
            UpdateBeam();
        }
    }
}

错误消息:

代码语言:javascript
复制
StackOverflowException: The requested operation caused a stack overflow.
UnityEngine.ContactFilter2D.CreateLegacyFilter (System.Int32 layerMask, System.Single minDepth, System.Single maxDepth) (at C:/buildslave/unity/build/Modules/Physics2D/ScriptBindings/Physics2D.bindings.cs:2297)
UnityEngine.Physics2D.Raycast (UnityEngine.Vector2 origin, UnityEngine.Vector2 direction, System.Single distance, System.Int32 layerMask) (at C:/buildslave/unity/build/Modules/Physics2D/ScriptBindings/Physics2D.bindings.cs:843)
LightBeam.CastRay (UnityEngine.Vector2 pos, UnityEngine.Vector2 dir, UnityEngine.LineRenderer beam) (at Assets/Scripts/LightBeam.cs:50)
LightBeam.CheckHit (UnityEngine.RaycastHit2D hit, UnityEngine.Vector2 dir, UnityEngine.LineRenderer beam) (at Assets/Scripts/LightBeam.cs:82)
LightBeam.CastRay (UnityEngine.Vector2 pos, UnityEngine.Vector2 dir, UnityEngine.LineRenderer beam) (at Assets/Scripts/LightBeam.cs:55)
LightBeam.CheckHit (UnityEngine.RaycastHit2D hit, UnityEngine.Vector2 dir, UnityEngine.LineRenderer beam) (at Assets/Scripts/LightBeam.cs:82)
LightBeam.CastRay (UnityEngine.Vector2 pos, UnityEngine.Vector2 dir, UnityEngine.LineRenderer beam) (at Assets/Scripts/LightBeam.cs:55)
LightBeam.CheckHit (UnityEngine.RaycastHit2D hit, UnityEngine.Vector2 dir, UnityEngine.LineRenderer beam) (at Assets/Scripts/LightBeam.cs:82)

更新:,原来光束是无限反射的。我添加了一个maxReflections值来限制循环的数量,但是除了抑制StackOverflow错误之外,它没有什么作用,并且当镜像被移动时,光束仍然闪烁。

此外,试图在Debug.Log(pos)方法中的CastRay完全崩溃的团结。

代码语言:javascript
复制
void CastRay(Vector2 pos, Vector2 dir, LineRenderer beam, int maxReflections)
    {
        
        if(maxReflections <= 0)
        {
            Debug.Log("Too many reflections");
            return;
        }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-06-09 15:00:59

事实证明,当光束的原点在其中一个镜子里时,光束就消失了。我解决了它通过移动新的雷卡斯特的起源轻微时,与镜子碰撞。

我在这里找到了解决方案:https://answers.unity.com/questions/1176130/need-help-ironing-out-this-weird-error-in-raycast2.html

票数 0
EN

Stack Overflow用户

发布于 2021-06-09 09:50:18

如果不满足条件if(hit.collider.gameObject.tag == "Mirror"),则需要执行lightPoints.Add(hit.point);并翻转波束,同时向LineRenderer组件位置数组添加点。这似乎不是一个好主意,因为你大概会到达点,当光线不再击中。实际上,一旦到达这个点,就会继续添加点,从而导致堆栈溢出。

我会添加一些安全条件,如果您没有击中感兴趣的游戏对象,可能是一个确定的射线长度,或者如果光线没有命中,您就停止在列表/数组中添加点。

我检查了您在脚本本身中出现的错误行,没有很好的恢复信息。但你有剧本以防有帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67900862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档