Skip to content

explain Weapon

Yoo Hyeokjin edited this page Jun 27, 2023 · 6 revisions

Weapon

목차

Weapon 설명

변수 선언

public int WeaponIndex;             // Weapon의 고유한 Index 번호
public int WeaponLevel = 1;         // Weapon의 현재 Level
public int WeaponMaxLevel;          // Weapon의 Max Level
public bool BEvolution = false;     // Weapon의 진화 유무
public float[] WeaponTotalStatList; // Weapon의 최종 Stat
private float[] mWeaponStats;       // Weapon 자체의 Stat

Weapon이 Damage를 주는 코드

private void OnTriggerEnter2D(Collider2D col) // 물체와 접촉하였을 때
{
    if (col.CompareTag("DestructibleObj")) // Trigger한 물체가 파괴 가능한 MapOject 일 때
    {
        if (col.gameObject.TryGetComponent(out DestructibleObject destructible))
        {
            destructible.TakeDamage(WeaponTotalStatList[(int)Enums.EWeaponStat.Might], WeaponIndex); // 해당 Object에 TakeDamage Method를 실행시켜 Damage를 입힌다.
        }
    }
    if (col.gameObject.tag == "Monster") // Trigger한 물체가 Enemy 일 때
    {
        col.gameObject.GetComponent<Enemy>().TakeDamage(WeaponTotalStatList[(int)Enums.EWeaponStat.Might], WeaponIndex); // 해당 Enemy의 TakeDamage Method를 실행시켜 Damage를 입힌다.
        if (WeaponIndex == 6 && BEvolution) // 무기가 진화된 Gralic이면 
        {
            GameManager.instance.Character.RestoreHealth(1); // Character의 체력을 1 회복시킨다.
            GameManager.instance.EvoGralicRestoreCount++;    // EvoGralic으로 회복한 양을 1 증가시킨다.
            if (GameManager.instance.EvoGralicRestoreCount <= 3600 && GameManager.instance.EvoGralicRestoreCount > 0)
            {  // EvoGralic은 공격력이 최대 60까지 증가할 수 있으니까 회복량을 0 < x <= 3600까지만 감지해서 공격력을 증가시켜야 한다.
                if (GameManager.instance.EvoGralicRestoreCount % 60 == 0)
                {
                    WeaponTotalStatList[((int)Enums.EWeaponStat.Might)] += 1; // 회복한 양이 60이면 공격력을 1 증가시킨다.
                }
            }
        }
    }
}

Weapon이 화면 밖으로 나가면 instance 삭제하는 코드

private void OnTriggerExit2D(Collider2D col) // 물체와 접촉이 끝났을 때
{
    if (col.gameObject.tag == "Boundary")
    {
        Destroy(this.gameObject); // Trigger한 물체가 Boundatry일 경우 해당 Weapon instance를 삭제한다.
    }
}

Weapon을 얻었을 때 기본적으로 하는 Setting

public void WeaponDefalutSetting(int weaponIndex=0)
{
    this.WeaponIndex = weaponIndex; // weaponIndex를 저장한다.
    this.mWeaponStats = Enumerable.Range(0, EquipmentData.DefaultWeaponStats.GetLength(1)).Select(x => EquipmentData.DefaultWeaponStats[weaponIndex, x]).ToArray(); // Weapon의 초기 Stat을 가져온다.
    WeaponLevel = 1; // Weapon의 현재 level을 1로 설정한다.
    WeaponMaxLevel = (int)mWeaponStats[(int)Enums.EWeaponStat.MaxLevel]; // Weapon의 Max Level을 mWeaponStats에서 가져와 저장한다.
    WeaponTotalStatList = mWeaponStats; // Weapon의 최종 Stat에 Weapon의 초기 Stat을 저장한다.
    AttackCalculation(); // Stat을 계산해주는 Method
}

