새소식

🎮 Game Dev (게임개발)/PC (데스크탑, 노트북, 터치패널)

[3D 액션게임] 15. 상점 만들기

  • -

🔔 유튜브 크리에이터 골든메탈님의 유니티강의 3D 쿼터뷰 액션게임 [BE5] 를 보고 공부하여 작성한 게시글입니다! 🔔

 

 

🧷 1. 상점 오브젝트

- 기본 배치

  • Item, Weapon Shop // 그룹 오브젝트
    • Table // 테이블
    • Goods Group // 테이블 위 아이템
      • 체력, 총알, 무기들 등등
    • Zone // 도넛형 시각적 이펙트로, 위에 있으면 E키를 통해 상점과 상호작용 할 수 있습니다.
    • Luna, Ludo // 상점 NPC
    • Spqwn Pos A,B,C // 아이템을 사면, 스폰 될 위치입니다.

 

- 테이블 배치

  • Cube 오브젝트를 적당한 크기로 만든 후, 에셋의 Textures의 Pattern을 입혔습니다.
  • Material의 Tiling을 통하여, 적당한 테이블의 모양으로 만듭니다.

- 물건 배치

  • 에셋의 프리팹 상점물건들을 Goods Group안 컴포넌트로 추가 후, 알맞게 배치해줍니다.

- 상호 작용 Zone 배치

  • Zone 위에 올라가서 상호작용 키인 'e'를 누르면, 상점 UI가 켜질 곳입니다.
  • Particle의 Donut Shape을 통해 파티클을 만들어줍니다.
    • Shape의 Mode - Loop로 돌아가는 파티클을 형성해줍니다.
    • Renderer의 Materal은 Defualt-Line으로 해줍시다.
  • 이후에 Shop이라는 스크립트를 통하여, 플레이어와 상점 상호작용을 해줄 예정입니다.
  • Sphere Collider을 트리거 체크 후, 배치합니다.

- 상점 NPC 배치 및 애니메이션

  • 에셋의 프리팹에서 Luna 혹은 Ludo라는 Npc 프리팹을 가져와 적당한 위치에 배치합니다.
  • 자식오브젝트 Mesh Object에 애니메이션 컨트롤러를 만들어 배치해줍니다.
  • 애니메이션은 Idle, Hello라는 애니메이션만 넣어줍니다. 이후 변수로 "doHello"란 트리거를 넣었습니다. (Hello 애니메이션의 트랜잭션에 연결시켜줍니다.)

  • 이후 Zone의 태그도 Shop으로 바꿔줍시다. (상호작용 태그로 할 수 있게끔)

 

- 아이템 스폰 장소

  • 상점에서 물건을 사면, 아이템을 스폰할 장소를 빈 오브젝트를 통해 위치를 선정해줍니다.

 

- 똑같이 위 과정을 통해, 무기 상점도 배치해 줍시다.

  • 복사 붙혀넣기해서 비슷하게 배치해주었습니다.

🧷 2. 상점 UI 제작

- UI 기본 배치도

  • Item or Weapon Shop Group // 그룹오브젝트 Image는 Sprites의 Panel A사용
    • Item Button A,B,C // 클릭 시 , 해당 아이템이 사집니다. 한개 배치후 복사 붙혀넣기로 배치하면 더 편합니다. Image는 Sprites의 Panel A를 사용합니다. 
      • Item Image // 에셋의 Sprites에 있습니다.
      • Item Text // 쿠키런 font 사용
      • Coin Image
      • Coin Text
    • Exit Button // 상점 UI에서 나갈 버튼
    • Portrait Image // Npc 초상화
    • Character Text // Npc가 하는 텍스트

- Group 위치

  • 기본적으로 만들어둔 Game Panel의 위치 밖에 만들어둡니다.

 

🧷 3. 상점 기능 스크립트

