繁体   English   中英

Unity2D / C#:如何使光线投射忽略它的第一次碰撞?

[英]Unity2D/C#: How do I make a raycast ignore its first collision?

我的平台游戏的光线投射控制器的一个特点是玩家可以通过单向平台跳下来。 这很好用,但我想添加额外的功能,如果玩家将跳跃的平台在一定距离内,玩家将只能跳下来。

我的平台控制器的跳跃功能如下所示:

  1. 我的角色从它的盒子对撞机下方射出一束光线,并检测它是否在地面上。
  2. 如果是,并且如果地面被标记为单向平台,并且玩家按下跳下按钮,它将跳到下一个平台,无论距离如何。

我试过制作一个跳跃方法,从角色的盒子对撞机的中心创建一个新的光线投射(下面的代码中没有显示,因为到目前为止我完全不成功),并检查一定距离的碰撞。 我的问题是它总是检测到它将要从中跳下的平台的对撞机,并且永远不会有机会检测到其他任何东西。

如何让这个新的光线投射忽略第一次碰撞,可能检测到光线距离内的碰撞,如果碰到某些东西让我的角色跳下来? 另外,我是否需要进行新的光线投射,或者我可以在控制器上使用当前的光线投射?

这里有一些我的raycast控制器脚本,希望能够解释一些功能:

private void MoveVertically(ref Vector3 deltaMovement)
{
    float directionY = Mathf.Sign(deltaMovement.y);
    float rayLength = Mathf.Abs(deltaMovement.y) + skinWidth;

    for (int i = 0; i < verticalRayCount; i++)
    {
        Vector2 rayOrigin = (directionY == -1) ? raycastOrigins.bottomLeft : raycastOrigins.topLeft;
        rayOrigin += Vector2.right * (verticalRaySpacing * i + deltaMovement.x);

        RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up * directionY, rayLength, collisionMask);

        Debug.DrawRay(rayOrigin, Vector2.up * directionY * rayLength, Color.red);

        if (hit)
        {
            if (hit.collider.tag == "platformOneWay")
            {
                if (directionY == 1)
                {
                    State.IsCollidingWithOneWay = true;
                    State.IsCollidingAbove = false;
                    continue;
                }

                if (CanJumpDown)
                {
                    State.IsCollidingBelow = false;
                    continue;
                }
            }

            deltaMovement.y = (hit.distance - skinWidth) * directionY;
            rayLength = hit.distance;

实际上,Unity3D提供了一个名为Physics2D.RaycastAll的API,它不仅返回第一个光线投射命中,而且返回最大距离内的所有光线投射命中数组。
Physics2D.RaycastAll将两个Vector2作为参数(光线投射原点和方向)并返回一个RaycastHit2D数组,该数组按照从原点到命中点的距离排序。
这里有一些代码可以显示这个函数的作用:

public class Raycaster : MonoBehaviour
{
    private void Start()
    {
        RaycastHit2D[] hits = Physics2D.RaycastAll(transform.position, Vector2.down);
        for (int i = 0; i < hits.Length; ++i)
        {
            Debug.LogFormat("The name of collider {0} is \"{1}\".", 
                i, hits[i].collider.gameObject.name);
        }
    }
}

另一种方法是创建LayerMasks。 在Unity编辑器中创建一个新图层,并将图层分配给游戏对象,在该游戏对象上连接对撞机。

使用LayerMask.GetMask在代码中获取图层蒙版ID,并将其添加为参数。 现在你的Raycast只会投射分配给图层的碰撞者。

var layerMask = LayerMask.GetMask ("myLayerName");
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast (ray, out hit, 100.0f, layerMask)) {
    Debug.Log ("Got ya!");
}

暂无
暂无

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

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