private void AttackCalculation()
{
    DamageCalculation();            // 공격력 계산해주는 Method
    ProjectileSpeedCalculation();   // 투사체 속도 계산해주는 Method
    DurationCalculation();          // 지속시간 계산해주는 Method
    AttackRangeCalculation();       // 공격 범위 계산해주는 Method
    CooldownCalculation();          // 쿨타임 계산해주는 Method
    CalculateNumberOfProjectiles(); // 투사체 수를 계산해주는 Method
}
private void DamageCalculation()
{ // Weapon 최종 Stat에 공격력을 계산해서 저장한다. 초기 Stat에 Player가 가지고 있는 Stat 증가량을 곱해준다.
    WeaponTotalStatList[((int)Enums.EWeaponStat.Might)] = mWeaponStats[((int)Enums.EWeaponStat.Might)] * GameManager.instance.CharacterStats[(int)Enums.EStat.Might];
}
private void ProjectileSpeedCalculation()
{ // Weapon 최종 Stat에 투사체 속도를 계산해서 저장한다. 초기 Stat에 Player가 가지고 있는 Stat 증가량을 곱해준다.
    WeaponTotalStatList[((int)Enums.EWeaponStat.ProjectileSpeed)] = mWeaponStats[((int)Enums.EWeaponStat.ProjectileSpeed)] * GameManager.instance.CharacterStats[(int)Enums.EStat.ProjectileSpeed];
}
private void DurationCalculation()
{ // Weapon 최종 Stat에 지속시간을 계산해서 저장한다. 초기 Stat에 Player가 가지고 있는 Stat 증가량을 곱해준다.
    WeaponTotalStatList[((int)Enums.EWeaponStat.Duration)] = mWeaponStats[((int)Enums.EWeaponStat.Duration)] * GameManager.instance.CharacterStats[(int)Enums.EStat.Duration];
}
private void AttackRangeCalculation()
{ // Weapon 최종 Stat에 공격 범위를 계산해서 저장한다. 초기 Stat에 Player가 가지고 있는 Stat 증가량을 곱해준다.
    WeaponTotalStatList[((int)Enums.EWeaponStat.Area)] = mWeaponStats[((int)Enums.EWeaponStat.Area)] * GameManager.instance.CharacterStats[(int)Enums.EStat.Area];
}
private void CooldownCalculation()
{ // Weapon 최종 Stat에 쿨타임을 계산해서 저장한다. 초기 Stat에 Player가 가지고 있는 Stat 증가량을 곱해준다.
    WeaponTotalStatList[((int)Enums.EWeaponStat.Cooldown)] = mWeaponStats[((int)Enums.EWeaponStat.Cooldown)] * GameManager.instance.CharacterStats[(int)Enums.EStat.Cooldown];
}
private void CalculateNumberOfProjectiles()
{ // Weapon 최종 Stat에 투사체 수를 계산해서 저장한다. 초기 Stat에 Player가 가지고 있는 Stat 증가량을 더해준다.
    WeaponTotalStatList[((int)Enums.EWeaponStat.Amount)] = ((int)mWeaponStats[((int)Enums.EWeaponStat.Amount)]) + GameManager.instance.CharacterStats[(int)Enums.EStat.Amount];
}

Upgrade와 Evolution

public void Upgrade() // Upgrade를 한다.
{
    WeaponLevel++; // Weapon의 Level을 올린다.
    foreach ((var statIndex, var data) in EquipmentData.WeaponUpgrade[WeaponIndex][WeaponLevel])
    {
        mWeaponStats[statIndex] += data; // Weapon의 Stat을 올린다.
    }
    Evolution(); // 진화 Method
}
public bool IsMaster()
{ // Weapon이 Max Level에 도달하였을 때 true를 반환, 아니면 false를 반환한다.
    return WeaponLevel == WeaponMaxLevel;
}
public bool IsEvoluction()
{ // Weapon의 진화 유무에 따라 bool을 return 한다.
    return BEvolution;
}
public float[] WeaponTotalStats { get { return WeaponTotalStatList; } } // Weapon의 최종 스텟을 get할 수 있게 하는 Method
public virtual void Attack() { } // Weapon이면 반드시 구현해야 하는 virtual Method, 공격을 이행하는 Method
public virtual void EvolutionProcess() { } // Weapon이면 반드시 구현해야 하는 virtual Method, 진화 과정을 이행하는 Method
private void Evolution()
{
    if (!IsMaster()) // Weapon이 Max Level이 아니면 그냥 return 한다.
        return;
    var equipManageSys = GameManager.instance.EquipManageSys;
    int evoPairAccIndex = EquipmentData.EvoWeaponNeedAccIndex[WeaponIndex];
    if (evoPairAccIndex < 0)    // 짝이 되는 악세서리의 index = -1 -> 짝이 무기인 경우
        EvolutionException(equipManageSys);
    else if (equipManageSys.HasAcc(evoPairAccIndex)) // 진화할 무기의 짝이 되는 Accessory를 가지고 있다면
        BEvolution = true; // 진화함을 true로 저장

    if (BEvolution)
        EvolutionProcess(); // 진화를 진행한다.
}
private void EvolutionException(EquipmentManagementSystem equipManageSys)     // 진화에 필요한 짝이 악세서리가 아닌 무기인 경우(예시 - 비둘기, 흑비둘기)
{
    var evoPairWeaponIndex = EquipmentData.EvoWeaponNeedWeaponIndex[WeaponIndex];
    if (equipManageSys.HasWeapon(evoPairWeaponIndex) && equipManageSys.Weapons[equipManageSys.TransWeaponIndex[evoPairWeaponIndex]].IsMaster())
        BEvolution = equipManageSys.Weapons[equipManageSys.TransWeaponIndex[evoPairWeaponIndex]].BEvolution = true;
}

