[unity] - 2d 탑다운 [ 대화창,초상화,타이핑 이펙트 ]
>TypeEffect 스크립트
public int CharPerSeconds;
public GameObject EndCursor;
public bool isAnim;
TextMeshProUGUI msgText;
AudioSource audioSource;
int index;
float interval;
string targetMsg; //원래 대화저장
CharPerSeconds(CPS)는 초당 몇개의 글자가 나오도록할것인지 저장한다.
isAnim은 애니메이션실행중인지 여부.
msgText는 대화 텍스트를 저장하고, audioSource도 저장해준다.
index는 대화 하나 안에 있는 글자 인덱스이다.
interval은 CPS를 조절하기위한 변수이다.
targetMsg는 원래 대화를 저장해준다.
-Awake에서 초기화를 해준다. 이 초기화는 public으로 선언되지 않은것들을 초기화해주는것.
private void Awake()
{
msgText = GetComponent<TextMeshProUGUI>();
audioSource= GetComponent<AudioSource>();
}
-SetMsg함수
public void SetMsg(string msg)
{
if (isAnim)
{
msgText.text = targetMsg;
CancelInvoke();
EffectEnd();
}
else {
targetMsg = msg;
EffectStart();
}
}
isAnim이 참이라는것은 대화중에 스페이스바 눌러서 대화를 한번에 나타나도록 한다.
Invoke함수를 없애고 대화 하나를 끝내준다.
거짓이면 targetMsg를 msg값으로 저장하고 EffectStart함수를 실행한다.
-EffectStart함수
void EffectStart()
{
msgText.text = "";
index = 0;
EndCursor.SetActive(false);
interval = 1.0f / CharPerSeconds; //따로 변수 만들어서 하는게 좋다
Debug.Log(interval);
isAnim = true;
Invoke("Effecting", interval); //1글자가 나오는 딜레이
}
처음 text와 index를 초기화시켜주고, EndCursor이 나타나지 않게 한다.
interval으로 몇초에 한글자씩 나오게할지 설정한다.
그리고 isAnim을 참으로 바꿔주고 Effecting함수를 실행시켜준다.
이런식으로 한글자씩 나온다.
-Effecting함수
void Effecting()
{
if (msgText.text == targetMsg)
{
EffectEnd();
return;
}
msgText.text += targetMsg[index];
//sound
if (targetMsg[index]!=' '|| targetMsg[index]!='.')
audioSource.Play();
index++;
Invoke("Effecting", interval);
}
text가 원하는 대화랑 똑같아지면 End함수 실행해주고 바로 함수를 종료시킨다.
아니라면 한글자를 더해준다.
소리는 공백이나 . 글자가 아닐때만 재생시켜주고 난뒤 index를 증가시킨다.
그리고 재귀함수를 실행시킨다.
-EffectEnd 함수
void EffectEnd()
{
isAnim = false;
EndCursor.SetActive(true);
}
isAnim을 거짓으로 바꾸고 EndCursor이 보이게 한다. ( 대화창에서 역삼각형모양 )
-----GameManager 수정----
public Animator talkPanel;
public Animator portraitAnim;
public TypeEffect talk;
public Sprite prevPortrait; //과거 스프라이트
talkPanel과 초상화가 위아래로 움직이게 하기 위해서 Animator의 객체로 선언한다.
TypeEffect라는 클래스의 talk객체를 선언한다.
prevPortrait라는 과거 스프라이트를 저장한다.
-Action함수 수정
public void Action(GameObject scanObj)
{
isAction = true;
scanObject = scanObj;
ObjData objData = scanObj.GetComponent<ObjData>();
Talk(objData.id, objData.isNpc);
talkPanel.SetBool("isShow",isAction);
}
Action여부에 따라 대화창이 보이거나 사라지도록한다.
has exit time 체크하면 (trigger일때) 굳이 conditions안해도된다. 알아서 빠져나온다.
-Talk함수
//set talk data
int questTalkIndex = 0;
string talkData = "";
if (talk.isAnim) {
talk.SetMsg("");
return;
}
else
{
questTalkIndex = questManager.GetQuestTalkIndex(id);
talkData = talkManager.GetTalk(id + questTalkIndex, talkIndex);
}
questTalkIndex와 talkData를 선언과 함께 초기화를해준다.
isAnim이 참이면 바로 대화를 다 보여주고 한 대화를 끝내버린다.
아니면 원래처럼 대화가 나온다.
if (isNpc)
{
talk.SetMsg(talkData.Split(':')[0]);
//show portrait
portraitImg.sprite= talkManager.GetPortrait(id,int.Parse(talkData.Split(':')[1]));//문자열을 해당타입으로 변환
portraitImg.color = new Color(1, 1, 1, 1);
//animation Portrait
if(prevPortrait!= portraitImg.sprite) {
portraitAnim.SetTrigger("doEffect");
prevPortrait = portraitImg.sprite;
}
}
else
{
talk.SetMsg(talkData);
portraitImg.color = new Color(1, 1, 1, 0);
}
메시지를 SetMsg로 저장한다.
아래 두줄은 똑같다.
만약 바로 전 초상화와 지금 초상화가 다를때 doEffect트리거를 실행하고 전 초상화에 지금 초상화를 저장한다.
y값이 바뀐것을 알수있다.
위아래를 조금씩 이동한다.