뱀파이어 서바이벌, 탕탕특공대, 롤토체스, 궁수의 전설 등의 게임처럼
능력치를 업그레이드 할 수 있는 증강 선택지를 띄워주는 기능이다.
1. 기존 아래 이미지처럼 인스펙터 창에 증강의 선택지로 사용할 오브젝트를 넣어 관리했던 스크립트:
using Assets.HeroEditor.Common.Scripts.Common;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System.Text;
public class Augmentation : SingletonPattern.Singleton<Augmentation>
{
[SerializeField] GameObject mainObject;
[SerializeField] AugmentEffect augmentEffect;
AugmentEffect AugmentEffect => augmentEffect;
[SerializeField] Augmentation_Objects[] augmentation_Objects;
List<GameObject> showList = new List<GameObject>();
const int Augmentation_Count = 3; //띄워질 증강 개수
public Dictionary<int, Action> AugmentationDict = new();
public Dictionary<E_SpecialAbilityType, double> AugementStat = new(); //증강 효과 넘겨주는 Dict
//<---ID내규--->
//0-99 : C랭크
//100- 199 : B랭크
//200- 299 : A랭크
public void Init()
{
ClearUI();
UpdateDict(0, AugmentEffect.ID_0_Effect);
UpdateDict(1, AugmentEffect.ID_1_Effect);
UpdateDict(2, AugmentEffect.ID_2_Effect);
UpdateDict(3, AugmentEffect.ID_3_Effect);
UpdateDict(4, AugmentEffect.ID_4_Effect);
UpdateDict(100, AugmentEffect.ID_100_Effect);
UpdateDict(101, AugmentEffect.ID_101_Effect);
UpdateDict(102, AugmentEffect.ID_102_Effect);
UpdateDict(103, AugmentEffect.ID_103_Effect);
UpdateDict(104, AugmentEffect.ID_104_Effect);
UpdateDict(200, AugmentEffect.ID_200_Effect);
UpdateDict(201, AugmentEffect.ID_201_Effect);
UpdateDict(202, AugmentEffect.ID_202_Effect);
UpdateDict(203, AugmentEffect.ID_203_Effect);
UpdateDict(204, AugmentEffect.ID_204_Effect);
}
public double GetValue_AugementStat(E_SpecialAbilityType e_TalentAbility)
{
if (!AugementStat.ContainsKey(e_TalentAbility))
{
Debug.Log("Not Contains Key");
return 0;
}
return AugementStat[e_TalentAbility];
}
public void SetValue_AugementStat(E_SpecialAbilityType e_CharacterAbility, double value)
{
if (!AugementStat.ContainsKey(e_CharacterAbility))
{
AugementStat.Add(e_CharacterAbility, value);
}
else
{
AugementStat[e_CharacterAbility] += value;
}
}
public void ClearUI()
{
mainObject.SetActive(false);
foreach (GameObject obj in showList)
{
obj.SetActive(false);
}
showList.Clear();
}
public void ActiveAugment(int id) //증강 버튼 클릭 시 호출
{
if (AugmentationDict.ContainsKey(id))
{
AugmentationDict[id]();
InGameManager.Instance.ResumeGame();
ClearUI();
}
else
{
Debug.LogError("Input Undefined Augementaion ID");
}
}
/// <summary>
/// C랭크, B랭크, A랭크 순서로 3가지 가능성 넘길 것. 합산 1이되어야 함
/// </summary>
/// <param name="possibility"></param>
public void ShowAugmentation(float[] possibility) //4,8,12,16라운드마다 띄워준다면 해당 라운드마다 등급별 가능성을 넘겨주어 레벨디자인하기 편하게
{
if(possibility.Length < 3)
{
Debug.LogWarning("Augment Rank possibility(float[]) has been changed to (0.7,0.2,0.1) because of parameters doesn't follow appointed ruels");
possibility = new float[3] {0.7f, 0.2f, 0.1f};
}
int result = Util.GetWeightedRandomIndex(possibility);
StringBuilder sb = new StringBuilder();
foreach (float f in possibility)
{
sb.Append(f + " ");
}
Debug.Log("AugmentRank is " + sb);
SelectAugementation(GetObjectsWithTargetRank((AugmentationRank)result));
foreach (GameObject obj in showList)
{
obj.SetActive(true);
}
mainObject.SetActive(true);
}
public GameObject[] GetObjectsWithTargetRank(AugmentationRank targetRank) //augmentation_Objects에서 매개변수로 받은 랭크에 해당하는 GameObject[]반환
{
GameObject[] objectsWithTargetRank = augmentation_Objects
.Where(augmentation => augmentation.Rank == targetRank)
.SelectMany(augmentation => augmentation.Object)
.ToArray();
return objectsWithTargetRank;
}
public void SelectAugementation(GameObject[] objects) //특정 랭크에 해당하는 GameObject[]를 받은 후 3개 랜덤으로 띄워줌
{
while (showList.Count < Augmentation_Count)
{
int randIndex = UnityEngine.Random.Range(0, objects.Length);
if (!showList.Contains(objects[randIndex]))
{
showList.Add(objects[randIndex]);
}
}
}
public void UpdateDict(int id, Action action)
{
AugmentationDict.Add(id, action);
}
}
[Serializable]
public struct Augmentation_Objects
{
public GameObject[] Object;
public AugmentationRank Rank;
}
public enum AugmentationRank
{
C = 0,
B = 1,
A = 2
}
public class AugmentEffect(){
public void ID_01_Effect(){
//
}
}
2.
위 방법은 증강 가짓수 만큼 각각 오브젝트를 만들어 사용하여 데이터를 활용하는 목적이 아니라
번역시스템, 추가 증강 등의 유지보수가 어려우므로 스크립트 제어 방향성으로 개선
- 하나의 프리팹으로 관리하고 프리팹의 생성자 Init()에서 이미지링크, 제목, 설명, 실행되어야할 Action을 받아 생성.
- 기존 DIctionary에 추가하여 사용했던 AugmentationEffect 메소드들을 Action으로 넘김
- 엑셀 데이터 활용하여 번역 시스템 추가
using Assets.HeroEditor.Common.Scripts.Common;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System.Text;
using UnityEditor;
public class Augmentation : SingletonPattern.Singleton<Augmentation>
{
[SerializeField] GameObject mainObject;
[SerializeField] GameObject targetObject;
[SerializeField] AugmentationPrefab augmentationPrefab;
[SerializeField] AugmentEffect augmentEffect;
AugmentEffect AugmentEffect => augmentEffect;
private List<PrefabValue> showList = new();
public const int Augmentation_Count = 3; //띄워질 증강 개수
public Dictionary<E_SpecialAbilityType, double> AugementStat = new(); //증강 효과 넘겨주는 Dict
PrefabValue[] prefabValues = new PrefabValue[15];
public double GetValue_AugementStat(E_SpecialAbilityType e_TalentAbility)
{
if (!AugementStat.ContainsKey(e_TalentAbility))
{
Debug.Log("Not Contains Key");
return 0;
}
return AugementStat[e_TalentAbility];
}
public void SetValue_AugementStat(E_SpecialAbilityType e_CharacterAbility, double value)
{
if (!AugementStat.ContainsKey(e_CharacterAbility))
{
AugementStat.Add(e_CharacterAbility, value);
}
else
{
AugementStat[e_CharacterAbility] += value;
}
}
public void ClearUI()
{
mainObject.SetActive(false);
Transform[] childTransforms = targetObject.GetComponentsInChildren<Transform>();
foreach(Transform child in childTransforms)
{
if(child.gameObject != targetObject)
{
Destroy(child.gameObject);
}
}
}
/// <summary>
/// C랭크, B랭크, A랭크 순서로 3가지 가능성 넘길 것. 합산 1이되어야 함
/// </summary>
/// <param name="possibility"></param>
public void ShowAugmentation(float[] possibility) //4,8,12,16라운드마다 띄워준다면 해당 라운드마다 등급별 가능성을 넘겨주어 레벨디자인하기 편하게
{
if(possibility.Length < 3)
{
Debug.LogWarning("Augment Rank possibility(float[]) has been changed to (0.7,0.2,0.1) because of parameters doesn't follow appointed ruels");
possibility = new float[3] {0.7f, 0.2f, 0.1f};
}
int result = Util.GetWeightedRandomIndex(possibility);
//로그파트
StringBuilder sb = new StringBuilder();
foreach (float f in possibility)
{
sb.Append(f + " ");
}
Debug.Log("AugmentRank is " + sb);
SelectAugementation((AugmentationRank)result);
mainObject.SetActive(true);
CreatePrefab();
}
public void SelectAugementation(AugmentationRank rank)
{
List<PrefabValue> selected = new();
foreach (PrefabValue prefab in prefabValues)
{
if (prefab.Rank == rank)
{
selected.Add(prefab);
}
}
while (showList.Count < Augmentation_Count)
{
int randIndex = UnityEngine.Random.Range(0, selected.Count);
if (!showList.Contains(selected[randIndex]))
{
showList.Add(selected[randIndex]);
}
}
selected.Clear();
}
public void CreatePrefab()
{
foreach(PrefabValue pv in showList)
{
AugmentationPrefab result = Instantiate(augmentationPrefab, targetObject.transform);
result.MakeAP(pv.Rank, pv.ImgLink, pv.TitleTxt, pv.InfoTxt, pv.action);
}
showList.Clear();
}
//<---ID내규--->
//0-99 : C랭크
//100- 199 : B랭크
//200- 299 : A랭크
public void Init()
{
ClearUI();
prefabValues[0] = new PrefabValue(AugmentationRank.C, "Image/Augmentation/AttackPower", Language.AugmentationLoader.Text(2), Language.AugmentationLoader.Text(3), AugmentEffect.ID_0_Effect);
prefabValues[1] = new PrefabValue(AugmentationRank.C, "Image/Augmentation/AttackSpeed", Language.AugmentationLoader.Text(4), Language.AugmentationLoader.Text(5), AugmentEffect.ID_1_Effect);
prefabValues[2] = new PrefabValue(AugmentationRank.C, "Image/Augmentation/Gold", Language.AugmentationLoader.Text(6), Language.AugmentationLoader.Text(7), AugmentEffect.ID_2_Effect);
prefabValues[3] = new PrefabValue(AugmentationRank.C, "Image/Augmentation/Summon", Language.AugmentationLoader.Text(8), Language.AugmentationLoader.Text(9), AugmentEffect.ID_3_Effect);
prefabValues[4] = new PrefabValue(AugmentationRank.C, "Image/Augmentation/Slow", Language.AugmentationLoader.Text(10), Language.AugmentationLoader.Text(11), AugmentEffect.ID_4_Effect);
prefabValues[5] = new PrefabValue(AugmentationRank.B, "Image/Augmentation/AttackPower", Language.AugmentationLoader.Text(12), Language.AugmentationLoader.Text(13), AugmentEffect.ID_100_Effect);
prefabValues[6] = new PrefabValue(AugmentationRank.B, "Image/Augmentation/AttackSpeed", Language.AugmentationLoader.Text(14), Language.AugmentationLoader.Text(15), AugmentEffect.ID_101_Effect);
prefabValues[7] = new PrefabValue(AugmentationRank.B, "Image/Augmentation/Gold", Language.AugmentationLoader.Text(16), Language.AugmentationLoader.Text(17), AugmentEffect.ID_102_Effect);
prefabValues[8] = new PrefabValue(AugmentationRank.B, "Image/Augmentation/Summon", Language.AugmentationLoader.Text(18), Language.AugmentationLoader.Text(19), AugmentEffect.ID_103_Effect);
prefabValues[9] = new PrefabValue(AugmentationRank.B, "Image/Augmentation/Slow", Language.AugmentationLoader.Text(20), Language.AugmentationLoader.Text(21), AugmentEffect.ID_104_Effect);
prefabValues[10] = new PrefabValue(AugmentationRank.A, "Image/Augmentation/AttackPower", Language.AugmentationLoader.Text(22), Language.AugmentationLoader.Text(23), AugmentEffect.ID_200_Effect);
prefabValues[11] = new PrefabValue(AugmentationRank.A, "Image/Augmentation/AttackSpeed", Language.AugmentationLoader.Text(24), Language.AugmentationLoader.Text(25), AugmentEffect.ID_201_Effect);
prefabValues[12] = new PrefabValue(AugmentationRank.A, "Image/Augmentation/Gold", Language.AugmentationLoader.Text(26), Language.AugmentationLoader.Text(27), AugmentEffect.ID_202_Effect);
prefabValues[13] = new PrefabValue(AugmentationRank.A, "Image/Augmentation/Summon", Language.AugmentationLoader.Text(28), Language.AugmentationLoader.Text(29), AugmentEffect.ID_203_Effect);
prefabValues[14] = new PrefabValue(AugmentationRank.A, "Image/Augmentation/Slow", Language.AugmentationLoader.Text(30), Language.AugmentationLoader.Text(31), AugmentEffect.ID_204_Effect);
}
}
public enum AugmentationRank
{
C = 0,
B = 1,
A = 2
}
public class PrefabValue
{
public AugmentationRank Rank;
public string ImgLink;
public string TitleTxt;
public string InfoTxt;
public Action action;
public PrefabValue(AugmentationRank rank, string imgLink, string titleTxt, string infoTxt, Action action)
{
Rank = rank;
ImgLink = imgLink;
TitleTxt = titleTxt;
InfoTxt = infoTxt;
this.action = action;
}
}