SkillFiringSystem 설명

public GameObject[] weaponPrefabs; //무기 프리팹
public GameObject[] evolutionWeaponPrefabs; //진화 무기 프리팹
public GameObject[] Birds; // peachone, EbonyWings, 둘의 진화체에 등장하는 새
public GameObject[] Circles;

public static SkillFiringSystem instance = null;

private void Awake()
{
    instance = this; // SkillFiringSystem instance를 하나 만든다.
}
private void Update()
{
    foreach (var weapon in GameManager.instance.EquipManageSys.Weapons)
    {
        weapon.Attack(); // 가지고 있는 Weapon의 Attack() 함수를 실행시킨다.
    }
}

image

EquipmentManagementSystem 설명

변수 선언

public List<Weapon> Weapons;           // 현재 가지고 있는 Weapon List
public List<Accessory> Accessories;    // 현재 가지고 있는 Accessory List
public List<int> MasteredWeapons;      // 현재 가지고 있는 Master한 Weapon List
public List<int> MasteredAccessories;  // 현재 가지고 있는 Master한 Weapon List
public int[] TransWeaponIndex;         // 해당 index의 weapon이 현재 보유중인 Weapons의 몇 번째 index에 있는지 반환하는 배열, 없다면 -1 반환
public int[] TransAccessoryIndex;      // 위와 같으나 Accessory에 해당

Character가 가지고 있는 초기 Weapon Setting -> 한번만 실행된다.

public void Set(int startingWeapon)
{
    Weapons = new List<Weapon>(); // List를 만들어준다.
    Accessories = new List<Accessory>(); // List를 만들어준다.
    TransWeaponIndex = Enumerable.Repeat<int>(-1, Constants.MAX_WEAPON_NUMBER).ToArray<int>(); // MAX_WEAPON_NUMBER만큼 -1로 채운다.
    TransAccessoryIndex = Enumerable.Repeat<int>(-1, Constants.MAX_ACCESSORY_NUMBER).ToArray<int>(); // MAX_ACCESSORY_NUMBER만큼 -1로 채운다.
    MasteredWeapons = new List<int>(); // List를 만들어준다.
    MasteredAccessories = new List<int>(); // List를 만들어준다.

    SetNewWeapon(startingWeapon); // Weapon을 얻었을 때 실행하는 코드
}

Weapon을 얻었을 때 실행하는 코드

public void SetNewWeapon(int weaponIndex)
{
    GameManager.instance.WeaponGetTime[weaponIndex] = GameManager.instance.GameTime; // Weapon을 얻은 시간을 저장한다.

    AddNewWeapon(weaponIndex); // 새로 얻은 무기를 Weapon List에 추가하는 Method
    TransWeaponIndex[weaponIndex] = Weapons.Count - 1; // 해당하는 무기가 Weapon List에 몇 번째에 해당하는 저장한다.

    Weapons.Last().WeaponDefalutSetting(weaponIndex); // 가지고 있는 무기들을 기본 Setting을 한다.
    GameManager.instance.WeaponSlot.GetComponent<SlotUI>().AddSlot(weaponIndex, 0); // Slot UI 에 해당 Weapon을 넣는다.

    ProcessWeaponSub(weaponIndex, Weapons.Last()); // 비둘기 관련된 Method
}

