이번에는 Event시스템을 만들어보겠습니다.
이벤트 특성상 글이 많이 나오기때문에, 글을 각 나라의 언어로 번역하는것이 중요합니다.
그렇게 하기 위해서 해야하는 일 들은 여러가지가 있습니다.
유니티에서는 밑의 두 가지 일을 간단하게 할 수있도록 패키지를 제공하고 있습니다.
따라서, 유니티의 Localization 시스템을 사용해서 이벤트 시스템을 구현해보겠습니다.
https://docs.unity3d.com/Packages/com.unity.localization@1.0/manual/index.html
미리 만들어둔 카드부터 시작해보겠습니다.

Name과 Description에 Localization을 적용해주고

테이블의 Save.. 를 통해서 csv파일로 저장한 다음 내용을 채워넣습니다.

이제 이 내용을 실제로 카드에 집어넣어야 합니다.
Json에서 문자열로 관리하던 Name과 Desc를 id 하나로 처리하도록 바꿔줍니다.
{
"cardInfo": [
{
"cardId": 1,
"cardType": 1,
"cardCost": 2,
"duration": 5,
"value": 2
},
{
"cardId": 2,
"cardType": 1,
"cardCost": 1,
"duration": 4,
"value": 1
},
{
"cardId": 3,
"cardType": 1,
"cardCost": 1,
"duration": 4.5,
"value": 1
},
{
"cardId": 4,
"cardType": 0,
"cardCost": 1,
"duration": 1,
"value": 1
},
{
"cardId": 5,
"cardType": 0,
"cardCost": 1,
"duration": 1,
"value": 1
}
]
}
[Serializable]
public class CardInfo
{
public int cardId;
public int cardCost;
public Define.CardType cardType;
public float duration;
public float value;
}
[Serializable]
public class CardInfos
{
public CardInfo[] cardInfo;
}
public class ResourceManager
{
private string cardInfoPath = "JsonData/CardData";
private CardInfos cardInfos = new CardInfos();
private GameObject[] cardPrefabs;
const int CARDOFFSET = 1;
public void Init()
{
cardInfos = JsonUtility.FromJson<CardInfos>(Resources.Load<TextAsset>(cardInfoPath).text);
cardPrefabs = Resources.LoadAll<GameObject>("Prefabs/Card");
}
// Getter...
}
이런식으로 Json을 받아오고 id를 받으면 해당 CardInfo를 반환하는 Getter를 둡니다.
그리고 CardBase의 SetCard에서 ResouceManager의 데이터를 받아 처리합니다.
public void SetCard(int id)
{
var cardInfo = Managers.Resource.GetCardInfo(id);
this.cardId = cardInfo.cardId;
this.cardCost = cardInfo.cardCost;
this.cardType = cardInfo.cardType;
cardCostText.text = cardInfo.cardCost.ToString();
cardName.GetComponent<LocalizeStringEvent>().StringReference.SetReference("CardInfoTable", (cardInfo.cardId * 100 + 0).ToString());
cardDesc.GetComponent<LocalizeStringEvent>().StringReference.SetReference("CardInfoTable", (cardInfo.cardId * 100 + 1).ToString());
}



에디터 우측 상단에 떠있는 English (en) 부분으로 언어를 설정할 수 있습니다.
스크립트 상에서 설정하려면
LocalizationSettings.SelectedLocale = LocalizationSettings.AvailableLocales.Locales[index];
이런식으로 설정하면 됩니다.
이제 Localization을 활용해서 Dialog 시스템을 만들어보겠습니다.

간단하게 에셋을 사용해서 꾸며줍니다.
왼쪽 위에 어색하게 떠있는 투구는 황금고블린 스프라이트가 없어서 대체로 놔둔 이미지입니다.
구현해야 할 것들을 정리해보겠습니다.
우선 위 두 개부터 구현해보도록 하겠습니다.
[Serializable]
public class DialogEventInfo {
public int eventID;
public int eventActor;
public int eventDialogCnt;
public int eventSelectCnt;
}
json파일로 eventInfo를 저장해주고 ResourceManager에서 불러와줍니다.
private void Update()
{
if (Input.GetKeyDown(KeyCode.E))
{
if (!dialogInProgress) SetEvent(1);
else UnsetEvent();
}
if (Input.GetKeyDown(KeyCode.Space) && dialogInProgress)
{
if (isTyping)
{
StopAllCoroutines();
dialogText.text = prevDialogue;
isTyping = false;
}
else
{
if (curLineIndex < dialogKeys.Count) {
prevDialogue = LocalizationSettings.StringDatabase.GetLocalizedString("DialogInfo", dialogKeys[curLineIndex]);
ShowNextLine();
}
else
{
if (!selectinProgress)
{
MakeSelection();
// 여기 이벤트 선택지 생성하면됨
}
}
}
}
}
E를 누르면 Event를 설정합니다. 이 때 dialogKeys와 ActorName 등 설정할 부분을 미리 설정하고 대화창을 화면에 띄워줍니다.
시작할 때 번역된 대사를 preDialogue 에 저장해두고 ShowNextLine() 내부에서 코루틴을 실행합니다.
만약 대사중에 Space를 누르면 코루틴을 멈추고 저장해뒀던 대사를 전부 출력합니다.
위에서는 SetReference 를 사용했고 여기서는 GetLocalizedString을 사용했는데, 이름에서 알 수 있듯이 SetReference는 언어 설정이 바뀔때 번역이 실시간으로 적용되고 GetLocalizedString은 문자열을 받아온 것이기 때문에 대사가 생성되고 나서 언어 설정이 바뀌어도 대사가 바뀌지 않습니다.
아래는 실행화면 입니다.

카드에 Unity Localization을 적용하고 Dialog 시스템을 만들었습니다.
특히 DOTween을 사용해서 대화창이나 버튼들이 움직이는 효과를 빠르게 만들 수 있었습니다.
다음에는 선택지를 띄우고 선택한 선택지에 따라 다른 함수가 실행되도록 만들어보겠습니다.
https://docs.unity3d.com/Packages/com.unity.localization@1.0/manual/index.html