91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用Unity怎么實現地面檢測

發布時間:2021-05-31 16:11:25 來源:億速云 閱讀:1241 作者:Leah 欄目:開發技術

這篇文章將為大家詳細講解有關使用Unity怎么實現地面檢測,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

1.普通射線

在角色坐標(一般是腳底),發射一根向下的射線(長度約0.2)

但是簡單射線只適用于簡單地形,實際使用中常常遇到以下問題

1.用collider去碰撞地面,某些時候會有一定的穿插,于是角色的最低點就可能穿透地面,你發射射線的點可能就到了地面以下,射線一直檢測不到真正的地面,于是角色就一直懸空

2.角色走斜坡時,角色中點可能會離開地面一小段距離,這一小段距離往往就足夠讓判斷機制誤以為角色已經離地,如果你增加射線的長度,那么一定程度上能緩解斜坡問題,但是會降低跳躍判斷的精度,精度過低就有可能出現:角色跳起,會有那么一小段距離,其實已經離地了,但是仍然返回了isGround = true;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class RaycastTest : MonoBehaviour {

    private bool isGround = false;
    private Rigidbody2D myRigidbody2D;
    void Awake () {
        myAnimator = GetComponent<Animator>();
        myRigidbody2D = GetComponent<Rigidbody2D>();
    }
	void FixedUpdate () {
        Debug.DrawRay(transform.position, Vector2.down * 0.11f, Color.red);
        RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, 0.15f, 1 << 8);
        if (hit.collider != null)
            isGround = true;
        else
            isGround = false;
}

2.Unity官方的Character Controller

直接給角色加入Character Controller組件,在腳本中Get到Character Controller,調用.isGrounded即可,但是實際效果讓人失望

因為.isGrounded是當角色移動的時候才會檢測是否著地的,也就是說它只能在調用simplemove(和move等移動函數)時,判斷isGrounded(是否著地)

這時播放一些動畫會導致判斷在true和false狀態來回切換,并且Skinwidth也會導致這種問題,再加上一些角色控制器的限制,邏輯上不是那么自由,例如需要自己實現物理模擬,比如重力,個人覺得非常麻煩,不推薦

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OnGroundSensor : MonoBehaviour
{
    public CapsuleCollider capcol;
    public float offset = 0.1f;

    private Vector3 point1;
    private Vector3 point2;
    private float radius;

    void Awake()
    {
        radius = capcol.radius - 0.05f;
    }

    void FixedUpdate()
    {
        point1 = transform.position + transform.up * (radius - offset);
        point2 = transform.position + transform.up * (capcol.height - offset) - transform.up * radius;
        Collider[] outputCols = Physics.OverlapCapsule(point1, point2, radius, LayerMask.GetMask("Ground"));
        if (outputCols.Length != 0)
        {
            //foreach (var col in outputCols)
            //    print("collision:" + col.name);
            SendMessageUpwards("IsGround");
        }
        else
            SendMessageUpwards("IsNotGround");
    }
}

3.三射線

這個方法是社團內的Aery同志傳授的,他應用到了一個2d卷軸游戲上https://github.com/KillerAery/DarkAdventrue

寫法和簡單射線沒有什么不同,區別在于給角色加上三條射線:左腳,右腳,襠
三條射線有一條返回true則isGround為true

在我們的這個2d游戲上表現不錯

我們看看他的代碼

float dt = Time.deltaTime;
//累計時間
vida.chargeTimer += dt;
vida.jumpTimer += dt;

//TODO 待優化代碼
//是否到地面 用三個groundCheck來檢測 
//public Transform[] groundChecks = new Transform[3];
for (int i = 0; i < 3; ++i)
{
    checkResult = Physics2D.Linecast(transform.position, 		
                    groundChecks[i].position, 
                    1 << LayerMask.NameToLayer("Ground"));
    vida.grounded = checkResult;
    if (vida.grounded) break;
}

if (vida.grounded)
{
    //火箭蛋(硬件蛋特殊技能)
    if (vida.playerType == Tags.YingjianDan)
    {
        vida.jumpable = 1;

    }
}

//跳躍
//按下K時
if (Input.GetKeyDown(KeyCode.K) && vida.jumpTimer >= 0.03f)
{
    if (vida.grounded)
    {
        //允許跳躍
        vida.jumpTimer = 0.0f;
        vida.jump = true;
    }
    else if (vida.jumpable > 0)
    {
        vida.jumpable--;
        //允許跳躍
        vida.jumpTimer = 0.0f;
        vida.jump = true;
    }

}

4.OverlapCapsule 投射膠囊碰撞體

這個方法是看傅老師的黑魂復刻系列視頻學的

使用Unity怎么實現地面檢測

使用Unity怎么實現地面檢測

point0,point1,radius 分別為膠囊體起點球心,膠囊體終點球心,膠囊體半徑

我們這里只要用到這一重載方法 Physics.OverlapCapsule(pointBottom, pointTop, radius, LayerMask)

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

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

5.LayerMask設置方法

最后提下這個LayerMask

假設ground層為10,指定碰撞第10層Layer,寫法為:Layermask mask=1<<10

但是,投射的膠囊體也會檢測自己本身,如果你希望游戲中基本上任何能碰撞物體都能夠用來站腳,那么應設置為:碰撞除了角色所在的Layer以外的所有層(假設Player層為8

寫法為:~(1<<8)

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;
        }
}

關于使用Unity怎么實現地面檢測就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

长武县| 高邮市| 襄汾县| 宣威市| 邯郸市| 连城县| 太原市| 江口县| 昌乐县| 英山县| 河北区| 道孚县| 翁牛特旗| 舟曲县| 栾川县| 通化市| 澳门| 五常市| 江津市| 密云县| 苗栗市| 都江堰市| 宁强县| 岳池县| 丰顺县| 湛江市| 仪征市| 神池县| 黑水县| 馆陶县| 柳州市| 同心县| 甘孜县| 石柱| 盘山县| 禄丰县| 大宁县| 阳新县| 隆化县| 博罗县| 毕节市|