private void ProcessWeaponSub(int weaponIndex, Weapon weapon)
{
    switch(weaponIndex) 
    {
        case 7: // peachOne
            weapon.GetComponent<Peachone>().SpawnBlueBird(SkillFiringSystem.instance.Birds[0]);
            break;
        case 8: // ebonyWings
            weapon.GetComponent<EbonyWings>().SpawnBlackBird(SkillFiringSystem.instance.Birds[1]);
            break;
    }
}
private void AddNewWeapon(int weaponIndex) // SkillFiringSystem에 저장된 해당되는 무기의 Prefab을 불러온다.
{
    switch (weaponIndex)
    {
        case 0: // Whip
            Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<Whip>());
            break;
        case 1: // MagicWand
            Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<MagicWand>());
            break;
        case 2: // Knife
            Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<Knife>());
            break;
        case 3: // Cross
            Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<Cross>());
            break;
        case 4: // KingBible
            Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<KingBible>());
            break;
        case 5: // FireWand
            Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<FireWand>());
            break;
        case 6: // Garlic
            Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<Gralic>());
            break;
        case 7: // peachOne
            Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<Peachone>());
            break;
        case 8: // ebonyWings
            Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<EbonyWings>());
            break;
        case 9: // LightningRing
            Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<LightningRing>());
            break;
    }
}

Accessory를 얻었을 때 실행되는 코드

public void GetAccessory(int accessoryIndex)
{ 
    TransAccessoryIndex[accessoryIndex] = Accessories.Count; // 얻은 Accessory가 몇 번째인지 저장한다.
    Accessories.Add(new Accessory(accessoryIndex)); // Accessory List에 얻은 Accessory를 추가한다.
    UpgradeAccessory(accessoryIndex); // Accessory를 Upgrade한다.
    GameManager.instance.AccessorySlot.GetComponent<SlotUI>().AddSlot(accessoryIndex, 1); // Slot UI 에 해당 Accessory를 넣는다.
}

Weapon, Accessory를 가지고 있는지 유무

public bool HasWeapon(int weaponIndex)
{
    if (weaponIndex < 0 || weaponIndex >= Constants.MAX_WEAPON_NUMBER)
        return false;
    return TransWeaponIndex[weaponIndex] >= 0;
}
public bool HasAcc(int accIndex)
{
    if (accIndex < 0 || accIndex >= Constants.MAX_ACCESSORY_NUMBER)
        return false;
    return TransAccessoryIndex[accIndex] >= 0;
}

Item을 얻었을 때 실행하는 Method

public void ApplyItem(Tuple<int, int, int> pickUp)
{
    switch ((Enums.EPickUpType)pickUp.Item1)
    {
        case Enums.EPickUpType.Weapon: // Weapon을 얻었다면 
            ApplyWeapon(pickUp.Item2, pickUp.Item3); // Weapon을 적용한다.
            break;
        case Enums.EPickUpType.Accessory: // Accessory를 얻었다면 
            ApplyAccessory(pickUp.Item2, pickUp.Item3); // Accessory를 적용한다.
            break;
        default:
            ApplyEtc(pickUp.Item2); // Etc를 얻었다면 그것을 적용한다.
            break;
    }
}

private void ApplyWeapon(int weaponIndex, int hasWeapon)
{ // Weapon을 가지고 있으면 Upgrade를 하고 없으면 Set해라
    if (hasWeapon == 0)
        SetNewWeapon(weaponIndex);
    else
        UpgradeWeapon(weaponIndex);
}
private void ApplyAccessory(int accessoryIndex, int hasAccessory)
{ // Accessory를 가지고 있으면 Upgrade를 하고 없으면 Set해라
    if (hasAccessory == 0)
        GetAccessory(accessoryIndex);
    else
        UpgradeAccessory(accessoryIndex);
}
private void ApplyEtc(int etcIndex)
{ // 얻은 Etc를 적용
    switch ((Enums.EEtc)etcIndex)
    {
        case Enums.EEtc.Food:
            // TODO: 체력 회복 함수와 연결
            break;
        case Enums.EEtc.Money:
            // TODO: 재화 획득 함수와 연결
            break;
        default:
            break;
    }
}

