一旦 CircleCast 在 Unity 中碰到某些东西,就让它停止?

Make CircleCast stop once it hits something in Unity?

我正在开发一个 2D 射弹可以从墙上弹开的游戏。我目前让物体本身弹跳得很好,但是我想要一个 Angry Birds Style HUD(减去重力)来显示物体将撞到墙上的位置,并显示它会弹跳的角度:(请原谅我的绘图技能)

我让这个系统在技术方面运行良好,除了光线投射是无止境的,所以实际结果如下所示:

所以要明确一点,最后,我希望第一个光线投射无限地出去,直到它击中某个东西,然后当它生成第二个第二个光线投射时,第一个光线投射到某个东西上,让第二个光线投射只去超出预先指定的距离(可能是 3f 或类似的东西),或者直到它撞到某物,在这种情况下它应该停止。

我的脚本:

Transform firePoint;

void Update
{
     DrawPredictionDisplay();
}

private void DrawPredictionDisplay()
    {
        Vector2 origin = firePoint.transform.position; //unity has a built in type converter that converts vector3 to vector2 by dropping the z component
        direction = firePoint.transform.up;
        float radius = 0.4f;
        RaycastHit2D hit = Physics2D.CircleCast(origin, radius, direction);

        // Draw black line from firepoint to hit point 1
        Debug.DrawLine(origin, direction * 10000, UnityEngine.Color.black);

        if (hit)
        {          
            origin = hit.point + (hit.normal * radius);
            Vector2 secondDirection = Vector2.Reflect(direction, hit.normal);            

            // Create second raycast
            RaycastHit2D hit2 = Physics2D.CircleCast(origin, radius, secondDirection);

            if (hit2)
            {
                if(hit.collider.gameObject.tag != "Destroy")
                {
                    // Enable prediction points
                    for (int i = 0; i < numOfPoints; i++)
                    {
                        predictionPoints2[i].SetActive(true);
                    }

                    // Calculate reflect direction
                    Vector2 origin2 = hit2.point + (hit2.normal * radius);
                    // Draw blue line from hit point 1 to predicted reflect direction
                    Debug.DrawLine(origin, secondDirection * 10000, UnityEngine.Color.blue);
                }      
            }
            
        }
    }

    Vector2 predictionPointPosition(float time)
    {
        Vector2 position = (Vector2)firePoint.position + direction.normalized * 10f * time;
        return position;
    }

    Vector2 predictionPointPosition2(float time, Vector2 origin, Vector2 direction)
    {
        Vector2 position = origin + direction.normalized * 10f * time;
        return position;
    }

备注:

虽然我会使用常规光线投射,但我发现普通光线投射不会削减它,因为光线投射只有 1 像素宽,而对象是(大约)512px x 512px,这意味着对象会先物理接触墙壁光线投射确实如此,导致不准确。

我已经创建了一个系统,它以类似于愤怒的小鸟的方式沿着光线投射路径生成点,以便玩家可以在游戏视图中看到光线投射在做什么,但因为它与问题无关我从上面的脚本中删除了那部分代码。这意味着我需要做的只是限制光线投射的距离,而不是为玩家找到一种方式来查看正在发生的事情。 (我在注释中添加了这个以避免引发玩家是否可以看到正在发生的事情的对话。)

firepoint 是发射弹丸的武器的 barrel/tip。 (武器根据to/following鼠标旋转)

你可以画line/path之后你知道它是否击中了一个物体:

Vector2 origin = firePoint.transform.position; //unity has a built in type converter that converts vector3 to vector2 by dropping the z component
direction = firePoint.transform.up;
float radius = 0.4f;
RaycastHit2D hit = Physics2D.CircleCast(origin, radius, direction);

var firstPathStart = origin;
var firstPathEnd = origin + direction * 10000;    

if (hit)
{          
    origin = hit.point + (hit.normal * radius);
    firstPathEnd = origin;
    
    Vector2 secondDirection = Vector2.Reflect(direction, hit.normal); 
    var secondPathStart = firstPathEnd;
    var secondPathEnd = origin + secondDirection * 3f;           

    // Create second raycast
    RaycastHit2D hit2 = Physics2D.CircleCast(origin, radius, secondDirection);

    if (hit2)
    {
        if(hit.collider.gameObject.tag != "Destroy")
        {
            // Enable prediction points
            for (int i = 0; i < numOfPoints; i++)
            {
                predictionPoints2[i].SetActive(true);
            }

            // Calculate reflect direction
            Vector2 origin2 = hit2.point + (hit2.normal * radius);
            secondPathEnd = origin2;
        }      
    }
    // Draw blue line from hit point 1 to predicted reflect direction
    Debug.DrawLine(secondPathStart, secondPathEnd, UnityEngine.Color.blue);                  
} 

// Draw black line from firepoint to hit point 1
Debug.DrawLine(firstPathStart, firstPathEnd, UnityEngine.Color.black);  

你可以做一个class来存储路径信息(路径有多少段,每段开始和结束的地方),当你检查碰撞并在最后绘制它时填充。