使用磁貼圖實現命中檢測

更新頁 :
頁面創建日期 :

驗證環境

窗戶
  • 視窗 11
統一編輯器
  • 2021.3.3f1
輸入系統包
  • 1.3.0

此提示的先決條件

作為此提示描述的前提,已預先進行了以下設置。

此提示的先決條件是什麼?

關於借用地圖材質

我們處理從以下網站借來的。

行走字元的實現

首先,實現一個地圖和一個執行命中檢測的角色。 可以使用鍵盤上的游標鍵移動此字元。 但是,如果實施正確的步行,它將與書本技巧的精髓相去甚遠,所以這次我只移動一個簡單的單圖。

如果要實現步行動畫,請參閱以下提示:

創建專案后,添加要移動到項目的物件的精靈圖像。

選擇圖像,然後從檢查器中將每單位像素數設定為32。 這是因為地圖晶元的一個正方形的大小是32圖元,所以它適合這個。 配置完成後,按下下面的“應用”按鈕。

將角色放在檢視中。

創建一個腳本來移動精靈。 這類似於以下提示:

將文稿名稱 Player 保留為 。

代碼如下:

using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
  // 一定時間ごとに呼ばれます
  void FixedUpdate()
  {
    // キーボードの情報を取得
    var keyboard = Keyboard.current;

    // スプライトの移動処理
    if (keyboard.leftArrowKey.isPressed)
    {
      transform.Translate(-0.1f, 0, 0, Space.World);
    }
    if (keyboard.rightArrowKey.isPressed)
    {
      transform.Translate(0.1f, 0, 0, Space.World);
    }
    if (keyboard.upArrowKey.isPressed)
    {
      transform.Translate(0, 0.1f, 0, Space.World);
    }
    if (keyboard.downArrowKey.isPressed)
    {
      transform.Translate(0, -0.1f, 0, Space.World);
    }
  }
}

附加到要移動的精靈。

運行遊戲並檢查是否要用鍵盤移動它。

準備地圖提示

首先,我們將準備一個地圖晶元並創建一個地圖。 此過程類似於以下提示: 帶有 2D Tilemap Extras 的 MapTips 也能夠進行碰撞檢測,但本文不會使用它們,因為該過程會很長。

準備地圖提示的原始圖像並將其添加到您的專案中。 為使操作更易於理解,請為地圖晶元材料準備一個“步行場所”和一個“不可步行的地方”。

在檢查器中為MapChips設置它,然後按兩下「應用」按鈕。 配置完成後,打開精靈編輯器。

這是一個 32 像素的地圖提示,所以我會在 32 像素處拆分它。

選擇「磁貼調色板」選項卡。 如果沒有,請使用功能表中的「視窗> 2D -> 平鋪調色板」顯示它。 創建新調色板。 這個名字是任意的,但現在我們稱之為“MapChipPalette”。

在場景中創建一個 MapChipPalette 資料夾並指定它。

通過將地圖提示拖動到調色板來添加地圖提示。 將其保存在您之前創建的 MapChipPalette 資料夾中。

創建地圖

這一次,地圖命中判斷將以「瓦片地圖」為單位進行。 因此,我們將創建兩個瓦片映射,“沒有命中檢測的瓦片地圖”和“帶命中檢測的瓦片地圖”。

首先,在層次結構中創建兩個圖塊映射。 您可以在格格中建立兩個。 為清楚起見,名稱為“TilemapObeject”和“TilemapGround”。

首先,創建一個“TilemapGround”。 由於它是一個可移動的範圍,您可以簡單地鋪設地面。 如果是在地面上,您可以更改模式。

順便說一下,如果字元是隱藏的,請選擇字元物件並將檢查器的圖層順序 Sprite Renderer 設置為 2。 默認情況下,圖層的順序為0,切片地圖為0,因此如果將其增加到此值以上,它將顯示在前臺。

然後選擇「磁貼地圖物件」並放置要使其靜止的地圖提示。 首先將圖層順序設置為 1。 這是為了讓它出現在地面前面。

這就是你隱藏地面的樣子。

當然,此時沒有與碰撞檢測相關的設置,因此您可以正常騎在高地上。 在此之後,我們將設置碰撞檢測。

碰撞檢測設置

首先,讓我們設置角色。 此設置與下面的提示幾乎相同,因此我將跳過詳細資訊並簡要說明該過程。

從層次結構中選擇一個角色對象,然後從添加元件中選擇物理 2D -> 圓形碰撞體 2D。 如果物體的形狀是矩形的,則“Box Collider 2D”就可以了。