Weapon, Accessory Upgrade하는 Method

public Weapon GetWeapon(int weaponIndex)
{ // 해당하는 무기를 return한다.
    if (TransWeaponIndex[weaponIndex] < 0)
        Debug.Log("없는 무기 호출");
    // TODO: 없는 무기 호출시 에러! 제대로 작성
    Debug.Log(TransWeaponIndex[weaponIndex]);
    Debug.Log(Weapons[TransWeaponIndex[weaponIndex]]);
    return Weapons[TransWeaponIndex[weaponIndex]];
}
public void UpgradeWeapon(int weaponIndex)
{ // Weapon을 Upgrade한다. 만약 MaxLevel이라면 Master한 Weapon에 추가한다.
    Weapons[TransWeaponIndex[weaponIndex]].Upgrade();
    if (Weapons[TransWeaponIndex[weaponIndex]].IsMaster())
    {
        MasteredWeapons.Add(weaponIndex);
    }
}
public void UpgradeAccessory(int accessoryIndex)
{ // Accessory을 Upgrade한다. 만약 MaxLevel이라면 Master한 Accessory에 추가한다.
    Accessories[TransAccessoryIndex[accessoryIndex]].Upgrade();
    if (Accessories[TransAccessoryIndex[accessoryIndex]].IsMaster())
    {
        MasteredAccessories.Add(accessoryIndex);
    }
}

GameManager에 저장된 Weapon별 정보

image

  • Kill : 몬스터를 죽인 수
  • KillCount : Weapon별 Enemy를 죽인 수
  • WeaponGetTime : Weapon별 무기 획득 시간
  • WeaponDamage : Weapon별 Enemy에게 가한 Damage

Kill, KillCount, WeaponDamage 적용

  • Enemy.cs에 TakeDamage Method에서 입력된다.
public void TakeDamage(float damage, int weaponIndex)
{
    mHealth -= damage;
    GameManager.instance.WeaponDamage[weaponIndex] += damage; // 이 부분에서 해당 Weapon이 Enemy에게 입힌 Damage를 저장한다.

    if (mHealth > 0)
    {
        StartCoroutine(KnockBack());
        mAnim.SetTrigger("Hit");
        Debug.Log("Hit");
        if(weaponIndex == 6)
        {
            if(mKnockbackpower < 3)
            {
                mKnockbackpower++;
            }
        }
    }
    else
    {
        mbLive = false;
        mColl.enabled = false;
        mRb.simulated = false;
        mSpriter.sortingOrder = 1;
        mAnim.SetBool("Dead", true);
        GameManager.instance.Kill++; // 이 부분에서 Enemy를 죽인 수를 저장한다.
        Dead();
        GameManager.instance.KillCount[weaponIndex]++; // 이 부분에서 해당 Weapon이 죽인 Enemy 수를 저장한다.
    }
}

WeaponGetTime 적용

  • EquipmentManagementSystem.cs에 SetNewWeapon에서 입력된다.
public void SetNewWeapon(int weaponIndex)
{
    GameManager.instance.WeaponGetTime[weaponIndex] = GameManager.instance.GameTime; // 이 부분에서 처음으로 무기를 얻을 때 얻은 시간을 저장한다.

    AddNewWeapon(weaponIndex);
    TransWeaponIndex[weaponIndex] = Weapons.Count - 1;

    Weapons.Last().WeaponDefalutSetting(weaponIndex);
    GameManager.instance.WeaponSlot.GetComponent<SlotUI>().AddSlot(weaponIndex, 0);

    ProcessWeaponSub(weaponIndex, Weapons.Last());
}

ScriptCode

Weapon.cs

using UnityEngine;
using System;
using System.Linq;

public class Weapon : MonoBehaviour
{
    public int WeaponIndex;
    public int WeaponLevel = 1;
    public int WeaponMaxLevel;
    public bool BEvolution = false;
    public float[] WeaponTotalStatList; // Might,Cooldown,ProjectileSpeed, Duration, Amount,AmountLimit,Piercing,Area,MaxLevel
    private float[] mWeaponStats;

