using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerManager : MovingObjcet
{
static public PlayerManager instance;
//public string currentMapName;
public string walkSound_1;
public string walkSound_2;
public string walkSound_3;
public string walkSound_4;
private AudioManager theAudio;
//public AudioClip walkSound_1;//사운드 파일
//public AudioClip walkSound_2;
private AudioSource audioSource;//사운드 플레이어
//뛰기,평범하게 걷기
public float runSpeed;
private float applyRunSpeed;
private bool applyRunFlag = false;
public bool notMove = false;//이벤트 실행시 움직임 정지
//한칸한칸 이동할때 플레그 형식으로 구현
private bool canMove = true;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
if (instance == null)
{
queue = new Queue<string>();
DontDestroyOnLoad(this.gameObject);
boxCollider = GetComponent<BoxCollider2D>();
//audioSource = GetComponent<AudioSource>();
animator = GetComponent<Animator>();
theAudio = FindAnyObjectByType<AudioManager>();
instance = this;
}
else
{
Destroy(this.gameObject);
}
}
//코루틴으로 이동제어 한칸 한칸 이동하게
IEnumerator MoveCoroutine()
{
while (Input.GetAxisRaw("Vertical") != 0 || Input.GetAxisRaw("Horizontal") != 0 && !notMove)
{
//시프트 키 입력 여부에 따라 뛰기 걷기 구분
if (Input.GetKey(KeyCode.LeftShift))
{
applyRunSpeed = runSpeed;
applyRunFlag = true;
}
else
{
applyRunSpeed = 0;
applyRunFlag = false;
}
//이동방향 벡터 움직임 구현
vector.Set(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"), transform.position.z);
//좌상,좌하 등 대각선 방향이동 장금
if (vector.x != 0)
vector.y = 0;
//에니메이터 불러오기
animator.SetFloat("DirX", vector.x);
animator.SetFloat("DirY", vector.y);
bool checkCollsionFlag = base.CheckCollsion();
if (checkCollsionFlag)
break;
animator.SetBool("Walking", true);
int temp = Random.Range(1, 4);
switch (temp)
{
case 1:
theAudio.Play(walkSound_1);
break;
case 2:
theAudio.Play(walkSound_2);
break;
case 3:
theAudio.Play(walkSound_3);
break;
case 4:
theAudio.Play(walkSound_4);
break;
}
theAudio.SetVolumn(walkSound_2, 0.5f);
boxCollider.offset = new Vector2(vector.x * 0.02f * speed * walkCount, vector.y * 0.02f * speed * walkCount);//박스콜라이더를 미리 옮겨서 충돌방지
//캐릭터 이동구현 코드
while (currentWalkCount < walkCount)
{
if (vector.x != 0)
{
//Translate는 현제 값에서 +를 해주는 코드
transform.Translate(vector.x * (speed + applyRunSpeed), 0, 0);
}
else if (vector.y != 0)
{
transform.Translate(0, vector.y * (speed + applyRunSpeed), 0);
}
if (applyRunFlag)
currentWalkCount++;//위의 applyRunFlas가 되면 추가되는 카운트 만약 아니라면 더해지지 않음
currentWalkCount++;//위의 카운트와는 별개의 카운트로 구분 됨
if (currentWalkCount == 12)
boxCollider.offset = Vector2.zero;//박스콜라이더를 원위치하여 충돌방지
yield return new WaitForSeconds(0.01f);//0.01초마다 대기
/*if(currentWalkCount % 9 == 2)
{
int temp = Random.Range(1, 2);
switch (temp)
{
case 1:
//audioSource.clip = walkSound_1;
//audioSource.Play();
break;
case 2:
//audioSource.clip = walkSound_2;
//audioSource.Play();
break;
}
}*/
}
currentWalkCount = 0;//0을 넣어서 반복문 초기화
}
animator.SetBool("Walking", false);
//한칸한칸 이동할때 bool값
canMove = true;
}
//매 프레임마다 이동명령을 받음
void Update()
{
if (canMove && !notMove)
{
//이동 방향키 입력을 할때 쯔구르 처럼 상하좌우 구분하게 하는 코드
if (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0)
{
//한칸 한칸 이동할때 bool값으로 canMove를 이용함
canMove = false;
StartCoroutine(MoveCoroutine());
}
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OrderManager : MonoBehaviour
{
private PlayerManager thePlayer;//이벤트 중 키 입력 방지
private List<MovingObjcet> characters;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
thePlayer = FindAnyObjectByType<PlayerManager>();
}
public void PreLoadCharacter()
{
characters = ToList();
}
public List<MovingObjcet> ToList()
{
List<MovingObjcet> tempList = new List<MovingObjcet>();
MovingObjcet[] temp = FindObjectsByType<MovingObjcet>(FindObjectsSortMode.None);
for (int i = 0; i < temp.Length; i++)
{
tempList.Add(temp[i]);
}
return tempList;//이 함수가 없어서 null이 나온다
}
public void NotMove()
{
thePlayer.notMove = true;
}
public void Move()
{
thePlayer.notMove = false;
}
public void Turn(string _name, string _dir)
{
for (int i = 0; i < characters.Count; i++)
{
if (_name == characters[i].characterName)
{
characters[i].animator.SetFloat("DirY", 0f);
characters[i].animator.SetFloat("DirX", 0f);
switch (_dir)
{
case "UP":
characters[i].animator.SetFloat("DirY", 1f);
break;
case "DOWN":
characters[i].animator.SetFloat("DirY", -1f);
break;
case "LEFT":
characters[i].animator.SetFloat("DirX", -1f);
break;
case "RIGHT":
characters[i].animator.SetFloat("DirX", 1f);
break;
}
}
}
}
public void Move(string _name, string _dir)
{
for (int i = 0; i < characters.Count; i++)
{
if (_name == characters[i].characterName)
{
characters[i].Move(_dir);
}
}
}
}
using UnityEngine;
public class TestDialogue : MonoBehaviour
{
[SerializeField]
public Dialogue dialogue;
private DialogueManager theDM;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
theDM = FindAnyObjectByType<DialogueManager>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.T))//T키 입력으로 대사창 실행
{
theDM.ShowDialogue(dialogue);
}
}
//private void OnTriggerEnter2D(Collider2D collision)
//{
// if (collision.gameObject.name == "Player")
// {
// theDM.ShowDialogue(dialogue);
// }
//}
}
using UnityEngine;
[System.Serializable]//커스텀 변수 실행용
public class Dialogue //다이어로그 클레스
{
[TextArea(1,2)]
public string[] sentences; //대사창 문장 조작
public Sprite[] sprites; //캐릭터 이미지 조작
public Sprite[] dialogueWindows; //다이어로그 이미지 조작
}
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());//대사 코루틴 시작
}
}
}
}
}
일단 UI를 만들기 위해서는 하이러키에 UI > Canvas 클릭한다
Canvas를 만들면 EventSystem이 만들어지는데 이건 무시하고 밖으로 빼 놓는다
유니티엔진에서는 UI를 만들어서 화면에 표시되는 메인메뉴나 스크린을 만들어 낸다 이걸 꼭 명심하자
처음 캔버스를 만들면
Screen Space - Overlay로 체크가 되어 있을 것이다
이 뜻은
카메라 영역에 UI가 표시되는게 아니라
다른 영역으로 UI가 표시 되더라도 화면에 나오게 한단는 뜻이다
하지만 우리는 Camera 영역에 직접 표시되게 할 것이다
Screen Space - Camera로 변경해주자
그리고 인스펙터에 메인카메라를 드레그해서 슬롯에 넣어주자
이렇게 되면 카메라가 캔버스가 된다
그리고 캔버스를 UI로 세팅해주자
기본값으로 들어가 있으니 선택해주자
캔버스 옵션에 UI, Order in Layer은 2로 세팅해주자
Order in Layer은 이미지가 겹칠 경우 따로 보이는 우선 순위를 세팅해 준 것이다
그리고 아래의 Canvas Scaler 스크린의 경우 Scal With Screen Size로 바꿔주자
Constant Pixl Size는 UI가 원래 사이즈대로 나오게 하는 것이고
선택한 Scale With Screen Size는 화면의 크기에 따라 이미지의 크기도 변경해주는 옵션이다
강좌의 UI에셋들은 960 * 540에 맞춰서 디자인 되어 있다 위 처럼 Reference Resolution 값을 수정해주자
Canvas의 세팅이 끝났다면 빈 객체를 만들어주고 Dialogue Manager을 만들어주자
그리고 Hierarchy에 Dialogue - basic와 Haon A - 1 넣어주자
그리고 간혹 이미지 사이즈가 작게나오는 경우가 있는데
원본이 되는 이미지의 Pixels Per Unit를 1로 바꿔주고 Filter Mode르 Point로 바꿔주자
그리고 Dialogue - basic는 Dialogue Window로 바꿔주고
Haon A - 1은 Sprite로 바꿔서 이렇게 넣어준다
그리고 이렇게 할때 스케일이 틀릴때가 있는데 이때는
스케일 사이즈를 조절해주자
그리고 여기서 케이디님은 예전 레거시 텍스트로 대화창을 만들어 주셨는데
필자는 신기술인 TMP로 만들어 줄 것이다
https://ruripanda.tistory.com/158
TMP(택스트 매쉬 프로) 인스톨
일단 UI > Text - TextMeshPro를 하이러키에 넣어준다 그러면 이렇게 창이 뜨는데 임포트해주자 필자의 경우에는 TMP Essentials와 TMP Examples & Extras 둘다 임포트했다 TMP프로는 기본값에 영어가 기본 포
ruripanda.tistory.com
텍스트 매쉬 프로 사용 인스톨 방법과 한글폰트 인코딩 방법은 필자가 따로 올려놓은 글을 참고한다
이정도 위치에 TMP 텍스트 창을 넣어준다
창들의 우선 순위는 위 이미지를 참고한다
텍스트 매쉬 프로는 이렇게 컴포넌트가 준비되어 있다
폰트 사이즈는 12로 맞춰준다
이제 대사창 애니메이션을 만들고 응용할 것이다
그리고 대화시스템 작동시 이동 정지를 만들어 줄 것이다
일단 캐릭터와 대사창을 밖으로 빼준다
평소에는 이렇게 대사창과 캐릭터를 밖으로 빼서 미리 대기해주는 것이다
그리고 우리는 대화창과 대사창이 처음에는 밖에 있다가 대화창이 실행되면
카메라 안쪽으로 이미지가 들어오게 할 것이다
위 사진처럼 애니메이션 폴더에 UI폴더를 준비해주자
애니메이터와 애니메이션이 이미 있는데 필자는 이미 강좌를 다 해봤기 때문에 자료가 있는 것이다
차근차근 만들어보자
일단 대사창을 이렇게 선택해주면
애니메이션이 만들어 질 수 있게 이렇게 준비가 된다
애니메이션 칩이 하나도 없으면 타임라인 같은 곳에 새로 만드는 버튼이 나온다
버튼을 클릭하고
UI 폴더에 새로운 애니메이션을 만들어두자
우선 Dialogue_Window_Appear을 만들어보자
그리고 왼쪽 창에 빨간 녹화버튼을 활성해화해 준다
그런 다음 대화창을 위로 올려주고 녹화 버튼을 해재해주면 녹화가 완료된다
다음은 Dialogue_Window_Disappear를 만들어주는데
이번에 녹화할 때는 반대로 밖으로 빼주는 작업을 한다
이렇게 녹화를 하면 우리는 이미 대사창을 활성화, 비활성화 하는 애니메이션을 완성한 것이다
그뒤 애니메이터로 들어와주면 이렇게 애니매이션이 준비가 되어있는게 보일 것이다
필자의 경우 화살표 세팅이 이미 완성되어 있는데 이건 이미 해놨기 때문에 그런 것이다
마우스 우 클릭을 하면 매뉴가 나오는데 Make Transition을 클릭하여
필자처럼 Appear과 Disappear이 서로 왔다갔다 하게 세팅해주자
그리고 연결해주는 화살표를 클릭해주면 우측처럼 창이 나오는데
우리는 이 창이 언제든지 바뀔 수 있으므로 Has Exit Time를 해제해주자
그리고 애니메이션에 걸리는 시간을 바꾸기 위해
Transition Duration을 0.2로 세팅해주자
이 작업까지 해주면 애니메이션이 실행될때 대사창이 아래에서 위로 올라오는 애미메이션이 구현된 것이다
이제 애니메이터 창에서 좌측을 보자
파라메터 창이 있는데 우리는 여기서 Bool값으로 Appear을 만들어 준다
이 파라메터 값으로 On/ Off를 구현할 것이다
아까 화살표에서 설정해주는 창으로 돌아가서 Conditions를 다시보면 +를 누르면 Appear 이 나올 것이다
이걸 세팅해주면 우리는 C#스크립트에서 파라메터 값을 입력해서 제어를 할 것이다
필자처럼 화살표를 눌러서 이렇게 세팅해준다
세팅하면서 Has Exit Time를 모두 체크 해제해주고
Transition Duration을 0.2초로 해제해주고 bool값으로 만들어준 Appear파라메터를 Disappear에서 Appear쪽으로 향하는 화살표는 True로 Appear에서 Disappear로 가는 화살표는 False로 세팅해준다
이렇게 완료되면 캐릭터 스프라이트도 애니메이션으로 만들어 준다
이렇게 캐릭터를 선택해주고 다시
다시 이렇게 창을 불러온다
위에처럼 같은 요령으로 캐릭터가 카메라 스크린 안으로 들어오는 애니메이션을 만들어주자
새로운 애니메이션을 만드는 것이기 때문에 이름을 다르게 만들어 줘야 한다
이번에 새로 만드는 애니메이션 이름은
Sprite_Appear로 하자
반대 애니메이션의 경우 Sprite_Disappear로 하자
그리고 이번에는 캐릭터가 투명하게 서서히 바뀌는 애니메이션을 추가로 만들어 줄 것이다
이것은 캐릭터의 알파값을 조절하면 된다
캐릭터를 선택한 상태에서 애니메이션을 새로 만들어주고
Sprite_Alpha_255라고 이름을 만들어주자
이 경우에는 미리 캐릭터가 대화창에 올라온 상태에서
녹화버튼을 누른 뒤
Color에서 A값 투명도를 255로 바꿔주자
그러면
캐릭터가 나오는 상태는 구현이 된거다
다음번에는 Sprite_Alpha_0이라는 이름의 애니메이션을 만들어서 녹화버튼을 누르고
위의 Color A값(알파값)을 0으로 만들어주자 그러면 투명해지는 애니메이션이 구현이 될 것이다
알파값을 줄이면 이렇게 서서히 캐릭터가 투명해진다
알파값까지 만들어주면 스프라이트에 이렇게 캐릭터 이동과 알파값 변경이 애니메이션으로 나올 것이다
필자처럼 기본 이미지와 화살표를 배치해주자
그리고 파라메터를 bool값으로 Appear과 Change를 만들어주자
그리고 화살표를 설정해주자
말로하면 번거롭고 이해하기 힘들 수 있어서 필자가 이렇게 스크린샷을 보기 편하게 올렸다
그리고 우리가 만들어준 애니메이션 박스를 더블 클릭해주면
인스팩터가 이렇게 변경이 되는데 우리는 여기서 Loop Time체크를 해재할 것이다
Loop Time는 애니메이션을 반복해주는 옵션이다
4개의 박스 전부 해제해 주자
이제 스크립트를 만들어 주자(주의! 여기서부터 졸립고 피곤합니다)
스크립트 이름은 DialogueManager로 만들어 주자
일단 씬을 이동해도 다이어로그 메니져가 없어지지 않기 위해 싱글턴화 시켜준다
그리고 스크립트를 보면 #region SingLeton와 #endregion Singleton이 있는데
이는 싱글턴해주는 함수를 접어주기 위해 C#에서 사용하는 스크립트 접기 기능(주석 접기)을 사용 한 것이다
스크립트가 너무 방대해지고 복잡해지면 사용해주자
그리고 커스텀 스크립트로 Dialogue라는 스크립트를 따로 만들어 주자
그리고 이렇게 작성해주자
이게 있어야지 대사창과 캐릭터, 다이어로그 이미지를 조작할 수 있다
그리고 보면 [TextArea(1,2)]라고 작성한 것을 볼 수 있는데 이게 있으면 대사창이 유니티엔진 인스펙터를 볼때 2줄로 나오게 된다
이제 다이어로그 매니져로 돌아가자
그리고 각종 변수를 설정해주자
필자는 케이디님이 올리신 강좌를 보면서 작성했는데 케이디님의 실력에 감탄만 나올 따름이였다
각 변수가 어떤 역활을 하는지 필자가 주석으로 보기 좋게 작성해놨다
그리고 필자는 TMPro(텍스트 매쉬 프로)를 사용해서 텍스트 부분 변수는 케이님과 틀리다
위에 작성이 다 끝났다면 void Start()를 작성해주자
각종 변수 초기화와 컴포넌트를 불러오는 작업이다
그리고 ShowDialogue를 작성해주자
이 부분은 대화창이 실행되기 전에 대화창 실행전 작업을 해주는 것이다
커스텀 스크립트를 참조해 준다
이제 스타트 코루틴을 작성해준다
일단 if문으로 count > 0 넣어서 카운트를 체크해주는 코드를 작성해준다
그뒤 if (listDialogueWindows[count] != listDialogueWindows[count - 1]) 코드를 작성해주면
다이어로그 윈도우(대사창)이 전과 틀린지 체크해 주는 것이다
그래서 틀리게 되면 각종 파라메터와 코루틴을 갱신해준다
그리고 else문으로 만약에
if (listSprites[count] != listSprites[count - 1]) 가 있는데
이 부분은 스프라이트가 전과 틀린 것인지 체크해주는 부분이다
이 부분이 작동되면 캐릭터 이미지가 바뀔 것이다
그리고 else로 0.05 초 정도 대기시간을 만들어 준다
이렇게 작성해주면 또 아래(119번째줄)에 else가 있는데 이 부분은 캐릭터와 대사창 갱신이다
다음 125번째 줄은 대화창이 실행되면 다른 키 입력이 작동되지 못하게 방지해주는 기능이다
126번째 줄 부터는 for문으로 대사창에서 한글자 한글자 출력이 되게 해주는 기능이다
text.text += listSentences[count][i]; 로 그 로직이 실행되게 되며
한글자 한글자 출력하면서 소리가 날건데
그 부분은
if(i % 7 == 1)
{
theAudio.Play(typeSound);//대사창이 움직일때 오디오 실행
}
yield return new WaitForSeconds(0.01f);
이 코드가 실행되면서 소리가 날 것이다
소리가 날때마다 yield return new WaitForSeconds로 0.01초 대기시간을 갖게 해주자
그리고 매 프레임마다 실행되는 void Update()로
if (talking && keyActivated) 조건으로 실행
대사가 실행되면서 &&으로 다른키가 입력도지 않게 해주며
if (Input.GetKeyDown(KeyCode.Z)) 코드로 Z키를 누를때마다
초기화가 되면서 코루틴이 작동되게 작성해준다
그리고 작성이 완료되면 인스펙터를 이렇게 연결해준다
그뒤 오디오 메니져로 들어가서 새롭게 오디오 슬롯을 2개 작성해준다
이 부분은 캐릭터의 대사창에서 한글자 한글자마다 소리가 나오고 대사가 종료되면 나오는 오디오 소리를 구핸주 주는 부분이다
다시 캔버스로 돌아와서 애니메이터를 슬롯에 넣어주고 우리가 오디오 메니저에 작성한 소리를 받아오게 텍스트를 입력해준다
이제 빈 게임오브젝트를 생성해서
TestDialogue 스크립트를 넣어준다
테스트 다이어로그는 필자가 T버튼으로 실행되게 작성해 놨다
마지막으로 필자가
MovingObjcet와 PlayerManager의 새로운 소스코드를 업로드 했는데
이 두분이 새로 작성되어 있다
작성해서 넣어주자 이렇게 해서 다 완료되면
테스트 다이어로그를 세팅해주자
이제 대사창을 실행해 보면...
이렇게 대사창이 실행되는 것을 볼 수 있다
PS
앞으로는 가이드를 작성하고
ps로 추신을 남겨놓을 것 입니다
이번 대사창을 만들면서 느낀 점이 케이디님도 몇일에 걸쳐서 작성하신 가이드 같고
저도 도중에 힘이 빠져서 더 자세히 작성하기 보다는 주석을 마구 적는 식으로 처리했습니다
정말 빡세네요
'쯔꾸르식 유니티 게임 공부' 카테고리의 다른 글
15.페이드 & 플레시 연출 (0) | 2025.01.24 |
---|---|
14.이벤트 구현하기 (0) | 2025.01.23 |
12.NPC 충돌방지(Box콜라이더 이동) (0) | 2025.01.16 |
11.이벤트 캐릭터 이동명령 이벤트 (0) | 2025.01.15 |
10.5 추가설명 (0) | 2025.01.14 |