Chapter 10-1. 생존킷 : 생존 킷 제작

Date:     Updated:

카테고리:

태그:

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

생존 킷 : 생존 킷 제작

🚀 컴퓨터 만들기

image

image

로켓 안에 들어가면 이렇게 컴퓨터를 할 수 있고, 컴퓨터로 원하는 아이템을 클릭하여 제작할 수 있다. 원하는 슬롯을 클릭하면 해당 아이템이 위의 굴뚝같은 곳에서 생성되어 떨어지게 된다.

image

  • 컴퓨터 오브젝트
    • 캔버스 (컴퓨터 모니터 화면을 나타낼 UI 캔버스)
      • 초록색 배경 이미지
        • 6 개의 슬롯
    • 아이템이 생성될 위치를 나타낼 빈 오브젝트 Item Appear Pos
      • 가운데 상단의 굴뚝같이 생긴 곳에서 아이템이 떨어지게끔 할 것이다.
      • 따라서 그 위치에 빈 오브젝트를 배치했고 이의 트랜스폼을 아이템 생성 위치로 사용할 것이다.

✈ 컴퓨터 오브젝트

image

컴퓨터에 필요한 컴포넌트들

  • Box Collider 2 개
    • 위에서 아이템이 생성되어 떨어질 때 땅바닥으로 떨어지지 않도록 콜라이더 2 개로 약간의 받침대 모양을 만들었다.
  • Audio Source
    • 슬롯 버튼을 누를 때, 아이템을 생성할 때 등등 효과음을 재생하기 위해서
    • Play On Awake 는 해제해준다.
  • 📜CoumputerKit.cs
    • 버튼을 누르면 아이템을 생성하고 그 아이템 제작에 필요했던 기존 보유 아이템들을 차감하고 효과음을 재생하고 등등 이런 일을 할 것이다.
    • 밑에 후술


✈ 컴퓨터 UI 만들기

Canvas - World Space

컴퓨터 화면으로 사용할 UI. 따라서 이 컴퓨터 모니터로 사용할 Canvas 의 Render Mode 를 World Space 로 해야 한다. 오브젝트로서 월드 상에 배치될 수 있는 UI Canvas 여야 하기 떄문에. 보통의 Canvas 상태인 Overlay 모드일 때는 카메라 화면 위에 덮어 씌워져 렌더링 되기 때문에 씬 상에 배치된 모든 3D 오브젝트들이 그려지고 난 후에 캔버스가 가장 나중에 그려지지만, 이 World Space 모드는 그런거 없다. 다른 씬 상의 오브젝트들과 같다. 캔버스의 크기는 컴퓨터 모니터 화면과 일치하게 scale 과 너비 높이를 조정하였다.

image

  • Order in Layer 값을 1 로 해준다.

  • Sort Layer
    • 같은 씬 내의 다른 Render 들과 비교했을 때의 캔버스의 렌더 순서를 관리한다.
      • Z 좌표와 관계없이 렌더링 순서를 제어 할 수 있게 된다.
    • Raycast 에 쓰는 그 Layer 와는 전혀 다르다!!
    • 같은 Sort Layer 끼리는 같은 Render 순서를 가진다.
    • 작은 값을 가지는 Sort Layer 에 속한 오브젝트들일 수록 먼저 그려지고, 큰 값을 가지는 SOrt Layer 에 속한 오브젝트일 수록 나중에 그려지기 떄문에 덮어 씌워져 그려지게 된다.
      • 즉, 레이어 목록에서 위에 있는 것일 수록 작은 값
  • Order in Layer
    • 동일한 Sort Layer 내에서의 순서! 마찬가지로 작은 값일 수록 같은 Sort Layer 에 속한 오브젝트들 중에서도 먼저 그려지고 큰 값이면 반대.
  • 위 사진을 예로 들자면 “default” 라는 이름의 Sort Layer 에 속한 오브젝트들 중에서도 0 번째, 즉 가장 먼저 그려짐.

