using UnityEngine;
using System.Collections.Generic;//<= 제네릭 필수!
using System.Collections;//<=코루틴을 적용하는데 필요
using TMPro;//<=텍스트 매쉬 프로 전용 using
public class DialogueManager : MonoBehaviour
{
public static DialogueManager instance;//씬을 이동하더라도 인스턴스로 남게 함
#region Singleton
private void Awake()
{
if (instance == null)
{
DontDestroyOnLoad(this.gameObject);
instance = this;
}
else
{
Destroy(this.gameObject);
}
}
#endregion Singleton
public TMP_Text text;//텍스트 메쉬 프로로 작성
public SpriteRenderer rendererSprite;//캐릭터 스프라이트 조절
public SpriteRenderer rendererDialoguWindow;//다이어로그 윈도우 조절
public List<string> listSentences;
public List<Sprite> listSprites;
public List<Sprite> listDialogueWindows;//리스트 형으로 대화창 실행불러오기
private int count;// 대화진행 상황
public Animator animSprite;//캐릭터 애니메이션
public Animator animDialogueWindow;//다이어로그 애니메이션
public string typeSound;//사운드 이름
public string enterSound;//사운드 이름
private AudioManager theAudio;//오디오 메니져 불러오기
public bool talking = false;//bool값으로 대화
public bool keyActivated = false;//bool값으로 키 입력 방지
//private OrderManager theOrder;오더 메니져 불러오기
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
count = 0;
text.text = "";
listSentences = new List<string>();
listSprites = new List<Sprite>();
listDialogueWindows = new List<Sprite>();
theAudio = FindAnyObjectByType<AudioManager>();
//theOrder = FindAnyObjectByType<OrderManager>();
//각종 변수 초기화와 컴포넌트 불러오기
}
public void ShowDialogue(Dialogue dialogue)//다이어로그 실행
{
talking = true;
//theOrder.NotMove();//오더메니져에서 움직임 실행 정지
for (int i = 0; i < dialogue.sentences.Length; i++)
{
listSentences.Add(dialogue.sentences[i]); //대사
listSprites.Add(dialogue.sprites[i]); //캐릭터 이미지
listDialogueWindows.Add(dialogue.dialogueWindows[i]); //대사창
}
animSprite.SetBool("Appear", true);
animDialogueWindow.SetBool("Appear", true); //애니메이터 파라메터 조작
StartCoroutine(StartDialogueCoroutine()); //코루틴 실행
}
public void ExitDialogue()//대화창 종료
{
text.text = "";
count = 0;
listSentences.Clear();
listSprites.Clear();
listDialogueWindows.Clear();
animSprite.SetBool("Appear", false);
animDialogueWindow.SetBool("Appear", false);
talking = false;
//theOrder.Move();//종료하면서 각종 변수와 코루틴 초기화,이벤트에서 관리하게 변경
}
IEnumerator StartDialogueCoroutine()//대화창 실행
{
if (count > 0)//대사 카운트가 0보다 크면
{
if (listDialogueWindows[count] != listDialogueWindows[count - 1])//바로 전 다이어로그와 비교
{
animSprite.SetBool("Change", true);
animDialogueWindow.SetBool("Appear", false); //파라메터 조작
yield return new WaitForSeconds(0.2f); //코루틴 대기
rendererDialoguWindow.GetComponent<SpriteRenderer>().sprite = listDialogueWindows[count];
rendererSprite.GetComponent<SpriteRenderer>().sprite = listSprites[count]; //컴포넌트 불러오기
animDialogueWindow.SetBool("Appear", true);
animSprite.SetBool("Change", false);
}
else//조건문으로 만약을 실행
{
if (listSprites[count] != listSprites[count - 1])//바로 전 캐릭터 이미지와 비교
{
animSprite.SetBool("Change", true);
yield return new WaitForSeconds(0.1f);
rendererSprite.GetComponent<SpriteRenderer>().sprite = listSprites[count];
animSprite.SetBool("Change", false);
}
else
{
yield return new WaitForSeconds(0.05f);
}
}
}
else
{
rendererDialoguWindow.GetComponent<SpriteRenderer>().sprite = listDialogueWindows[count];
rendererSprite.GetComponent<SpriteRenderer>().sprite = listSprites[count];
}
keyActivated = true;//키입력 방지
for (int i = 0; i < listSentences[count].Length; i++)
{
text.text += listSentences[count][i];//첫번째 문장에 가나다라 마바사가 있다면 한글자씩 출력
if(i % 7 == 1)
{
theAudio.Play(typeSound);//대사창이 움직일때 오디오 실행
}
yield return new WaitForSeconds(0.01f);
}
}
// Update is called once per frame
void Update()
{
if (talking && keyActivated)//조건문으로 키입력 방지와 대화 시작
{
if (Input.GetKeyDown(KeyCode.Z))//Z키 클릭
{
keyActivated = false;
count++;
text.text = "";
theAudio.Play(enterSound);//각종 초기화
if (count == listSentences.Count)//대화창 코루틴 실행
{
StopAllCoroutines(); //모든 코뤁틴 정지
ExitDialogue(); //대사 코루틴 나가기
}
else
{
StopAllCoroutines(); //모든 코루틴 정지
StartCoroutine(StartDialogueCoroutine());//대사 코루틴 시작
}
}
}
}
}
using System.Collections;
using UnityEngine;
public class Event1 : MonoBehaviour
{
public Dialogue dialogue_1;
public Dialogue dialogue_2;
private DialogueManager theDM;
private OrderManager theOrder;
private PlayerManager thePlayer;// animator.getFloat "DirY"==1f;위를 바라볼때
private bool flag;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
theDM = FindAnyObjectByType<DialogueManager>();//다이어로그 찾아오기
theOrder = FindAnyObjectByType<OrderManager>();//오더메니져 찾아오기
thePlayer = FindAnyObjectByType<PlayerManager>();//플레이어 매니져 찾아오기
}
private void OnTriggerStay2D(Collider2D collision)
{
if (!flag && Input.GetKey(KeyCode.Z) && thePlayer.animator.GetFloat("DirY") == 1f)
//조건문 플레그가 flase이면서 z키를 입력하고 캐릭터가 보는 방향이 위일때
{
flag = true;
StartCoroutine(EventCoroutine());
}
}
IEnumerator EventCoroutine()
{
theOrder.PreLoadCharacter();
yield return new WaitUntil(() => !theDM.talking);
theOrder.NotMove();
theDM.ShowDialogue(dialogue_1);
theOrder.Move("Player", "RIGHT");
theOrder.Move("Player", "RIGHT");
theOrder.Move("Player", "UP");
yield return new WaitUntil(() => thePlayer.queue.Count == 0);
theDM.ShowDialogue(dialogue_2);
yield return new WaitUntil(() => !theDM.talking);
theOrder.Move();
}
}
이번 시간은 좀 쉬어가는 시간이다
Event1이라는 스크립트를 만들어 준다
첫번째로 작성할 부분은 다이어로그 1,2를 등록할 수 있게 커스텀 이벤트를 만들어준다
그리고 그 아래 9~11줄까지는 필요한 컴포넌트를 불러와 준다
그뒤 void Start()에 장착한다
그 뒤 플레그가 아니면서 Z키를 누르고 플레이어 캐릭터가 위를 바라보면이라는 조건을 달아준다
그 뒤 flag를 true로 바꿔주고 코루틴을 실행한다
32번 줄부터는 코루틴이다
일단 캐릭터에게 할당한 이름이 있기 때문에 theOrder.PreLoadCharacter을 작성해준다
그뒤 theOrder.NotMove()를 호출해 준다
그리고 우리는 DialogueManager에서 the.Order.NotMove()를 실행하게 했는데 이제 이 부분을 지워주고 Event1에서 조작하게 한다
필자가 보여준 스샷의 64번째 줄이다
그리고 당연히 우리가 OrderManager을 불러오는 함수도 정지해준다
45번 줄과 56번 줄이다
Event1으로 다시 돌아와서
ShowDialogue(dialogue_1) 을 실행하고 캐릭터 움직임을 어떻게 할지 작성해준다
그뒤 큐가 다 완료될때까지 기다리고
ShowDialogue(dialogue_2)가 실행되게 한다
그뒤 WaitUntil로 리턴문을 작성 종료해준다
이제 빈 오브젝트에 Event1을 넣어주고 표지판에서 애니메이션을 실행하게 한다
이제 완성이 됬다
ps.
이번 강좌는 정말 쉬어가기네요
대사창에서 시간을 너무 잡아먹어서...
글을 읽으신 분들은 모르실 수 있는데 전에 올린 대사창은 한 일주일 공부한 것 같습니다
'쯔꾸르식 유니티 게임 공부' 카테고리의 다른 글
16.날씨효과 (0) | 2025.02.04 |
---|---|
15.페이드 & 플레시 연출 (0) | 2025.01.24 |
13.대화시스템 (0) | 2025.01.21 |
12.NPC 충돌방지(Box콜라이더 이동) (0) | 2025.01.16 |
11.이벤트 캐릭터 이동명령 이벤트 (0) | 2025.01.15 |