同樣,添加「物理 2D -> 剛體 2D」。。

將重力刻度設置為0以防止 Rigidbody 2D 自動下落。

選中約束下的 Z 以防止角色在碰撞時旋轉。

接下來,選擇要點擊的“TilemapObject”,然後從“添加元件”中選擇“Tilemap -> Tilemap Collider 2D”。

僅此而已。 你甚至不需要任何程式設計。 運行遊戲並嘗試擊中成為牆壁的物體。 我認為您可以確保它正確停止。

但是,當您真正擊中它時,我認為行為中會有關注點。 以下是一些解決方案:

使用地圖和解決方案進行命中檢測的不便行為

當你碰壁時,你可能會發現一些困擾你的事情。

如果你靠牆移動,你會被夾在中間

Box Collider 2D 我認為如果您使用物件,就會發生這種情況。

例如,從下面的場景中,當您按下左下角的鍵時,您希望它沿著牆壁向左移動。 但是,在取得一些進展之後,我認為它會卡在某物上並停止。

按位置識別牆壁上的凹痕

Circle Collider 2D 我認為如果您附上. 牆應該是平坦的,但是如果你把它靠在牆上,你會看到牆在移動,就好像它是不平坦的。

障礙和顛簸的原因和解決方案

發生這種情況的原因似乎是「命中確定是在地圖晶元的基礎上執行的」。 實際上,當您選擇TilemapObject時,命中檢測所在的位置會出現一條綠線,您可以看到這是以MapTip單位繪製的一條線。

因此,如果移動物體在一條正好相當於一個地圖晶元的線上,它將被判斷為用一個地圖晶元擊中。 如果在地圖晶元的邊界處碰撞,兩個地圖晶片會被擊中並判斷,因此反彈的強度會增加。

我認為解決此問題的最佳方法是將命中檢測與附加的地圖晶元相結合。 具體操作方法如下:

從檢查器中選擇Tilemap Collider 2D 具有命中檢測的“TilemapObject”,然後從 中選中“在複合中使用”。

如警告中所述,僅此一項不起作用,因此請從“添加元件”中選擇“物理 2D -> 複合碰撞體 2D”。

剛體 2D 與複合碰撞體 2D 一起添加。

這有點令人困惑,但我認為您可以確認具有命中檢測的地圖晶元之間邊界處的綠線已經消失。

我不希望磁貼移動,所以我將 Rigidbody 2D 元件正文類型保留為“靜態”。

現在運行遊戲並嘗試讓它移動。 我認為即使您沿牆壁對角線移動,它也不會被卡住,並且可以平穩移動而不會顛簸移動。

消除角色從牆上推回

你可以看到,如果你移動角色來推動牆壁,然後停止移動,它會表現得有點像從牆上反彈回來。

要解決此問題,Rigidbody 2D 請選擇字元物件並從元件中將「碰撞檢測」更改為「連續」。。

“不連續”和“連續”的區別如下。

不連續的

碰撞檢測是一種在移動後思考的機制。 它是一種從移動並嵌入牆壁的狀態執行碰撞檢測的形式。 如果將其與蹦床和橡膠聯繫起來很容易理解,但是嵌入的越多,力就會越強,反彈力也會越強。 相反,計算是在移動後進行的,因此處理成本低。

連續的

它在確定途中的內容時進行處理。 確定移動前後的位置之間是否有牆, 如果有一堵牆,它會判斷那裡的碰撞並停止,所以幾乎沒有排斥力。 相反,處理成本略有增加,因為計算包含在運動的中間。

被捕獲在地圖物件的一角

根據程式和位置的不同,有些被捕獲,有些沒有,原因沒有太大變化。 順便說一下,它發生在像 Box Collider 2D 這樣的角上,而不是圓圈。

即使發生這種神秘現象,對撞機的圓角也很好,以避免障礙。 它僅限於 Box Collider 2D,但要使其變圓,角色物件的 Box Collider 2D 元件具有“邊緣半徑”,您可以在其中放置一個值。 如果輸入 1 作為數字單位,則將對物件大小進行捨入。 這取決於大小,但最好放大約0.1。

順便說一下,命中判斷僅根據圓度的大小增加,因此如果很大,請進行調整。 Box Collider 2D 有一個 Collider Edit 按鈕,允許您通過按兩下該按鈕直接在檢視中調整其大小。 由於外綠線是實際的命中檢測,因此請設置大小,使其不會不自然。

之後,運行遊戲以確保它不會被划傷並進行調整。