Chapter 12-1. 기타 : 트랩 만들기

Date:     Updated:

카테고리:

태그:

인프런에 있는 케이디님의 [유니티 3D] 실전! 생존게임 만들기 - Advanced 강의를 듣고 정리한 필기입니다. 😀
🌜 강의 들으러 가기 Click

🚀 단순한 트랩 만들기

트랩 오브젝트

image

image

이 3 가지 오브젝트를 조합해서 트랩을 만든다. Rigidbody 를 붙여줄 때 중력과 물리를 꺼준다. 고기에 Trigger 충돌이 발동하면 나무와 나뭇가지의 중력과 물리를 활성화하여 쓰러지게 할 것이다.

  • 네모 나무, 나뭇가지
    • Box Collider
    • Rigidbody (Use Gravity 해제, Is Kinematic 체크)
  • 전체 SimpleTrap 부모 오브젝트에게 Box Collider 붙이고 Is Trigger체크. 고기 쪽에 붙인다.
    • 레이어는 “Building”
    • AudioSource 를 붙인다.
    • 📜SimpleTrap 이 붙을 것


📜SimpleTrap

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

public class SimpleTrap : MonoBehaviour
{
    private Rigidbody[] rigid; // Twig, Board 의 Rigidbody 가지고 올 것
    [SerializeField] private GameObject go_Meat;  // 트랩에 걸리면 고기가 사라지게
    [SerializeField] private int damage; // 플레이어에게 입힐 데미지

    private bool isActivated = false; // 트랩이 발동되면 true

    private AudioSource theAudio;
    [SerializeField] private AudioClip sound_Activate; // 트랩 발동 사운드

    void Start()
    {
        rigid = GetComponentsInChildren<Rigidbody>();
        theAudio = GetComponent<AudioSource>();
    }

    private void OnTriggerEnter(Collider other)
    {
        if (!isActivated)
        {
            if (other.transform.tag != "Untagged")
            {
                isActivated = true;
                theAudio.clip = sound_Activate;
                theAudio.Play();

                Destroy(go_Meat);

                for (int i = 0; i < rigid.Length; i++)
                {
                    rigid[i].useGravity = true;
                    rigid[i].isKinematic = false;
                }

                if (other.transform.name == "Player")
                    other.transform.GetComponent<StatusController>().DecreaseHP(damage);
            }
        }
    }
}

  • Terrain 의 태그는 “Untagged”이다. 이 태그가 아닌 플레이어, 동물AI 등등 모든 것이 닿으면
    • 트랩 사운드 재생
    • 고기 없애기
    • Twig와 Board의 중력, 물리 활성화하여 넘어지게 하기
    • 플레이어의 데미지 입히기

image

플레이어가 고기에 닿으면 트랩의 중력과 물리가 발동하여 무너지게 되고 플레이어의 체력이 깎이게 된다.


🚀 좀 더 심화적인 트랩 만들기

✈ 트랩 오브젝트

image

image

가장 밑에있는 나뭇 가지에 플레이어가 닿으면 연필 같이 생긴 나무가 떨어지고 이 나무에 맞으면 데미지를 입게 할 것이다! 데미지는 지속 데미지는 아니고 딱 한번만 입는다.

  • 부모 DeadTrap
    • 태그 “Trap”, 레이어 “Building”
    • 📜DeapTrap 불일 것
    • Box Collider 2 개 (📜DeamTrap 에서 가져올 것)
      • 하나는 가운데
        • 메인 카메라의 Raycast 충돌을 받아 액션 텍스트 띄울 것
      • 다른 하나는 얇은 나뭇 가지 있는 바닥
        • 이 곳에 겹치면 트랩이 발동하게 할것
          • IsTrigger 체크
        • 메인 카메라의 Raycast 충돌을 받아 액션 텍스트 띄울 것
    • Animator
    • Audio Source
  • 플레이어가 부딪치면 관통 안되고 밀려날 수 있도록 모든 자식 오브젝트들에게 Box Collider 붙여주기
    • 단, 플레이어가 맞아서 데미지를 입힐 저 연필 모양의 나무(WoodWall)는 IsTrigger가 체크된 Box Collider 를 한번 기존 Box Collider 바깥에 입혀지도록 하나 더 추가해준다.
    • 📜TrapDamage 붙일 것
      • OnTriggerEnter 이벤트시 플레이어에게 데미지 입히는 처리
    • Rigidbody
      • 플레이어가 맞으면 튕겨나가도록 질량을 1000으로 무겁게
      • 중력 끄고 물리 처리 끄고


✈ 트랩 애니메이션

트랩 애니메이션 클립

트랩이 활성화 될 때

image

  • “DeadTrap_Activate” 애니메이션 클립
    • 트랩이 활성화되면 다음과 같은 애니메이션이 재생될 수 있도록 녹화하여 키들을 만들었다.
트랩이 비활성화 상태일 떄

image

  • “DeadTrap_Deactivate” 애니메이션 클립
    • 그냥 정지해있을 때.


트랩 애니메이션 컨트롤러

image

  • DeadTrap의 Animator 컴포넌트의 컨트롤러에 할당해준다.
  • Trigger 파라미터를 위와 같이 추가해준다.
  • 각 Trigger가 발동할 때 해당 Transition이 일어나도록 한다.
    • Has Exit Time 은 체크 해제. 그냥 애니메이션 재생이 끝나면 즉각 끝내도록!


✈ 트랩 작동시키기

📜DeadTrap

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

public class DeadTrap : MonoBehaviour
{
    private Animator anim;
    private AudioSource theAudio;

    private bool isActivated = false;

    [SerializeField] private AudioClip sound_Activate;
    [SerializeField] private TrapDamage theTrapDamage;

