05-02 04:19
Notice
Recent Posts
Recent Comments
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

(주) 망나니 힘집

[탑다운] 오브젝트 관리 , 대화 시스템 본문

유니티 최고/Unity Game Making

[탑다운] 오브젝트 관리 , 대화 시스템

군포망나니 2022. 1. 20. 12:20

이 글은 골드메탈님 수업을 듣고 작성하였습니다. 

 

* 오브젝트 관리 *  

오브젝트의 아이디, 사물 or npc 인지 등의 판별하 

스크립트 생성 

public class Object : MonoBehaviour
{
    //id 변수 생성 
    public int id;
    //npc 판별 
    public bool isNpc; 
}

작성 후 각 오브젝트마다 스크립트 삽입 후 id 와 npc 여부 체크합니다. 

 

* 대화 시스템 구축 * -------> 굉장히 굉장히 굉장히 굉장히 굉장히 복잡하다. 

 TalkManager 스크립트를 생성 

(어떤 대사가 들어가는지 저장을 하는 코드를 생성한다. )

 

public class TalkManager : MonoBehaviour
{
    //key : value 
    //int : id ,string : 대사 
    Dictionary<int, string[]> talkData; 
    void Awake()
    {
        //초기화
        talkData = new Dictionary<int, string[]>(); 
        GenerateDate(); 
    }

    //데이터를 집어넣는 함수 생성 
    void GenerateDate()
    {
        //Add 함수를 이용하여 대화 데이터 입력을 추가한다. 
        //int -> id 를 넣는다. 
        //대화 하나에 문장이 여러개 있을 수 있어서  string[]을 사용한다. -> 구분 짓기 위해 , (콤마) 사용. 
        talkData.Add(1000, new string[] { "안녕" , "반가워" });
        //player 의 독백 
        talkData.Add(100, new string[] { "그냥 박스네" });
        talkData.Add(200, new string[] { "누군가 사용한 흔적이 있어." });
    }

    //대화 문장을 반환하기 위한 함수를 하나 만든다. 
    public string GetTalk(int id, int talkIndex)
    {
        //id 에 따라 한 문장씩 리턴해준다.  
        return talkData[id][talkIndex]; 
    }
}

 

이렇게 코드를 작성한 후, GameManager 스크립트에서 함수를 호출한다. 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
    public TalkManager talkManager; 
    //액션을 취할 때만 사용하기 위해 변수 생성
    public GameObject talkPanel;
    //변수 생성 
    public bool isAction;
    //변수 2개 생성
    //대화 변수
    public Text talkText;
    //스캔한 오브젝트 변수 
    public int talkIndex; 
    public GameObject scanObject; 
    //매개변수로 scanObj을 받는 함수 생성
    public void Action(GameObject scanObj)
    {
        if (isAction)      
        {
            isAction = false;                     
        }
        else
        {
            isAction = true;
            scanObject = scanObj;
            //Object 스크립트 내에 있는 데이터를 가져옴
            Object objData = scanObject.GetComponent< Object > ();
            //텍스트 넣기  
            Talk(objData.id, objData.isNpc);
        }

        //SetActive() : 숨기기와 보여주기를 구현해주는 함수    
        talkPanel.SetActive(isAction); 
    }

     void Talk(int id, bool isNpc)
    {
        string talkData = talkManager.GetTalk(id, talkIndex); 
        if(isNpc)
        {
            talkText.text = talkData; 
        }
        else
        {
            talkText.text = talkData;
        }
    }
}

이렇게 코드를 짜준다. 

 

그 후 GameManager 에 TalkManager 스크립트를 삽입한다. 

그 후 실행하면 미리 지정해 놓은 대화창이 뜬다. 

 

여기서 문제점이 발생한다. 문장이 2개 이상 작성한 경우 , 첫번째 문장만 뜬다. 

이것을 해결해야 한다. -> 대화가 모두 끝나야 액션이 끝나도록 설정을 바꾸어야 한다. 

 

#GameManager Script

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
    public TalkManager talkManager; 
    //액션을 취할 때만 사용하기 위해 변수 생성
    public GameObject talkPanel;
    //변수 생성 
    public bool isAction;
    //변수 2개 생성
    //대화 변수
    public Text talkText;
    //스캔한 오브젝트 변수 
    public int talkIndex; 
    public GameObject scanObject; 
    //매개변수로 scanObj을 받는 함수 생성
    public void Action(GameObject scanObj)
    {
        scanObject = scanObj;
        //Object 스크립트 내에 있는 데이터를 가져옴
        //Object 스크립트 내에 있는 데이터를 가져옴
        Object objData = scanObject.GetComponent< Object > ();
        //텍스트 넣기  
        Talk(objData.id, objData.isNpc);
        //SetActive() : 숨기기와 보여주기를 구현해주는 함수    
        talkPanel.SetActive(isAction);
    }

        

     void Talk(int id, bool isNpc)
    {
        string talkData = talkManager.GetTalk(id, talkIndex); 

        if(talkData == null) {
            isAction = false;
            talkIndex = 0; 
            //talkIndex 는 대화가 끝날 때 0 으로 초기화한다. 
            //talkIndex = 0 코드가 없으면, 한문장의 대화창을 가진 오브젝트를 클릭했을 때, "Index was outside the bounds of the array" 
            //라는 오류 코드가 발생한다. 
            return;
        }


        if(isNpc)
        {
            talkText.text = talkData; 
        }
        else
        {
            talkText.text = talkData;
        }
        isAction = true;
        talkIndex++; 
    }
}

 

# TalkManager Script 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TalkManager : MonoBehaviour
{
    //key : value 
    //int : id ,string : 대사 
    Dictionary<int, string[]> talkData; 
    void Awake()
    {
        //초기화
        talkData = new Dictionary<int, string[]>(); 
        GenerateDate(); 
    }

    //데이터를 집어넣는 함수 생성 
    void GenerateDate()
    {
        //Add 함수를 이용하여 대화 데이터 입력을 추가한다. 
        //int -> id 를 넣는다. 
        //대화 하나에 문장이 여러개 있을 수 있어서  string[]을 사용한다. -> 구분 짓기 위해 , (콤마) 사용. 
        talkData.Add(1000, new string[] { "안녕" , "반가워" });
        //player 의 독백 
        talkData.Add(100, new string[] { "그냥 박스네" });
        talkData.Add(200, new string[] { "누군가 사용한 흔적이 있어." });
        talkData.Add(2000, new string[] { "누구야?" });
    } 

    //대화 문장을 반환하기 위한 함수를 하나 만든다. 
    public string GetTalk(int id, int talkIndex)
    {
        //id 에 따라 한 문장씩 리턴해준다.  
        if (talkIndex == talkData[id].Length)
            return null;
        else
            return talkData[id][talkIndex]; 
    }
    //void 함수에서 return 은 강제 종료 역할이다. 
}

 

이렇게 코드를 짜면 완성이다. 

진짜진짜정말 복잡하다.