유니티 바닥 지뢰 코드

유니티 바닥 지뢰 코드 밟으면 터지는 함정, 제대로 만들기

게임 속에서 긴장감 넘치는 순간을 연출하는 데 지뢰만큼 효과적인 장치가 또 있을까요? 플레이어의 예상치 못한 발걸음 하나로 게임의 흐름이 완전히 뒤바뀌는 짜릿한 경험은 게임의 몰입도를 끌어올립니다. 이 글에서는 단순히 폭발하는 지뢰를 넘어, 플레이어를 감지하고 경고 신호를 보낸 뒤 폭발하며 주변에 피해를 입히는 지능적인 바닥 지뢰 시스템을 유니티 스크립트로 구현하는 방법을 단계별로 소개합니다.


1. 지뢰 스크립트 작성

Landmine.cs라는 이름의 C# 스크립트를 새로 만들고 아래 코드를 입력해 주세요. 이 스크립트는 지뢰의 생명 주기(감지, 폭발)를 모두 관리합니다.

C#

using UnityEngine;
using System.Collections;

// 지뢰의 현재 상태를 관리하기 위한 enum
public enum MineState
{
    Dormant,    // 비활성 (위험하지 않은 상태)
    Triggered,  // 감지됨 (폭발 대기 중)
    Detonating  // 폭발 중
}

public class Landmine : MonoBehaviour
{
    [Header("지뢰 설정")]
    public GameObject explosionPrefab; // 폭발 효과 프리팹
    public float damage = 50f; // 폭발 시 입히는 데미지
    public float detonationDelay = 1.5f; // 감지 후 폭발까지의 지연 시간
    public float explosionRadius = 5f; // 폭발 범위
    public float detectionRadius = 2f; // 감지 트리거 범위

    [Header("시각/청각 효과")]
    public Light warningLight; // 폭발 대기 시 깜빡이는 경고등
    public AudioClip warningSound; // 폭발 대기 시 재생할 경고음
    public AudioClip explosionSound; // 폭발 시 재생할 사운드

    private MineState currentState = MineState.Dormant;
    private AudioSource audioSource;

    void Awake()
    {
        audioSource = GetComponent<AudioSource>();
        // 지뢰 오브젝트에 SphereCollider가 있을 경우 감지 범위로 설정
        SphereCollider detectionTrigger = GetComponent<SphereCollider>();
        if (detectionTrigger != null)
        {
            detectionTrigger.isTrigger = true;
            detectionTrigger.radius = detectionRadius;
        }

        // 경고등이 있다면 초기에 비활성화
        if (warningLight != null)
        {
            warningLight.enabled = false;
        }
    }

    void OnTriggerEnter(Collider other)
    {
        // 지뢰가 비활성 상태이고 "Player" 태그를 가진 오브젝트가 감지되면
        if (currentState == MineState.Dormant && other.CompareTag("Player"))
        {
            currentState = MineState.Triggered;
            
            // 폭발 딜레이 코루틴 시작
            StartCoroutine(ActivateAndDetonate());
        }
    }

    private IEnumerator ActivateAndDetonate()
    {
        // 경고등이 있다면 깜빡이는 효과를 시작
        if (warningLight != null)
        {
            warningLight.enabled = true;
        }
        
        // 경고음 재생
        if (audioSource != null && warningSound != null)
        {
            audioSource.PlayOneShot(warningSound);
        }

        // 설정된 시간만큼 기다립니다.
        yield return new WaitForSeconds(detonationDelay);

        currentState = MineState.Detonating;
        Explode();
    }