    private void OnTriggerEnter2D(Collider2D col)
    {
        if (col.CompareTag("DestructibleObj"))
        {
            if (col.gameObject.TryGetComponent(out DestructibleObject destructible))
            {
                destructible.TakeDamage(WeaponTotalStatList[(int)Enums.EWeaponStat.Might], WeaponIndex);
            }
        }
        if (col.gameObject.tag == "Monster")
        {
            col.gameObject.GetComponent<Enemy>().TakeDamage(WeaponTotalStatList[(int)Enums.EWeaponStat.Might], WeaponIndex);
            if (WeaponIndex == 6 && BEvolution)
            {
                GameManager.instance.Character.RestoreHealth(1);
                GameManager.instance.EvoGralicRestoreCount++;
                if (GameManager.instance.EvoGralicRestoreCount == 60)
                {
                    GameManager.instance.EvoGralicRestoreCount = 0;
                    WeaponTotalStatList[((int)Enums.EWeaponStat.Might)] += 1;
                }
            }
        }
    }
    private void OnTriggerExit2D(Collider2D col)
    {
        if (col.gameObject.tag == "Boundary")
        {
            Destroy(this.gameObject);
        }
    }
    public void WeaponDefalutSetting(int weaponIndex=0)
    {
        this.WeaponIndex = weaponIndex;
        this.mWeaponStats = Enumerable.Range(0, EquipmentData.DefaultWeaponStats.GetLength(1)).Select(x => EquipmentData.DefaultWeaponStats[weaponIndex, x]).ToArray();
        WeaponLevel = 1;
        WeaponMaxLevel = (int)mWeaponStats[(int)Enums.EWeaponStat.MaxLevel];
        WeaponTotalStatList = mWeaponStats;
        AttackCalculation();
    }
    public void Upgrade()
    {
        WeaponLevel++;
        foreach ((var statIndex, var data) in EquipmentData.WeaponUpgrade[WeaponIndex][WeaponLevel])
        {
            mWeaponStats[statIndex] += data;
        }
        Evolution();
    }
    public bool IsMaster()
    {
        return WeaponLevel == WeaponMaxLevel;
    }
    public bool IsEvoluction()
    {
        return BEvolution;
    }
    public float[] WeaponTotalStats { get { return WeaponTotalStatList; } }
    public virtual void Attack() { }
    public virtual void EvolutionProcess() { }
    private void Evolution()
    {
        if (!IsMaster())
            return;
        var equipManageSys = GameManager.instance.EquipManageSys;
        int evoPairAccIndex = EquipmentData.EvoWeaponNeedAccIndex[WeaponIndex];
        if (evoPairAccIndex < 0)    // 짝이 되는 악세서리의 index = -1 -> 짝이 무기인 경우
            EvolutionException(equipManageSys);
        else if (equipManageSys.HasAcc(evoPairAccIndex))
            BEvolution = true;

        if (BEvolution)
            EvolutionProcess();
    }
    private void EvolutionException(EquipmentManagementSystem equipManageSys)     // 진화에 필요한 짝이 악세서리가 아닌 무기인 경우(예시 - 비둘기, 흑비둘기)
    {
        var evoPairWeaponIndex = EquipmentData.EvoWeaponNeedWeaponIndex[WeaponIndex];
        if (equipManageSys.HasWeapon(evoPairWeaponIndex) && equipManageSys.Weapons[equipManageSys.TransWeaponIndex[evoPairWeaponIndex]].IsMaster())
            BEvolution = equipManageSys.Weapons[equipManageSys.TransWeaponIndex[evoPairWeaponIndex]].BEvolution = true;
    }
    //아래 계산을 한번에 하기
    //ToDo: 레벨업 할때마다 갱신하는 것으로 변경
    private void AttackCalculation()
    {
        DamageCalculation();
        ProjectileSpeedCalculation();
        DurationCalculation();
        AttackRangeCalculation();
        CooldownCalculation();
        CalculateNumberOfProjectiles();
    }
    private void DamageCalculation()
    {
        WeaponTotalStatList[((int)Enums.EWeaponStat.Might)] = mWeaponStats[((int)Enums.EWeaponStat.Might)] * GameManager.instance.CharacterStats[(int)Enums.EStat.Might];
    }
    private void ProjectileSpeedCalculation()
    {
        WeaponTotalStatList[((int)Enums.EWeaponStat.ProjectileSpeed)] = mWeaponStats[((int)Enums.EWeaponStat.ProjectileSpeed)] * GameManager.instance.CharacterStats[(int)Enums.EStat.ProjectileSpeed];
    }
    private void DurationCalculation()
    {
        WeaponTotalStatList[((int)Enums.EWeaponStat.Duration)] = mWeaponStats[((int)Enums.EWeaponStat.Duration)] * GameManager.instance.CharacterStats[(int)Enums.EStat.Duration];
    }
    private void AttackRangeCalculation()
    {
        WeaponTotalStatList[((int)Enums.EWeaponStat.Area)] = mWeaponStats[((int)Enums.EWeaponStat.Area)] * GameManager.instance.CharacterStats[(int)Enums.EStat.Area];
    }
    private void CooldownCalculation()
    {
        WeaponTotalStatList[((int)Enums.EWeaponStat.Cooldown)] = mWeaponStats[((int)Enums.EWeaponStat.Cooldown)] * GameManager.instance.CharacterStats[(int)Enums.EStat.Cooldown];
    }
    private void CalculateNumberOfProjectiles()
    {
        WeaponTotalStatList[((int)Enums.EWeaponStat.Amount)] = ((int)mWeaponStats[((int)Enums.EWeaponStat.Amount)]) + GameManager.instance.CharacterStats[(int)Enums.EStat.Amount];
    }
}

