Unity 내일배움캠프 TIL 0906 | 게임 NPC 생성 | 애니메이션 타일

cheeseonrose·2023년 9월 6일
0

Unity 내일배움캠프

목록 보기
28/89
post-thumbnail

스스로 불러온 재앙에 짓눌려~ 2

Unity 입문 개인 프로젝트

게임 NPC 생성

  • 우선은 NPC 클래스가 있어야 할 것 같아서 INPC 인터페이스와 NPC 클래스를 생성해줬다.
  • INPC
    • 사실 그냥 NPC 클래스에서 InteractWithPlayer 함수를 virtual로 선언해주면 필요 없을 것 같은데 이..일단 이대로 진행시켜
public interface INpc 
{
    public string Name { get; }
    public string Dialog { get; }

    void InteractWithPlayer();
}
  • NPC
    • 생성자에 NPC 이름과 대화 내용을 전달 받는다.
      지금은 NPC의 대화 말이 1개이지만 추후에 더 늘어난다면 배열로 타입을 바꿔줘야 될 것 같음
    • 플레이어와 대화를 시작할 때는 UIManager에 NPC 이름과 대화를 넘겨준다.
    • NPC 오브젝트에 Player가 접근하면 NPC 호출 패널을 활성화해주고, Player가 멀어진다면 다시 비활성화 해준다.
public class Npc : MonoBehaviour, INpc
{
    public string Name { get; }
    public string Dialog { get; }

    private GameObject canvas;

    public Npc(string name, string dialog)
    {
        Name = name;
        Dialog = dialog;
    }

    public void InteractWithPlayer()
    {
        UIManager.U.SetNpcDialogPanel(Name, Dialog);
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            canvas = GameObject.FindWithTag("Canvas");

            if (canvas == null) return;
            
            InteractWithPlayer();
            canvas.transform.Find("CallNpcPanel").gameObject.SetActive(true);
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        canvas = GameObject.FindWithTag("Canvas");

        if (canvas == null) return;

        canvas.transform.Find("CallNpcPanel").gameObject.SetActive(false);
        canvas.transform.Find("NpcInteractionPanel").gameObject.SetActive(false);
    }
}
  • JongminManagerNpc
    • 각각의 NPC 객체는 이런 식으로 구성된다.
      고유의 이름과 대화 내용을 base로 전달하는 방식
public class JongminManagerNpc : Npc
{
    static string name = "박종민 매니저";
    static string dialog = "안녕하세요! 무슨 일로 찾아오셨나요?";

    public JongminManagerNpc() : base(name, dialog) { } 
}

UI Manager 추가

  • UI 요소가 많은데 이것들을 한 번에 관리할 필요성을 느껴서 UI Manager 오브젝트를 추가하고 스크립트를 연결해줬다.
    GameManager와 마찬가지로 싱글톤으로 구현해주고, 다른 오브젝트에서 UI Manager의 함수를 호출하도록 변경해주었다.
    근데 아직 다 옮기지는 못해서 추가 리팩토링 필요함

Canvas Scaler

  • 작업하는 도중에 캔버스 크기가 자꾸 지혼자 바뀌어서 구글링을 해보니 보통 작업 시작하기 전에 가로 화면 기준 1920 x 1080 으로 캔버스 크기를 고정시킨다고 한다.
  • Scale With Screen Size로 설정하면 해상도에 따라 알아서 캔버스 크기가 변경된다.

참여자 리스트

  • 어제 미뤄놨던 이유는 NPC를 추가했을 때 따로 넣어주지 않아도 코드 상에서 알아서 현재 존재하는 NPC들을 리스트에 반영하고 싶었기 때문
    그래서 NPC 클래스를 만들 때까지 기다렸따!!!! 하하하
  • GameManager.LoadAttendeeList
    • 게임 매니저의 Start 함수에서 호출해준다.
    • Resources 폴더 안에서 NPC 프리팹들을 가져와서 NpcController 오브젝트의 하위 오브젝트로 생성해준다. (어제 튜터님이 말씀해주신 방법!!)
      그 후에 UI Manager에게 현재 참가자 리스트를 set 할 것을 요청
private void LoadAttendeeList()
{
	GameObject npcController = GameObject.Find("NpcController");
    GameObject[] npcList = Resources.LoadAll<GameObject>("Prefabs/Npc");
    foreach (GameObject npc in npcList)
    {
    	GameObject curNpc = Instantiate(npc);
        curNpc.transform.SetParent(npcController.transform);
    }
    
    UIManager.U.SetAttendeeList();
}
  • UIManager.SetAttendeeList
    • 최상단에는 플레이어 닉네임을 넣는다.
    • Resources 폴더에서 가져온 AttendeeName 프리팹을 만들어주고, 캔버스에 만들어놓은 ScrollView 하위(contentContainer)에 넣어준다.
      이름은 NpcController 하위의 Npc 오브젝트들의 이름을 가져와 대입해줌
public void SetAttendeeList()
{
	// 최상단에 플레이어 닉네임
    GameObject playerName = Instantiate(Resources.Load<GameObject>("Prefabs/AttendeeName"));
    playerName.GetComponent<Text>().text = PlayerPrefs.GetString(Player.PLAYER_NAME);
    playerName.transform.SetParent(contentContainer);
    
    // Npc 닉네임
    GameObject npcController = GameObject.Find("NpcController");
    int npcNum = npcController.transform.childCount;
    
    for (int i = 0; i < npcNum; i++)
    {
    	GameObject npcName = Instantiate(Resources.Load<GameObject>("Prefabs/AttendeeName"));
        npcName.GetComponent<Text>().text = npcController.transform.GetChild(i).GetComponent<Npc>().Name;
        npcName.transform.SetParent(contentContainer);
    }
}
  • 이렇게 해주면 스크롤 뷰의 Viewport - Content 하위에 이름 Text 오브젝트가 생성된다.

  • 그리고 요렇게 이름이 짜잔


애니메이션 타일

  • 스불재 시작
  • 괜찮은 타일 에셋을 찾아서 적용하려고 했는데 세상에 애니메이션도 있고 귀염뽀짝한데 심지어 무료임 ;; 근데 상업적 이용도 가능하대 우째?
    당장 써.
  • 타일 이미지를 가져와서 Sprite Mode는 Multiple, PPU 값 조정, Advanced - Filter Mode를 Point(no filter)로 설정해준 뒤 적용
    Sprite Editor를 열면 Slice를 할 수 있다.
    Grid By Cell Size로 해주면 이렇게 슥슥 잘린다!
  • 애니메이션 타일은 package를 설치해주면 간편하다
    Github 2d-extras 여기서 유니티 버전에 맞게 브랜치 바꾸고 설치 or Package 내의 manifest.json에 dependency 복붙 (끝에 master 브랜치말고 유니티 버전에 맞는 브랜치 명으로 바꿔줘야 함)
  • 그러면 Project 창 우클릭 - Create - 2D - Tiles - Animated Tile 요게 보일 것임
  • 애니메이션 개수를 설정해주고 애니메이션용 타일들을 끌어다 놓으면 완성
    애니메이션 속도는 speed 값으로 조절해주거나 Tilemap 컴포넌트의 Animation Frame Rate 값을 조절해주면 된다
    근데 나는 폭포만 빠르게 하고 싶어서 폭포 타일들의 speed 값만 살짝 조정해줬다

TODO

  1. 나무 심기
  2. 튜터님 구역 추가
  3. 코드 리팩토링
  4. 매니저님 npc 애니메이션 추?가 (보류)
  5. 노동



와~ 야근이다~
끗 ..

0개의 댓글