    private void Explode()
    {
        // 폭발 효과 프리팹 생성
        if (explosionPrefab != null)
        {
            Instantiate(explosionPrefab, transform.position, Quaternion.identity);
        }

        // 폭발 사운드 재생
        if (audioSource != null && explosionSound != null)
        {
            audioSource.PlayOneShot(explosionSound);
        }

        // 폭발 범위 내의 모든 오브젝트를 감지합니다.
        Collider[] colliders = Physics.OverlapSphere(transform.position, explosionRadius);
        foreach (Collider hit in colliders)
        {
            // PlayerHealth 스크립트를 찾아 데미지 적용
            PlayerHealth playerHealth = hit.GetComponent<PlayerHealth>();
            if (playerHealth != null)
            {
                playerHealth.TakeDamage(damage);
            }
        }
        
        // 지뢰 오브젝트를 파괴합니다.
        Destroy(gameObject, 0.5f); // 효과음을 재생할 시간을 주기 위해 0.5초 지연
    }
    
    // 유니티 에디터에서 감지 및 폭발 범위를 시각적으로 확인하기 위한 함수
    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere(transform.position, detectionRadius);
        
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, explosionRadius);
    }
}

2. 플레이어 체력 스크립트 작성

지뢰의 폭발 데미지를 받을 플레이어에게 부착할 스크립트입니다. PlayerHealth.cs라는 이름으로 만드세요.

C#

using UnityEngine;

public class PlayerHealth : MonoBehaviour
{
    public float currentHealth = 100f;

    public void TakeDamage(float amount)
    {
        currentHealth -= amount;
        Debug.Log("플레이어가 데미지를 입었습니다. 남은 체력: " + currentHealth);

        if (currentHealth <= 0)
        {
            Debug.Log("플레이어 사망!");
            // 게임오버 로직을 여기에 추가합니다.
        }
    }
}

3. 유니티 에디터 설정 및 코드 해설

  1. 지뢰 프리팹 제작:
    • 지뢰로 사용할 오브젝트를 만들고 Landmine.cs 스크립트를 부착합니다.
    • **Sphere Collider**를 추가하고 **Is Trigger**를 체크합니다. 이 컴포넌트가 지뢰의 감지 범위 역할을 합니다.
    • AudioSource 컴포넌트를 추가하고 Landmine 스크립트의 AudioClip 변수에 경고음, 폭발음 에셋을 연결합니다.
    • 폭발 효과를 위한 파티클 시스템을 만들고 Explosion Prefab으로 연결합니다.
  2. 플레이어 설정:
    • 플레이어 오브젝트에 PlayerHealth.cs 스크립트를 부착합니다.
    • **Rigidbody**와 **Collider**를 추가하고, 오브젝트의 태그를 **”Player”**로 설정합니다.
  3. 지뢰의 상태 관리:
    • enum을 이용한 상태 관리는 지뢰가 현재 어떤 행동을 하고 있는지 명확히 파악하게 해줍니다. Dormant 상태일 때만 OnTriggerEnter가 작동하도록 해, 이미 활성화된 지뢰가 중복으로 감지되는 것을 방지합니다.
  4. IEnumerator와 코루틴: ActivateAndDetonate() 코루틴은 지뢰가 감지된 순간부터 폭발까지의 시간 차이를 비동기적으로 처리합니다. 덕분에 폭발 딜레이 시간 동안 경고 사운드나 깜빡이는 효과를 자연스럽게 연출할 수 있습니다.
  5. Physics.OverlapSphere(): 이 함수는 특정 위치를 중심으로 한 가상의 구체 안에 들어온 모든 **Collider**를 배열 형태로 반환합니다. 지뢰의 폭발 범위 내에 있는 모든 대상에게 일괄적으로 피해를 줄 때 매우 유용합니다.

이제 플레이어가 지뢰에 다가가면 지뢰가 활성화되고, 잠시 후 폭발하여 데미지를 입히는 것을 확인할 수 있습니다. OnDrawGizmosSelected() 덕분에 씬 뷰에서 지뢰를 클릭하면 감지 범위와 폭발 범위가 시각적으로 표시되어 디버깅에 큰 도움이 될 것입니다. 이 기본 코드를 기반으로 지뢰가 다른 오브젝트에도 데미지를 주거나, 폭발 시 주변 물체를 밀어내는 물리 효과를 추가하여 더욱 흥미로운 함정을 만들어보세요.

댓글 남기기