SkillFiringSystem.cs

using UnityEngine;

public class SkillFiringSystem : MonoBehaviour
{
    public GameObject[] weaponPrefabs; //무기 프리팹
    public GameObject[] evolutionWeaponPrefabs; //진화 무기 프리팹
    public GameObject[] Birds; // peachone, EbonyWings, 둘의 진화체에 등장하는 새
    public GameObject[] Circles;
    
    public static SkillFiringSystem instance = null;

    private void Awake()
    {
        instance = this;
    }
    private void Update()
    {
        foreach (var weapon in GameManager.instance.EquipManageSys.Weapons)
        {
            weapon.Attack();
        }
    }
}

EquipmentManagementSystem.cs

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

public class EquipmentManagementSystem 
{
    public List<Weapon> Weapons;
    public List<Accessory> Accessories;
    public List<int> MasteredWeapons;
    public List<int> MasteredAccessories;
    public int[] TransWeaponIndex; // 해당 index의 weapon이 현재 보유중인 Weapons의 몇 번째 index에 있는지 반환하는 배열, 없다면 -1 반환
    public int[] TransAccessoryIndex; // 위와 같으나 Accessory에 해당

    public void Set(int startingWeapon)
    {
        Weapons = new List<Weapon>();
        Accessories = new List<Accessory>();
        TransWeaponIndex = Enumerable.Repeat<int>(-1, Constants.MAX_WEAPON_NUMBER).ToArray<int>();
        TransAccessoryIndex = Enumerable.Repeat<int>(-1, Constants.MAX_ACCESSORY_NUMBER).ToArray<int>();
        MasteredWeapons = new List<int>();
        MasteredAccessories = new List<int>();

        SetNewWeapon(startingWeapon);
    }
    public void ApplyItem(Tuple<int, int, int> pickUp)
    {
        switch ((Enums.EPickUpType)pickUp.Item1)
        {
            case Enums.EPickUpType.Weapon:
                ApplyWeapon(pickUp.Item2, pickUp.Item3);
                break;
            case Enums.EPickUpType.Accessory:
                ApplyAccessory(pickUp.Item2, pickUp.Item3);
                break;
            default:
                ApplyEtc(pickUp.Item2);
                break;
        }
    }
    public bool HasWeapon(int weaponIndex)
    {
        if (weaponIndex < 0 || weaponIndex >= Constants.MAX_WEAPON_NUMBER)
            return false;
        return TransWeaponIndex[weaponIndex] >= 0;
    }
    public bool HasAcc(int accIndex)
    {
        if (accIndex < 0 || accIndex >= Constants.MAX_ACCESSORY_NUMBER)
            return false;
        return TransAccessoryIndex[accIndex] >= 0;
    }
    public void SetNewWeapon(int weaponIndex)
    {
        GameManager.instance.WeaponGetTime[weaponIndex] = GameManager.instance.GameTime;

        AddNewWeapon(weaponIndex);
        TransWeaponIndex[weaponIndex] = Weapons.Count - 1;

        Weapons.Last().WeaponDefalutSetting(weaponIndex);
        GameManager.instance.WeaponSlot.GetComponent<SlotUI>().AddSlot(weaponIndex, 0);

        ProcessWeaponSub(weaponIndex, Weapons.Last());
    }
    public Weapon GetWeapon(int weaponIndex)
    {
        if (TransWeaponIndex[weaponIndex] < 0)
            Debug.Log("없는 무기 호출");
        // TODO: 없는 무기 호출시 에러! 제대로 작성
        Debug.Log(TransWeaponIndex[weaponIndex]);
        Debug.Log(Weapons[TransWeaponIndex[weaponIndex]]);
        return Weapons[TransWeaponIndex[weaponIndex]];
    }
    public void UpgradeWeapon(int weaponIndex)
    {
        Weapons[TransWeaponIndex[weaponIndex]].Upgrade();
        if (Weapons[TransWeaponIndex[weaponIndex]].IsMaster())
        {
            MasteredWeapons.Add(weaponIndex);
        }
    }
    public void GetAccessory(int accessoryIndex)
    {
        TransAccessoryIndex[accessoryIndex] = Accessories.Count;
        Accessories.Add(new Accessory(accessoryIndex));
        UpgradeAccessory(accessoryIndex);
        GameManager.instance.AccessorySlot.GetComponent<SlotUI>().AddSlot(accessoryIndex, 1);
    }
    public void UpgradeAccessory(int accessoryIndex)
    {
        Accessories[TransAccessoryIndex[accessoryIndex]].Upgrade();
        if (Accessories[TransAccessoryIndex[accessoryIndex]].IsMaster())
        {
            MasteredAccessories.Add(accessoryIndex);
        }
    }
    private void ProcessWeaponSub(int weaponIndex, Weapon weapon)
    {
        switch(weaponIndex) 
        {
            case 7: // peachOne
                weapon.GetComponent<Peachone>().SpawnBlueBird(SkillFiringSystem.instance.Birds[0]);
                break;
            case 8: // ebonyWings
                weapon.GetComponent<EbonyWings>().SpawnBlackBird(SkillFiringSystem.instance.Birds[1]);
                break;
        }
    }
    private void AddNewWeapon(int weaponIndex)
    {
        switch (weaponIndex)
        {
            case 0: // Whip
                Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<Whip>());
                break;
            case 1: // MagicWand
                Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<MagicWand>());
                break;
            case 2: // Knife
                Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<Knife>());
                break;
            case 3: // Cross
                Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<Cross>());
                break;
            case 4: // KingBible
                Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<KingBible>());
                break;
            case 5: // FireWand
                Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<FireWand>());
                break;
            case 6: // Garlic
                Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<Gralic>());
                break;
            case 7: // peachOne
                Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<Peachone>());
                break;
            case 8: // ebonyWings
                Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<EbonyWings>());
                break;
            case 9: // LightningRing
                Weapons.Add((SkillFiringSystem.instance.weaponPrefabs[weaponIndex]).GetComponent<LightningRing>());
                break;
        }
    }
    private void ApplyWeapon(int weaponIndex, int hasWeapon)
    {
        if (hasWeapon == 0)
            SetNewWeapon(weaponIndex);
        else
            UpgradeWeapon(weaponIndex);
    }
    private void ApplyAccessory(int accessoryIndex, int hasAccessory)
    {
        if (hasAccessory == 0)
            GetAccessory(accessoryIndex);
        else
            UpgradeAccessory(accessoryIndex);
    }
    private void ApplyEtc(int etcIndex)
    {
        switch ((Enums.EEtc)etcIndex)
        {
            case Enums.EEtc.Food:
                // TODO: 체력 회복 함수와 연결
                break;
            case Enums.EEtc.Money:
                // TODO: 재화 획득 함수와 연결
                break;
            default:
                break;
        }
    }
}
Clone this wiki locally