[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 11 (능력 업그레이드💪구현)

2023. 5. 10. 00:22·게임개발/언데드서바이벌_골드메탈_클론코딩

https://www.youtube.com/watch?v=-47pjK-P888&list=PLO-mt5Iu5TeZF8xMHqtT_DhAPKmjF6i3x&index=14 


1. 아이템 데이터 만들기

데이터를 체계적으로 관리하기위해 스크립터블 오브젝트 제공

아이템 데이터 생성을 담당할 스크립트 생성 : ItemData.cs

[CreateAssetMenu(fileName ="Item",menuName ="Scriptble Object/ItemData")]
public class ItemData : ScriptableObject
{
    public enum ItemType { Melee,Range,Glove,Shoe,Heal}

    [Header("# Main Info")]
    public ItemType itemType;
    public int itemId;
    public string itemName;
    public string itemDesc;
    public Sprite itemIcon;

    [Header("# Level Info")]
    public float baseDamage;
    public int baseCount;
    public float[] damages;
    public int[] counts;


    [Header("# Weapon")]
    public GameObject projectile;

}

Monobehavior 지우고 ScriptableObject로 대체

아이템의 각종 속성들을 변수로 작성하기

- enum으로 아이템 종류 편하게 구분(ItemType)

CreateAssetMenu : 커스텀  메뉴를 생성하는 속성

[CreateAssetMenu(fileName ="Item",menuName ="Scriptble Object/ItemData")]

 

스크립트블 오브젝트를 담을 폴더 생성(Data)

***Create 메뉴에서 코드로 지정한 Scriptble Object > ItemData클릭으로 에셋 생성

스크립트블 오브젝트 : 다양한 데이터를 저장하는 에셋

Item 0 인스펙터

나머지도 복사 후 기타 값들을 넣어준다. (Icon, Projectile도 변경)(Item 0 ~ Item 4)

 


2. 레벨업 버튼 제작

Canvas > Create Empty : 레벨업 버튼을 묶어줄 부모 오브젝트 생성(Level Up)

앵커및 크기조정

자식 오브젝트로 버튼 추가(Item 0)

background = panel

자식 오브젝트 Text를 폰트변경, 크기 0,0 ,Horizontal&Vertical Overflow로 변경

Image의 Source Image를 변경(Select 0)

크기가 크기 때문에 Set Native Size클릭해서 원본크기로 돌려 놓는다.    //안되서 직접 썻습니다.

Pos Y = 3

 

업그레이드 버튼을 담당할 스크립트 생성 : Item.cs

아이템 관리에 필요한 변수들 선언

using UnityEngine.UI;
using static Cinemachine.DocumentationSortingAttribute;

public class Item : MonoBehaviour
{
    public ItemData data;
    public int level;
    public Weapon weapon;
    public Gear gear;

    Image icon;
    Text textLevel;
}

using UnityEngine.UI; 해주어야 Image와 Text 사용 가능

자식 오브젝트의 컴포넌트가 필요하므로 GetComponentsInChildren<Image>[1];

- 자기 자신도 포함되서 두번째 값으로 가져오기

Text는 여러개를 가져올것이기 때문에 배열 선언

 

LateUpdate에서 레벨 텍스트 갱신

    private void LateUpdate()
    {
        textLevel.text = "Lv." + (level + 1);
    }

 

버튼에 작성한 스크립트 추가 후 스크립트블 오브젝트 넣어두기

완성된 버튼은 Ctrl + D로 복사하여 다른 데이터 넣기

 

Level Up(Empty,부모)에게 Vertical Layout Group 컴포넌트를 추가

버튼을 데이터 개수에 맞게 복사하고 각각 스크립트블 오브젝트 연결

 

버튼 클릭 이벤트와 연결할 함수 추가

    public void OnClick()
    {
        switch (data.itemType)
        {
            case ItemData.ItemType.Melee:
            case ItemData.ItemType.Range:
                break;
            case ItemData.ItemType.Glove:
            case ItemData.ItemType.Shoe:
                break;
            case ItemData.ItemType.Heal:
                break;

        }
        
		level++;

        if (level == data.damages.Length)
        {
            GetComponent<Button>().interactable = false;
        }
    }

아이템 타입을 통해 switch case문 작성해두기

여러 개의 case를 붙여서 로직을 실행하게 할 수 있어요

이후 level 값 하나 더하기

level이 최대값이면 올라가지 않게 interactable = false 설정

- interactable = false : 클릭 비활성화

 

나와서 인스펙터 창에서 Button 컴포넌트의 On Click () 에 각각의 (Script)Item의 OnClick() 메서드 연결

오작동을 방지하기 위해 모든 버튼의 Navigation을 None으로 변경


3. 무기 업그레이드

과거에 작성하였던 Player의 자식 Weapon1,2를 삭제

 

무기를 만드는 코드를 작성

        switch (data.itemType)
        {
            case ItemData.ItemType.Melee:
            case ItemData.ItemType.Range:
                if(level == 0)
                {
                    GameObject newWeapon = new GameObject();
                    weapon = newWeapon.AddComponent<Weapon>();
                    weapon.Init(data);
                }
                break;

새로운 게임오브젝트를 코드로 생성

AddComponent<T> : 게임 오브젝트에 T 컴포넌트를 추가하는 함수

- AddComponent 함수 반환 값을 미리 선언한 변수에 저장 

weapon.Init으로 초기화

 

(Init) Ctrl + 마우스 클릭으로 함수를 클릭하면 해당 함수 내용으로 바로 이동

Weapon의 Init 메소드

    public void Init(ItemData data)
    {
        // Basic Set
        name = "Weapon " + data.itemId;
        transform.parent = player.transform;
        transform.localPosition = Vector3.zero;

        // Property Set
        id=data.itemId;
        damage = data.baseDamage;
        count = data.baseCount;
        for(int index = 0; index < GameManager.instance.pool.prefabs.Length; index++)
        {
            if(data.projectile== GameManager.instance.pool.prefabs[index])
            {
                prefabId = index;
                break;
            }
        }
        switch (id)
        {
            case 0:
                speed = 150;
                Batch();
                break;
            default:
                speed = 0.3f;
                break;
        }
        player.BroadcastMessage("ApplyGear",SendMessageOptions.DontRequireReceiver);
    }

Weapon 초기화 함수에 스크립트블 오브젝트를 매개변수로 받아 활용

Basic set(기본적인 사항)과 Property set()으로 나눠서 초기화

//Basic set

transform.parent = player.transform : 부모를 player로 지정

transform.localPosition = Vector3.zero : 지역 위치인 localPosition을 원점으로 변경

- 플레이어 안에서 (0,0,0)이여아 하기 때문이다.

//Property set

각종 무기 속성 변수들을 스크립트블 오브젝트 데이터로 초기화

 

프리펩 아이디는 풀링 매니저의 변수에서 찾아서 초기화

        for(int index = 0; index < GameManager.instance.pool.prefabs.Length; index++)
        {
            if(data.projectile== GameManager.instance.pool.prefabs[index])
            {
                prefabId = index;
                break;
            }
        }

- Data에서 프리팹 아이디를 숫자로 직접 넣어도 되지만 꼬일 수 있기 때문에 

- 스크립트블 오브젝트의 독립성을 위해서 인젝스가 아닌 프리펩으로 설정

 

Start 함수 로직은 삭제하고

 

더 이상, 이 Weapon은 부모의 자식이 아님으로, Awake 함수에서의 플레이어 초기화는 게임매니저 활용으로 변경

    private void Awake()
    {
    	//player = GetComponentInParent<Player>();
        player = GameManager.instance.player;
    }

 

Item에 OnClick에 LevelUp 로직 추가

        switch (data.itemType)
        {
            case ItemData.ItemType.Melee:
            case ItemData.ItemType.Range:
                if(level == 0)
                {
                    GameObject newWeapon = new GameObject();
                    weapon = newWeapon.AddComponent<Weapon>();
                    weapon.Init(data);
                }
                else
                {
                    float nextDamage = data.baseDamage;
                    int nextCount = 0;

                    nextDamage += data.baseDamage * data.damages[level];
                    nextCount += data.counts[level];

                    weapon.LevelUp(nextDamage, nextCount);
                }
                level++;
                break;

- 처음 이후의 레벨업은 데미지와 횟수를 계산

- Weapon의 작성된 레벨업 함수를 그대로 활용


4. 장비 업그레이드

장비를 담당하는 새로운 스크립트 생성(Gear.cs)\

 

장비의 타입과 수치를 저장할 변수 선언

Weapon과 동일하게 초기화 함수 작성

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

public class Gear : MonoBehaviour
{
    public ItemData.ItemType type;
    public float rate;

    public void Init(ItemData data)
    {
        // Basic Set
        name = "Gear " + data.itemId;
        transform.parent = GameManager.instance.player.transform;
        transform.position = Vector3.zero;

        // Property Set
        type = data.itemType;
        rate = data.damages[0];
        ApplyGear();

    }

}

 

	public void Levelup(float rate)
    {
        this.rate = rate;
        ApplyGear();
    }

    void ApplyGear()
    {
        switch (type)
        {
            case ItemData.ItemType.Glove:
                RateUp();
                break;
            case ItemData.ItemType.Shoe:
                SpeedUp();
                break;
        }
    }

    void RateUp()
    {
        Weapon[] weapons = transform.parent.GetComponentsInChildren<Weapon>();

        foreach(Weapon weapon in weapons)
        {
            switch (weapon.id)
            {
                case 0:
                    weapon.speed = 150 + (150 * rate);
                    break;
                default:
                    weapon.speed = 0.5f * (1f - rate);
                    break;
            }
        }
    }
    void SpeedUp()
    {
        float speed = 3;
        GameManager.instance.player.speed = speed + speed * rate;
    }

Weapon과 동일하게 레벨업 함수 작성

RateUp() : 장갑의 기능인 연사력을 올리는 함수 작성

transform.parent.GetComponentsInChildren<Weapon>() : 플레이어로 올라가서 모든 Weapon을 가져오기

foreach문으로 하나씩 순회하면서 타입에 따라 속도 올리기

SpeedUp() : 신발의 기능인 이동 속도를 올리는 함수 작성

ApplyGear를 실행하는게 관건인데, 언제 사용하느냐?

1. 처음에 기어가 생성될 때 (Init)

2. 기어가 업데이트 될 때 (LevelUp)

 

Item으로 돌아가서 Gear 변수 선언

public class Item : MonoBehaviour
{
    public ItemData data;
    public int level;
    public Weapon weapon;
    public Gear gear;
    //...
}

- 버튼 스크립트에서 새롭게 작성한 장비 타입의 변수 선언

 

 

    public void OnClick()
    {
        switch (data.itemType)
        {
            //...
            case ItemData.ItemType.Glove:
            case ItemData.ItemType.Shoe:
                if(level == 0){
                    GameObject newGear = new GameObject();
                    gear = newGear.AddComponent<Gear>();
                    gear.Init(data);
                }
                else
                {
                    float nextRate = data.damages[level];
                    gear.Levelup(nextRate);
                    
                }
                level++;
                break;
            //...

        }

- 무기 로직과 마찬가지로 최초 레벨업은 게임오브젝트 생성 로직을 작성

- 나중에 생성된 무기가 기어에 영향을 받지 않는 문제 발생

 

BroadcastMessage : 특정 함수 호출을 모든 자식에게 방송하는 함수

player.BroadcastMessage("ApplyGear",SendMessageOptions.DontRequireReceiver);

 - SendMessageOptions.DontRequireReceiver : 이 옵션은 받는 대상이 없어도 오류를 출력하지 않는다.

Weapon.cs의 BroadcastMessage를 초기화, 레벨업 함수 마지막 부분에서 호출(Init,LevelUp)

 

치료 기능의 음료수 로직은 case문에서 바로 작성

            case ItemData.ItemType.Heal:
                GameManager.instance.health = GameManager.instance.maxHealth;
                break;

 

레벨 값을 올리는 로직을 무기, 장비 case 안쪽으로 이동  //이미 하였음


깃허브 올리기

Commit : ver 1.11
Description : Ability implement

 

https://github.com/mekain80/CloneCode_Undead_Survivor

 

GitHub - mekain80/CloneCode_Undead_Survivor: https://www.youtube.com/watch?v=MmW166cHj54&list=PLO-mt5Iu5TeZF8xMHqtT_DhAPKmjF6i3x

https://www.youtube.com/watch?v=MmW166cHj54&list=PLO-mt5Iu5TeZF8xMHqtT_DhAPKmjF6i3x&index=1 - GitHub - mekain80/CloneCode_Undead_Survivor: https://www.youtube.com/watch?v=MmW166cHj54&li...

github.com

 

'게임개발 > 언데드서바이벌_골드메탈_클론코딩' 카테고리의 다른 글

[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 12 (레벨업🥳시스템)  (0) 2023.05.10
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 11+ (플레이어 무기 장착 표현하기)  (0) 2023.05.10
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 10 (HUD📐제작하기)  (0) 2023.05.06
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 9 (타격감🌟있는 몬스터 처치 만들기)  (0) 2023.05.06
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 8 (자동🎯원거리 공격 구현)  (0) 2023.04.10
'게임개발/언데드서바이벌_골드메탈_클론코딩' 카테고리의 다른 글
  • [클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 12 (레벨업🥳시스템)
  • [클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 11+ (플레이어 무기 장착 표현하기)
  • [클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 10 (HUD📐제작하기)
  • [클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 9 (타격감🌟있는 몬스터 처치 만들기)
메카인
메카인
  • 메카인
    메카인의 지식창고
    메카인
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 코딩 공부
        • TIL(Today I Learn)
        • TIL
        • 백준(C++)
        • Python
        • 알고리즘
        • 프로젝트 회고
      • C++
        • C++
        • C++ STL
        • C,C++ mCoding yotube
      • 게임개발
        • 언데드서바이벌_골드메탈_클론코딩
        • 3D_골드메탈_클론코딩
        • 유니티_문제해결
        • 게임 수학
      • Unreal 공부
        • UE5 GameDev
        • Unreal Engine 4 C++ The Ult..
      • 교재 문제 풀이
        • 운영체제
      • 정보처리기사
        • 정처기 요약
        • 정처기 오답노트
      • 학교수업
        • 데이터베이스
        • 프로그래밍 언어론
        • 리눅스 시스템
        • 네트워크
      • 일상
        • 주식
        • 독서
      • (비공개 전용)
        • memory
        • Build
        • OOP
        • Smart Pointer
        • lamda
        • 게임 수학
        • 모던 C++
        • 모던 C++ STL
        • 모던 C++ Concurrency, Paralle..
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
    • 블로그 관리
  • 링크

  • 공지사항

    • 공지사항 - 인생과 블로그의 목표
  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
메카인
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 11 (능력 업그레이드💪구현)
상단으로

티스토리툴바