image

Order in Layer 값을 0 으로 했을 때의 모습이다. 컴퓨터 오브젝트의 모니터 부분보다 렌더링 순서가 더 앞서 덮혀져 잘 안보이게 된다. 사실 잘 이해가 안됐던게.. 이 컴퓨터 오브젝트는 조립된게 아닌 전체적인 하나의 오브젝트일 뿐인데 왜 컴퓨터의 다른 부분들은 이 캔버스보다 렌더링이 앞서서 덮혀지는데 왜 유독 컴퓨터의 모니터부분만 캔버스보다 렌더링을 뒤에 해서 캔버스를 덮는걸까? 강의하신 분께서 이 컴퓨터 모델 에셋을 만드실 때 모니터 부분만 렌더링 우선순위에 조작을 가하신걸까? 그럴 수가 있나? Blender 도 미숙하고 3D 모델을 제대로 만들어 본 적이 없어서 잘 모르겠다.. 왜 컴퓨터의 오직 모니터부분만 저렇게 캔버스를 덮어서 렌더링이 되는걸까? 어렵다.. 혹시 이 글을 보고 계신 방문자분께서 이 이유데 대해 아신다면 꼭.. 댓글로 저도 좀 알려주세요 ㅠㅠ

image

Order in Layer 값을 1 로 해주니 캔버스가 잘 보이게 되었다. 이렇게 Order in layer 값을 높여줄 수록 렌더링이 가장 늦게 되어 가장 먼저 덮혀져 그려지므로 잘 보이게 된다. 씬 상의 다른 오브젝트들보다 이 캔버스의 렌더링 순서를 더 뒤로 밀어 주었다고 이해 하고 넘어가야 겠다. ㅠ


슬롯들

화면의 6 개의 이미지 슬롯에 버튼 이벤트를 달아준다. 이 버튼을 누르면 아이템이 생성되는 일을 하는 함수를 호출하도록 📜ComputerKit 에서 함수를 짤 것이다.


🚀 아이템 만들기

아이템 프리팹

image

컴퓨터에서 생성할 아이템이다. 아이템이라 작고 귀엽다. 컴퓨터에서 첫 번째 슬롯을 누르면 생성시킬 포션 조작대이다. 아이템화일 때 모습이기 때문에 작게 만들어 주었다. 나중에 이 아이템으로 실제로 배치할 땐 원래 크기로 배치할 것이다.

  • 필요한 컴포넌트
    • Box Collider
      • Collider 가 있어야 바닥을 안뚫는다.
    • Rigidbody
      • 중력이 있어야 컴퓨터에서 아이템을 생성했을 때 위에서 떨어질 수 있다.
      • 질량을 작게 0.01 로
    • 📜ItemPickUp 스크립트를 붙인다.
      • 아래에서 만들 Item을 할당해준다.
      • 이 스크립트가 붙어야 아이템으로서 역할을 할 수 있다. 주울 수 있고 또 아이템으로서 인식할 수 있다.
  • 태그와 레이어는 “Item” 으로 설정해준다.
    • 그래야 📜ActionController 에서 카메라를 통해 아이템으로 인식 할 수 있다.


Item

image

아이템 프리팹은 방금 위에서 만든 프리팹 할당


📜ComputerKit

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

[System.Serializable]
public class Kit  // 하나의 아이템이 담고 있는 정보
{
    public string kitName;
    public string kitDescription;
    public string[] needItemName;
    public int[] needItemNumber;
    public GameObject go_Kit_Prefab;
}

public class ComputerKit : MonoBehaviour
{
    [SerializeField]
    private Kit[] kits;  // 컴퓨터로 생성할 수 있는 아이템 배열

    [SerializeField]
    private Transform tf_ItemAppear; // 아이템 나오는 구멍의 트랜스폼 정보 (Item Appear Pos)

