상세 컨텐츠

본문 제목

유니티 공부(10)

유니티

by MJ_119 2023. 9. 18. 20:49

본문

출처 : 골드메탈 유니티 뱀서라이크 11

 

능력 업그레이드 구현

 

1. 아이템 데이터 만들기

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

[CreateAssetMenu(fileName = "Item", menuName = "Scriptable Object/ItemData")] //CreateAssetMenu : 커스텀 메뉴를 생성하는 속성
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 Data")]
    public float baseDamage;
    public int baseCount;
    public float[] damages; // 데미지 배율
    public int[] counts; // 근접이면 무기 개수, 원거리면 몬스터 관통수.

    [Header("# Weapon")] // 무기 프리펩 넣는곳
    public GameObject projectile;

}

 

 

 

2. 레벨업 버튼 제작

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

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

    Image icon;
    Text textLevel;

    void Awake()
    {
        icon = GetComponentsInChildren<Image>()[1];
        icon.sprite = data.itemIcon;

        Text[] texts = GetComponentsInChildren<Text>();
        textLevel = texts[0];
    }


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

    public void OnClick()
    {
        switch (data.itemType)
        {
            case ItemData.ItemType.Melee: // 근접공격
            case ItemData.ItemType.Range: // 원거리공격

                break;

            case ItemData.ItemType.Glove:
                break;
            case ItemData.ItemType.Shoe:
                break;
            case ItemData.ItemType.Heal:
                break;
        }

        level++;


        if( level == data.damages.Length ) // 레벨이 맥스에 도달하면 버튼 인터렉티브 비활성화
        {
            GetComponent<Button>().interactable = false;
        }

    }
}

 

3. 무기 업그레이드

 

Item 스크립트

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

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

    Image icon;
    Text textLevel;

    void Awake()
    {
        icon = GetComponentsInChildren<Image>()[1];
        icon.sprite = data.itemIcon;

        Text[] texts = GetComponentsInChildren<Text>();
        textLevel = texts[0];
    }


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

    public void OnClick()
    {
        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);
                }
                break;

            case ItemData.ItemType.Glove:
                break;
            case ItemData.ItemType.Shoe:
                break;
            case ItemData.ItemType.Heal:
                break;
        }

        level++;


        if( level == data.damages.Length ) // 레벨이 맥스에 도달하면 버튼 인터렉티브 비활성화
        {
            GetComponent<Button>().interactable = false;
        }

    }
}

 

Weapon 스크립트

void Awake()
    {
        // player = GetComponentInParent<Player>(); // 부모의 컴포넌트 가져오기
        player = GameManager.instance.player;
    }

public void Init(ItemData data)
    {
        // Basic Set
        name = "Weapon " + data.itemId;
        transform.parent = player.transform; // 부모 오브젝트를 플레이어로 지정.
        transform.localPosition = Vector3.zero; // 지역 위치인 localPosition을 원점으로 변경

        // 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; // speed 값은 연사속도를 의미 : speed가 적을수록 많이 발사
                break;
        }
    }

 

4. 장비 업그레이드

 

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

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

public class Item : MonoBehaviour
{
    public ItemData data;
    public int level;
    public Weapon weapon;
    public Gear gear; // 버튼 스크립트에서 새롭게 작성한 장비 타입의 변수 선언

    Image icon;
    Text textLevel;

    void Awake()
    {
        icon = GetComponentsInChildren<Image>()[1];
        icon.sprite = data.itemIcon;

        Text[] texts = GetComponentsInChildren<Text>();
        textLevel = texts[0];
    }


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

    public void OnClick()
    {
        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;

            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;
            case ItemData.ItemType.Heal:
                GameManager.instance.health = GameManager.instance.maxHealth;
                break;
        }

        


        if( level == data.damages.Length ) // 레벨이 맥스에 도달하면 버튼 인터렉티브 비활성화
        {
            GetComponent<Button>().interactable = false;
        }

    }
}
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.localPosition = Vector3.zero;

        // Property Set
        type = data.itemType;
        rate = data.damages[0];
        ApplyGear(); // 장비가 새롭게 추가되거나 레벨업 할 때 로직적용 함수 호출
    }

    public void LevelUp(float rate)
    {
        this.rate = rate; // Weapon과 동일하게 레벨업 함수 작성
        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>(); // 플레이어로 올라가서 모든 무기<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;
    }
}

'유니티' 카테고리의 다른 글

유니티 공부(12)  (0) 2023.10.20
유니티 공부(11)  (0) 2023.10.19
유니티 공부(9)  (0) 2023.09.12
유니티 공부(2)  (0) 2023.08.17
유니티 공부(1)  (0) 2023.08.16

관련글 더보기