    void Start()
    {
        anim = GetComponent<Animator>();
        theAudio = GetComponent<AudioSource>();
    }

    private void OnTriggerEnter(Collider other)
    {
        if (!isActivated)
        {
            if (other.transform.tag != "Untagged" && other.transform.tag != "Trap")
            {
                StartCoroutine(theTrapDamage.ActivatedTrapCoroutine());
                isActivated = true;
                anim.SetTrigger("Activate");
                theAudio.clip = sound_Activate;
                theAudio.Play();
            }
        }
    }
}

DeadTrap에 붙는다. 아랫 나뭇 가지를 밟으면 트랩을 작동시킨다.

  • OnTriggerEnter
    • DeadTrap의 Box Collider 중 하나인 얇은 나뭇가지 부분! 그 부분은 Is Trigger가 체크되어 있으며, 그 부분을 밟으면 트랩이 작동되게 할 것이다.
      • 밟은 대상이 지형이 아니고(“Untagged”) 자기 자신이 아니라면(“Trap”)
        • 밑에 후술할 📜TrapDamage 의 ActivatedTrapCoroutine 실행하여 데미지 입히는 처리
          • isActivated true로 해야 데미지를 입을 수 있다.
        • 트랩 애니메이션 재생
        • 트랩 활성 효과음 재생

image

📜TrapDamage 가 붙어있는 WoodWall 활당.


📜TrapDamage

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

public class TrapDamage : MonoBehaviour
{
    [SerializeField] private int damage;
    [SerializeField] private float finishTime;

    private bool isHurt = false; // false 일 때만 데미지 입게
    private bool isActivated = false;

    public IEnumerator ActivatedTrapCoroutine()
    {
        isActivated = true;

        yield return new WaitForSeconds(finishTime);
        isActivated = false;
        isHurt = false;
    }

    private void OnTriggerEnter(Collider other)
    {
        if (isActivated)
        {
            if (!isHurt)
            {
                isHurt = true;

                if (other.transform.name == "Player")
                    other.transform.GetComponent<StatusController>().DecreaseHP(damage);
            }
        }
    }
}

WoodWall에 붙는다. 움직이는 이 오브젝트와 충돌이 일어나야만 데미지를 입게 할 것이다.

  • 트랩이 활성화되면 📜DeadTrap에서 ActivatedTrapCoroutine을 실행하여 isActivated가 True가 된다. 그리고 finishTime 이 시간동안 대기를 한 후 다시 isActivated을 False로 만든다.
    • 따라서 이렇게 트랩이 활성화 된 후 finishTime 이 시간동안에만 WoodWall와 충돌 OnTriggerEnter 이 일어날 때 데미지를 입을 수 있게 된다.
    • 그리고 isHurt를 통해 finishTime시간 당 1 회만 입을 수 있다.
    • 코루틴 함수는 병렬적으로 실행이 되기 떄문에 ActivatedTrapCoroutine 실행 중에, 즉 대기 시간을 기다리는 중에 OnTriggerEnter 가 실행 될 수 있다.
  • 플레이어의 데미지 깎기

image


✈ 트랩의 작동이 끝나고나면 재설치

📜DeadTrap

    public bool GetIsActivated()
    {
        return isActivated;
    }

    public void ReInstall()
    {
        isActivated = false;
        anim.SetTrigger("Deactivate");
    }

재설치 할 수 있도록 함수 만듬. “Deactivate” 애니메이션 재생. 단, 재설치는 isActivated가 True 인 상태에서만 이루어져야 한다.


📜ActionController

    private void TryAction()
    {
        if(Input.GetKeyDown(KeyCode.E))
        {
            CheckAction();
            CanPickUp();
            CanMeat();
            CanDropFire();
            CanComputerPowerOn();
            CanArchemyTableOpen();
            CanReInstallTrap();
        }
    }
    
    private void CheckAction()
    {
        if (Physics.Raycast(transform.position, transform.forward, out hitInfo, range, layerMask))
        {
            if (hitInfo.transform.tag == "Item")
                ItemInfoAppear();
            else if (hitInfo.transform.tag == "Weak_Animal")
                MeatInfoAppear();
            else if (hitInfo.transform.tag == "Fire")
                FireInfoAppear();
            else if (hitInfo.transform.tag == "Computer")
                ComputerInfoAppear();
            else if (hitInfo.transform.tag == "ArchemyTable")
                ArchemyInfoAppear();
            else if (hitInfo.transform.tag == "Trap")
                TrapInfoAppear();
            else
                InfoDisappear();
        }
        else
            InfoDisappear();
    }

    private void TrapInfoAppear()
    {
        if (hitInfo.transform.GetComponent<DeadTrap>().GetIsActivated())
        {
            Reset();
            lookActivatedTrap = true;
            actionText.gameObject.SetActive(true);
            actionText.text = "함정 재설치 " + "<color=yellow>" + "(E)" + "</color>";
        }
    }

    private void InfoDisappear()
    {
        pickupActivated = false;
        dissolveActivated = false;
        firedLookActivated = false;
        lookComputer = false;
        lookArchemyTable = false;
        lookActivatedTrap = false;
        actionText.gameObject.SetActive(false);
    }

    private void CanReInstallTrap()
    {
        if (lookActivatedTrap)
        {
            if (hitInfo.transform != null)
            {
                hitInfo.transform.GetComponent<DeadTrap>().ReInstall();
                InfoDisappear();
            }
        }
    }

트랩 활성화 후 DeadTrap(레이어 “Building”이며 layerMask에는 이 레이어가 등록 되어 있음)의 Box Collider 를 쳐다보면 액션 텍스트 활성화, 그리고나서 E 누르면 재설치 하게끔.



🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기

Unity Lesson 3 카테고리 내 다른 글 보러가기

댓글 남기기