簡體   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