ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [유니티 강좌] 2D RPG 쯔꾸르 제작하기 Part 10 : NPC 구현하기
    유니티/쯔꾸르 2019. 3. 19. 09:40

    출처 - https://www.youtube.com/watch?v=EdsVx9yN2Cc&list=PLUZ5gNInsv_NW8RQx8__0DxiuPZn3VDzP


    1. 코드

    Moving Object.cs

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
     
    public class MovingObject : MonoBehaviour
    {
        public BoxCollider2D boxCollider;
        public LayerMask layerMask; //통과가 불가능한 레이어를 설정 
     
        public float speed;
        public int walkCount;
        protected int currentWalkCount;
     
        protected Vector3 vector;
        public Animator animator;
     
        protected bool npcCanMove = true;
     
        protected void Move(string _dir,int _frequency)
        {
            StartCoroutine(MoveCoroutine(_dir, _frequency));
        }
     
        IEnumerator MoveCoroutine(string _dir, int _frequency)
        {
            npcCanMove = false;
            vector.Set(00, vector.z);
            switch (_dir)
            {
                case "UP":
                    vector.y = 1f;
                    break;
                case "DOWN":
                    vector.y = -1f;
                    break;
                case "LEFT":
                    vector.x = -1f;
                    break;
                case "RIGHT":
                    vector.x = 1f;
                    break;
            }
            animator.SetFloat("DirX", vector.x);
            animator.SetFloat("DirY", vector.y);
            animator.SetBool("Walking"true);
     
            while (currentWalkCount < walkCount)
            {
                //위에서 벡터의 x,y값을 0,0으로 초기화 하기 때문에 절대 대각선으로 갈 일이 없다. 
                transform.Translate(vector.x * speed, vector.y * speed, 0);
                currentWalkCount++;
                yield return new WaitForSeconds(0.01f);
            }
            currentWalkCount = 0;
            if(_frequency != 5)
                animator.SetBool("Walking"false);
            npcCanMove = true;
        }
    }
     
    cs


    NPCManager.cs

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
     
    [System.Serializable]
    public class NPCMove
    {
        [Tooltip("NPCMove를 체크하면 NPC가 움직임")]
        public bool NPCmove;
        public string[] direction; //NPC가 움직일 방향
        [Range(15)]
        public int frequency; //npc의 속도
    }
     
    public class NPCManager : MovingObject
    {
        //위에서 선언한 NPCMove 클래스를 활용하기 위해 
        [SerializeField]
        public NPCMove npc;
     
        // Start is called before the first frame update
        void Start()
        {
            StartCoroutine(MoveCoroutine());
        }
     
        IEnumerator MoveCoroutine()
        {
            if (npc.direction.Length != 0)
            {
                for(int i = 0; i < npc.direction.Length; i++)
                {
                    switch (npc.frequency)
                    {
                        case 1:
                            yield return new WaitForSeconds(4f);
                            break;
                        case 2:
                            yield return new WaitForSeconds(3f);
                            break;
                        case 3:
                            yield return new WaitForSeconds(2f);
                            break;
                        case 4:
                            yield return new WaitForSeconds(1f);
                            break;
                        case 5:
                            break;
                    }
     
                    yield return new WaitUntil(() => npcCanMove);
                
                    base.Move(npc.direction[i], npc.frequency);
     
     
                    //실질적인 이동구간 
                    if (i == npc.direction.Length - 1)
                        i = -1;
                }
            }
        }
     
    }
     
    cs


    2. 강좌


    playerManagerNPCManager 두 개의 스크립트를 생성한다.

    공유할 변수들만 moving object 스크립트에 남기고 모두 PlayerManager 스크립트로 옮긴다.

     


    Moving object 컴포넌트를 삭제하고 새로 만든 스크립트인 Player Manager를 추가한다.

     


    위와 같이 설정하고 메인 캐릭터의 애니메이터를 설정한 방식과 똑같이 애니메이터를 설정해준다. Pixels Per Unit1로 설정하면 캐릭터의 크기를 1로 설정해 놓았을 때 맵과 가장 알맞은 크기가 된다.

     


    NPC 스크립트와 moving object 스크립트를 수정한 후 스크립트를 추가하고 값을 셋팅한다.

    Moving Object 스크립트를 수정하여 Move라는 함수를 만들고 NPCManager 스크립트에서 Move 함수를 이용한다. 물론 Moving Object를 상속받았기 때문에 가능하다.

    frequency5로 설정했을 경우 무한루프에 빠지게 된다. 그래서 moving object 스크립트에 protected bool npcCanMove라는 변수를 선언해준다

     


    npcCanMove라는 변수가 true가 될 때까지 기다린다.

     



     


    만약 up-up이렇게 연속적인 방향으로 이동할 경우 부자연스러운 부분을 처리하기 위해 변수를 하나 더 넘겨준다.

     



    frequency5가 아닐 때에만 walkingfalse로 바꿔준다. 속도가 5일 때만 연속적인 움직임이 나와야 하므로



Designed by Tistory.