    private bool isCraft = false;  // 지금 제작 되는 중인지. false 일 때만 제작 가능하게 할 것.

    // 필요한 컴포넌트
    private Inventory theInventory; // 📜Inventory.cs

    private AudioSource theAudio;
    [SerializeField] private AudioClip sound_ButtonClick; // 버튼 클릭 사운드
    [SerializeField] private AudioClip sound_Beep; // 아이템 부족하여 키트 생성이 불가능할 때 사운드
    [SerializeField] private AudioClip sound_Activated; // 아이템 생성 소리
    [SerializeField] private AudioClip sound_Output;  // 아이템 나오는 소리

    void Start()
    {
        theInventory = FindObjectOfType<Inventory>();
        theAudio = GetComponent<AudioSource>();
    }

    private void PlaySE(AudioClip _clip) // 효과음 재생
    {
        theAudio.clip = _clip;
        theAudio.Play();
    }

    public void ClickButton(int _slotNumber) // 슬롯 버튼 클릭시 호출
    {
        PlaySE(sound_ButtonClick);  // 일단 버튼 클릭음 재생
        if(!isCraft)  // 현재 제작 중이 아니라면 제작 가능
        {
            if (!CheckIngredient(_slotNumber)) // 재료 있는지 체크
                return;

            isCraft = true; // 중복 실행 방지. 제작 중입니다.
            UseIngredient(_slotNumber); // 재료 사용(보유 아이템에서 제작에 쓰인 갯수만큼 차감)
            StartCoroutine(CraftCoroutine(_slotNumber)); // 키트 생성
        }
    }

    private bool CheckIngredient(int _slotNumber)
    {
        for (int i = 0; i < kits[_slotNumber].needItemName.Length; i++)
        {
            if (theInventory.GetItemCount(kits[_slotNumber].needItemName[i]) < kits[_slotNumber].needItemNumber[i])
            {
                PlaySE(sound_Beep);  // 아이템 제작 재료 모잘라서 생성할 수 없는 경우 경고음 재생
                return false;
            }
        }
        return true;
    }

    private void UseIngredient(int _slotNumber)
    {
        for (int i = 0; i < kits[_slotNumber].needItemName.Length; i++)
            theInventory.SetItemCount(kits[_slotNumber].needItemName[i], kits[_slotNumber].needItemNumber[i]);
    }

    IEnumerator CraftCoroutine(int _slotNumber) // 버튼 누르면 3 초 대기 후 아이템 생성
    {
        PlaySE(sound_Activated); // 아이템 생성 소리 재생
        yield return new WaitForSeconds(3f);
        PlaySE(sound_Output); // 아이템 빠져나오는 소리 재생 

        Instantiate(kits[_slotNumber].go_Kit_Prefab, tf_ItemAppear.position, Quaternion.identity); // 아이템 생성
        isCraft = false;  // 제작이 끝났으니 다시 false로
    }
}

CheckIngredient 함수와 UseIngredient 함수에 대한 원리는 9.4 : 건축 아이템 소모 포스트 참고

image

  • 아이템이 생성되는 곳으로서 지정해놓기 위해 만들었던 빈 오브젝트인 Item Appear Postf_ItemAppear에 ㅎ라당.
  • 일단 6개의 슬롯 중 하나만 해볼거라서 kits 배열의 사이즈는 우선 1로 (나중에 6 개 다 채워보는게 좋겠다.)
    • 포션 제작 도구를 제작하려면 “Twig” 아이템이 2 개 있어야..
  • 효과음들도 할당
  • 첫 번째 슬롯의 버튼 이벤트는 ClickButton(0) 호출, 두 번째 슬롯의 버튼 이벤트는 ClickButton(1) 호출등등 이런식으로 하게끔 모든 슬롯의 버튼 이벤트에 함수 연결.


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

맨 위로 이동하기

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

댓글 남기기