unity複雜地形檢測角色是否在地面上(與地面碰撞)(着地)的方法

補充:在膠囊碰撞體裏的物體都會被檢測到,因此當添加了諸如武器之類的碰撞盒時,應該將他們的layer設置爲和角色本身一樣的Layer,否則將會導致碰撞數量大於一個,而且即使脫離了地面,OverLarpCapsule返回碰撞數組也會>=1,導致浮空判斷爲真.或者你可以重新寫關於數組的判斷方法.


這個問題困擾了我幾天,在我找到解決方案之前,嘗試了以下方法

1.射線,在角色座標(一般是腳底),發射一根向下的射線,長度大約爲0.2,這樣是的確可以檢測到玩家是否在地面的,但只適用於簡單地形,如果你配置好了下落動畫,那麼用這種方法在斜面上往下走的話就會導致着地狀態檢測爲false,如果有動畫的話,就會播放浮空動畫..這是由於角色往前走了一步時,剛體還沒來得及讓玩家因重力而下降足夠的高度,導致射線不能射到斜面.因此判false,加長射線長度可以緩解問題,但又會導致跳躍動畫出現問題,(動畫會提前着地).而且在經過腳下有縫隙的情況而角色膠囊體半徑大於縫隙並不會掉下去的時也會導致着地狀態判false;

2.unity官方角色控制器,簡單的加上控制器並調用控制器腳本查詢是否着地時無法達到想要的效果的,着地狀態返回false,折騰了半天發現控制器只能在調用simplemove時(和move等移動函數)判斷isGrounded(是否着地),而且播放一些動畫會導致判斷在true和false狀態來回切換.並且Skinwidth也會導致這種問題.再加上一些角色控制器的限制,邏輯上不是那麼自由.例如需要自己編寫重力,因此我放棄了這個方法.

如果你有能用角色控制器達到正確的效果的方法的話,希望能告訴我,謝謝


最終使用的方法是投射一個膠囊碰撞體來檢測地面

方法來自這個視頻,視頻作者並不是我:視頻鏈接

原理:投射一個和角色本身膠囊體碰撞器一樣大小的膠囊碰撞器,(也可以不一樣,知道原理後就會知道什麼樣的大小合適了)通過這個膠囊體能比較準確的檢測着地狀態,再不是特別陡的坡和不是特別快的速度下都能比較準確的檢測到.

API:

Physics.OverlapCapsule(pointBottom, pointTop, radius, LayerMask);

以pointBottom爲底部半圓圓心,PointTop爲頂部半圓圓心,radius爲半徑,連接起來構成一個膠囊體



值得注意的是:LayerMask的設置方法,假設ground層爲10,那麼這裏如果要只碰撞第10層Layer,那麼Layermask mask=1<<10;這是位運算.按這種格式寫就行了.

然而,投射的膠囊體也會檢測自己本身,而再遊戲中也希望基本上任何能碰撞物體都能夠用來站腳,所以實際上我們要做的應該是碰撞除了用戶本身Layer以外的所有層.假設Player層爲8

寫出來的話就是:~(1<<8)

~可以理解爲位運算的取反符號


實際的代碼:

 private CapsuleCollider capsuleCollider;
    private Vector3 pointBottom, pointTop;
    private float radius; 

void Awake () {
       
        capsuleCollider = GetComponent<CapsuleCollider>();
        radius = capsuleCollider.radius;


    }


bool OnGround()
    {

        pointBottom = transform.position + transform.up * radius-transform.up*overLapCapsuleOffset;
        pointTop = transform.position + transform.up * capsuleCollider.height - transform.up * radius;
        LayerMask ignoreMask = ~(1 << 8);

        colliders = Physics.OverlapCapsule(pointBottom, pointTop, radius, ignoreMask);
        Debug.DrawLine(pointBottom, pointTop,Color.green);
        if (colliders.Length!=0)
        {
            isOnGround = true;
            return true;
        }
        else
        {
             isOnGround = false;
            return false;
        }
     
       
    }
另外: 爲避免角色在下陡坡時直接浮空,應該增加一個時間變量來計算浮空時間,當達到一定時間後才播放浮空動畫.同時也能避免角色在經過一個小坡後離地面只有幾釐米時直接播放浮空動畫的不合理情況.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章