我试图为一个简单的拼图系统,一个游戏涉及光束和镜子在统一。光束是使用一个空的GameObject创建的,该Raycast2D转换为Raycast2D,并使用LineRenderer来显示光束。当光束与镜像物体碰撞时,我只需使用Vector2.Reflect计算新的方向。
当镜像是静态的时,实现可以正常工作。当我试图在游戏中移动它们时,它会导致随机堆栈溢出错误,而且似乎没有一个模式。下面是一个工作镜像设置的示例:

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

我猜这是由于镜子将光束反射回来并导致无限反射循环,但我不知道为什么会发生这种情况。
相关守则:
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();
}
}
}错误消息:
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完全崩溃的团结。
void CastRay(Vector2 pos, Vector2 dir, LineRenderer beam, int maxReflections)
{
if(maxReflections <= 0)
{
Debug.Log("Too many reflections");
return;
}发布于 2021-06-09 15:00:59
事实证明,当光束的原点在其中一个镜子里时,光束就消失了。我解决了它通过移动新的雷卡斯特的起源轻微时,与镜子碰撞。
我在这里找到了解决方案:https://answers.unity.com/questions/1176130/need-help-ironing-out-this-weird-error-in-raycast2.html
发布于 2021-06-09 09:50:18
如果不满足条件if(hit.collider.gameObject.tag == "Mirror"),则需要执行lightPoints.Add(hit.point);并翻转波束,同时向LineRenderer组件位置数组添加点。这似乎不是一个好主意,因为你大概会到达点,当光线不再击中。实际上,一旦到达这个点,就会继续添加点,从而导致堆栈溢出。
我会添加一些安全条件,如果您没有击中感兴趣的游戏对象,可能是一个确定的射线长度,或者如果光线没有命中,您就停止在列表/数组中添加点。
我检查了您在脚本本身中出现的错误行,没有很好的恢复信息。但你有剧本以防有帮助。
https://stackoverflow.com/questions/67900862
复制相似问题