타일맵으로 적중 감지 구현
검증 환경
- 윈도우
-
- 윈도우 11
- Unity 에디터
-
- 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 타일맵 엑스트라가 포함된 맵팁도 충돌 감지가 가능하지만, 절차가 길기 때문에 이 글에서는 사용하지 않습니다.
MapTip의 원본 이미지를 준비하여 프로젝트에 추가합니다. 조작을 알기 쉽게 하기 위해, 맵 칩 소재에 대해 "걸을 수 있는 장소"와 "걸을 수 없는 장소"를 준비해 주세요.
인스펙터에서 MapChips에 대해 설정하고 적용 버튼을 클릭합니다. 구성이 완료되면 스프라이트 에디터(Sprite Editor) 를 엽니다.
32픽셀 맵팁이므로 32픽셀로 분할하겠습니다.
타일 팔레트 탭을 선택합니다. 그렇지 않은 경우 메뉴에서 "Window > 2D -> Tile Palette"로 표시하십시오. 새 팔레트를 만듭니다. 이름은 임의적이지만 지금은 "MapChipPalette"라고 부르겠습니다.
Scenes에서 MapChipPalette 폴더를 만들고 지정합니다.
맵팁을 팔레트로 끌어 추가합니다. 이전에 만든 MapChipPalette 폴더에 저장합니다.
지도 만들기
이번에는 맵 히트 판정이 "타일맵" 단위로 수행됩니다. 따라서 "히트 감지가 없는 타일맵"과 "히트 감지가 있는 타일맵"이라는 두 개의 타일맵을 생성합니다.
먼저 계층 구조에 두 개의 타일맵을 만듭니다. 그리드에서 두 개를 만들 수 있습니다. 명확성을 위해 이름은 "TilemapObeject" 및 "TilemapGround"입니다.
먼저 "TilemapGround"를 만듭니다. 움직일 수있는 범위이기 때문에 간단히 땅을 눕힐 수 있습니다. 지상에 있으면 패턴을 변경할 수 있습니다.
덧붙여서 캐릭터가 숨겨져 있으면 캐릭터 객체를 선택하고 인스펙터의 Sprite Renderer
레이어 순서를 2로 설정합니다.
레이어의 순서는 기본적으로 0이고 타일맵은 0이므로 이 값 이상으로 늘리면 전경에 표시됩니다.
그런 다음 TilemapObject를 선택하고 움직이지 않게 만들려는 맵 팁을 배치합니다. 먼저 레이어 순서를 1로 설정합니다. 이것은 땅 앞에 나타나게 하기 위한 것입니다.
이것은 당신이 땅을 숨기는 것처럼 보입니다.
물론 이 시점에서는 충돌 감지와 관련된 설정이 없기 때문에 정상적으로 고지대를 주행할 수 있습니다. 그런 다음 충돌 감지를 설정합니다.
충돌 감지 설정
먼저 캐릭터를 설정해 보겠습니다. 이 설정은 아래 팁과 거의 동일하므로 자세한 내용은 건너 뛰고 절차를 간략하게 설명하겠습니다.
계층 구조에서 캐릭터 오브젝트를 선택하고 컴포넌트 추가(Add Component)에서 피직스 2D -> 서클 콜라이더 2D(Physics 2D - Circle Collider 2D) 를 선택합니다. 오브젝트의 모양이 직사각형이라면 "Box Collider 2D"가 좋습니다.
마찬가지로 "Physics 2D -> Rigidbody 2D"를 추가합니다.
자동 낙하를 방지하기 Rigidbody 2D
위해 중력 눈금을 0으로 설정합니다.
제약 조건(Constraints)에서 Z를 선택하여 충돌 시 스프라이트가 회전하지 않도록 합니다.
그런 다음 누르려는 "TilemapObject"를 선택하고 "Add Component"에서 "Tilemap -> Tilemap Collider 2D"를 선택합니다.
그게 전부입니다. 프로그래밍이 필요하지 않습니다. 게임을 실행하고 벽이 되는 물체를 치십시오. 제대로 멈출 수 있다고 생각합니다.
그러나 실제로 부딪쳤을 때 행동에 우려되는 점이 있다고 생각합니다. 다음은 몇 가지 솔루션입니다.
지도와 솔루션을 사용한 적중 감지의 불편한 동작Inconvenient behavior of the hit detection with the map and solutions
벽에 부딪히면 당신을 괴롭히는 몇 가지 사항을 발견할 수 있습니다.
벽에 부딪히면 중간에 끼게 됩니다
Box Collider 2D
나는 당신이 물건을 사용하고 있다면 일어날 것이라고 생각합니다.
예를 들어, 아래 장면에서 왼쪽 하단의 키를 누르면 벽을 따라 왼쪽으로 이동하기를 원합니다. 그러나 약간의 진전이 있으면 무언가에 갇혀 멈출 것이라고 생각합니다.
위치별로 벽의 움푹 들어간 곳 인식
Circle Collider 2D
붙이면 알기 쉽다고 생각합니다.
벽은 평평해야 하지만 벽에 대고 움직이면 벽이 고르지 않은 것처럼 움직이는 것을 볼 수 있습니다.
걸림돌과 충돌의 원인과 해결책
이러한 현상이 발생하는 이유는 "히트 판정이 맵칩 기반으로 수행되기 때문"인 것 같습니다. 실제로 TilemapObject를 선택하면 적중 횟수 감지가 있는 위치에 녹색 선이 나타나며, 이 선이 MapTip 단위로 그려진 것을 볼 수 있습니다.
따라서 움직이는 물체가 정확히 하나의 맵 칩에 해당하는 선상에 있다면 하나의 맵 칩으로 히트로 판단됩니다. 맵 칩의 경계에서 충돌하면 맵 칩 2개가 맞아 판정되기 때문에 바운스의 강도가 높아집니다.
이 문제를 해결하는 가장 좋은 방법은 히트 감지와 첨부 된 맵 칩을 결합하는 것입니다. 방법은 다음과 같습니다.
인스펙터에서 히트 감지 기능이 있는 "TilemapObject"를 선택하고Tilemap Collider 2D
에서 "Use in composite"를 선택합니다.
경고에서 언급했듯이 이것만으로는 효과가 없으므로 "Add Component"에서 "Physics 2D -> Composite Collider 2D"를 선택하십시오.
Composite Collider 2D와 함께 Rigidbody 2D가 추가되었습니다.
조금 헷갈리긴 한데, 히트 디텍션이 있는 맵칩의 경계에 있는 초록색 선이 사라진 것을 확인할 수 있을 것 같습니다.
타일맵이 이동하는 것을 원하지 않으므로 구성 요소 본문 유형을 "정적"으로 두겠습니다 Rigidbody 2D
.
이제 게임을 실행하고 움직이십시오. 벽을 따라 대각선으로 움직여도 들키지 않고 울퉁불퉁 한 움직임없이 부드럽게 움직일 수 있다고 생각합니다.
벽에서 캐릭터가 뒤로 밀려나는 것을 제거합니다.
캐릭터를 움직여 벽을 밀고 움직임을 멈추면 벽에서 튕겨 나온 것처럼 행동하는 것을 볼 수 있습니다.
이Rigidbody 2D
문제를 해결하려면 캐릭터 개체를 선택하고 구성 요소에서 "충돌 감지"를 "연속"으로 변경합니다.
"불연속"과 "연속"의 차이점은 다음과 같습니다.
불연속
충돌 감지는 이동 후 생각하는 메커니즘입니다. 벽에 옮겨져 박힌 상태에서 충돌 감지를 수행하는 형태입니다. 트램폴린이나 고무와 연관시키면 알기 쉽지만, 매립하면 할수록 반발력이 높아지고, 바운스가 강해집니다. 대신 이사 후 계산이 수행되므로 처리 비용이 저렴합니다.
지속적
진행 중인 작업을 결정하면서 처리됩니다. 이동 전후의 위치 사이에 벽이 있는지 확인합니다. 벽이 있으면 충돌을 판단하고 멈추기 때문에 반발력이 거의 없습니다. 대신 계산이 이동 중간에 포함되기 때문에 처리 비용이 약간 증가합니다.
맵 개체의 모퉁이에 잡혔습니다.
프로그램이나 장소에 따라 잡히는 것도 있고 잡히지 않는 것도 있고, 원인도 크게 바뀌지 않고 있습니다. 그건 그렇고, 둥근 원이 아닌 Box Collider 2D와 같은 각진 모서리에서 발생합니다.
이러한 신비한 현상이 발생하더라도 걸림돌을 피하기 위해 충돌기의 모서리를 둥글게 만드는 것이 좋습니다. Box Collider 2D로 제한되어 있지만, 이를 둥글게 만들기 위해 캐릭터 오브젝트의 Box Collider 2D 컴포넌트에 "가장자리 반경"이 있고 거기에 값을 입력합니다. 숫자 단위로 1을 입력하면 객체 크기에 대해 반올림이 발생합니다. 크기에 따라 다르지만 0.1 정도를 넣는 것이 좋습니다.
덧붙여서 명중 판정은 둥글기의 크기에 의해서만 증가하기 때문에, 크면 조정해 주세요. Box Collider 2D에는 콜라이더 편집(Collider Edit) 버튼이 있으며, 이 버튼을 클릭하여 뷰에서 직접 크기를 조정할 수 있습니다. 바깥쪽 녹색 선이 실제 적중 감지이므로 부자연스럽지 않도록 크기를 설정합니다.
그런 다음 게임을 실행하여 긁히지 않았는지 확인하고 조정하십시오.