-   Shop 스크립트 (상호작용 영역인 Zone에 위치)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Shop : MonoBehaviour
{
    public RectTransform uiGroup;
    public Animator anim;

    public GameObject[] itemObj;
    public int[] itemPrice;
    public Transform[] itemPos;
    public string[] talkData;
    public Text talkText;

    Player enterPlayer;

    public void Enter(Player player)
    {
        enterPlayer = player;
        uiGroup.anchoredPosition = Vector3.zero;
    }

    
    public void Exit()
    {
        anim.SetTrigger("doHello");
        uiGroup.anchoredPosition = Vector3.down * 1000;
    }

    public void Buy(int index)
    {
        int price = itemPrice[index];
        if(price > enterPlayer.coin){
            StopCoroutine(Talk());
            StartCoroutine(Talk());
            return;
        }

        enterPlayer.coin -= price;
        Vector3 ranVec = Vector3.right * Random.Range(-3, 3)
                          + Vector3.forward * Random.Range(-3, 3);

        Instantiate(itemObj[index], itemPos[index].position + ranVec, itemPos[index].rotation);
    }

    IEnumerator Talk()
    {
        talkText.text = talkData[1];
        yield return new WaitForSeconds(2f);
        talkText.text = talkData[0];
    }
}

변수

  • RectTransform uiGroup : 상점 UI Group 오브젝트를 담습니다.
  • Animator anim : 애니메이션을 연결 합니다.
  • GameObject[] itemObj : 아이템, 혹은 무기들의 프리팹을 넣어줄 오브젝트 배열입니다.
  • int[] itemPrice : 아이템 가격입니다.
  • Transform[] itemPos : 아이템 스폰 위치입니다.
  • string[] talkData : npc의 text를 담을 배열입니다.
  • Text talkText : UI의 npc 텍스트 오브젝트입니다.
  • Player enterPlayer : 상호작용하는 플레이어의 오브젝트 변수입니다.

함수

  • Enter() : 상점 UI을 띄워줍니다.
  • Exit() : 상점 UI를 내려줍니다. 또한 애니메이션 트리거를 실행시켜줍니다.
  • Buy() : 버튼 누르고 돈을 가지고 있다면, 아이템을 사서 스폰 시켜줍니다.
  • Talk() : 돈이 없을 시, NPC의 Text를 바꿔줍니다.

중요한 점

  • 꼭 함수들을 public하여 버튼의 이벤트로 사용할 수 있게끔 만들어 줍시다.

 

 

-   Shop 스크립트 오브젝트 연결

ex) 아이템 상점 Zone

 

-   Player 스크립트

/* Player script, 변경 혹은 추가되는 부분만 작성하였습니다. */
public class Player : MonoBehaviour
{
    bool isShop;

    void Interation()
    {
        if (iDown && nearObject != null && !isJump && !isDodge) {
            if (nearObject.tag == "Weapon") {
                Item item = nearObject.GetComponent<Item>();
                int weaponIndex = item.value;
                hasWeapons[weaponIndex] = true;

                Destroy(nearObject);
            }
            else if (nearObject.tag == "Shop")
            {
                Shop shop = nearObject.GetComponent<Shop>();
                shop.Enter(this);
                isShop = true;
            }
        }
        
    }


    private void OnTriggerStay(Collider other)
    {
        if (other.tag == "Weapon" || other.tag == "Shop")
            nearObject = other.gameObject;
    }
    private void OnTriggerExit(Collider other)
    {
        if (other.tag == "Weapon")
            nearObject = null;
        else if (other.tag == "Shop")
        {
            Shop shop = nearObject.GetComponent<Shop>();
            shop.Exit();
            isShop = false;
            nearObject = null;
        }
    }
}
  • isShop : 현재, 쇼핑중이라는 플래그를 두어, 다른 동작을 못하도록 조건 제어용입니다.
  • Interation() : Zone 위에서 'e' 키를 누를 시 shop.Enter을 실행시켜줍시다.
  • onTriggerStay, OnTriggerExit 함수에서도, shop에 대한 조건문을 두어 줍니다.

 

-   버튼 이벤트 함수 설정

  • Item Button A,B,C는 On Click 함수로 Shop.Buy()를 연결
  • Exit Button에는 Shop.Exit() 함수를 연결해줍니다.

 

이번 시간에서는, UI와 스크립트의 연결법을 알게 되었습니다. 이때, 최대한 Object들을 연결해가며 어떻게 간결하게 짤지를 연구해 보면 좋겠다고 느꼈습니다.

 

 

 

출처: 골든메탈님 유튜브

https://www.youtube.com/watch?v=r27DFyivQCY&list=PLO-mt5Iu5TeYkrBzWKuTCl6IUm_bA6BKy&index=15 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.