Menu
CoddyTech

바닥에 서 있기

Coddy Unity 여정의 물리와 게임플레이 섹션에 포함된 레슨. 71개 중 11번째.

모든 접촉에는 법선이 있습니다. 법선은 길이가 1인 방향 벡터로, 접촉한 표면에 수직이며 표면에서 멀어져 당신의 오브젝트를 향합니다. collision.GetContact(0)은 첫 번째 접촉 지점이고, normal은 어느 쪽에 닿았는지 알려줍니다. 평평한 땅 위에 서 있으면 법선은 (0, 1, 0)이고, 오른쪽 벽에 닿으면 (-1, 0, 0)이며, 천장에 머리를 부딪치면 (0, -1, 0)입니다.

이 상자는 착지와 옆면에 부딪히는 경우를 구분합니다.

void OnCollisionEnter(Collision collision)
{
    Vector3 normal = collision.GetContact(0).normal;
    if (normal.y > 0.5f)
    {
        Debug.Log("Landed on " + collision.gameObject.name);
    }
    else
    {
        Debug.Log("Bumped the side of " + collision.gameObject.name);
    }
}

검사에 정확히 1이 아니라 normal.y > 0.5f를 사용하는 이유는 경사면도 지면으로 처리하기 위해서입니다. 60도 경사면에서 y는 0.5이며, 이는 사람이 걸어 올라가는 경사보다 더 가파릅니다. 지속되는 접촉을 처리하는 데 도움이 되는 메시지가 두 가지 더 있습니다. 접촉이 지속되는 동안 OnCollisionStay는 매 물리 단계마다 실행되고, 접촉이 끝날 때는 OnCollisionExit가 한 번 실행됩니다. 접촉이 끝나면 더 이상 아무것도 닿아 있지 않으므로 접촉 지점이 없습니다. 따라서 그때는 GetContact를 호출하지 마세요.

challenge icon

챌린지

쉬움

플레이어가 무언가 위에 서 있을 때만 점프하게 하세요.

  1. private bool grounded;를 추가하세요. OnCollisionStay에서 collision.GetContact(0).normal.y > 0.5f일 때 true로 설정하고, OnCollisionExit에서는 false로 설정하세요.
  2. FixedUpdate()에서 if (jumpPressed && grounded)일 때만 점프하고, 공중에서 입력한 점프가 무시되도록 해당 if 뒤에 jumpPressed = false;를 설정하세요.

‘플레이’를 누르고 이중 점프를 시도해 보세요. 두 번째 입력은 아무 효과도 없습니다. 그런 다음 ‘확인’을 누르세요.

직접 해보기

using UnityEngine;

public class Hopper : MonoBehaviour
{
    public float speed = 4f;
    public float jump = 6f;
    private Rigidbody rb;
    private bool jumpPressed;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            jumpPressed = true;
        }
    }

    void FixedUpdate()
    {
        float h = Input.GetAxisRaw("Horizontal");
        rb.linearVelocity = new Vector3(h * speed, rb.linearVelocity.y, 0);
        if (jumpPressed)
        {
            rb.AddForce(Vector3.up * jump, ForceMode.Impulse);
            jumpPressed = false;
        }
    }
}

물리와 게임플레이의 모든 레슨

직접 연습해 보세요: Unity 플레이그라운드