유니티/쯔꾸르

2D RPG 쯔꾸르 제작하기 Part 6 : 맵 (Scene) 이동하기

아메숑 2019. 3. 10. 23:41

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


1. 코드

StartPoint.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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class StartPoint : MonoBehaviour
{
    //맵 이동시 플레이어가 시작될 위치
    public string startPoint;
 
    private MovingObject thePlayer;
    private CameraManager theCamera;
 
    // Start is called before the first frame update
    void Start()
    {
        thePlayer = FindObjectOfType<MovingObject>();
        theCamera = FindObjectOfType<CameraManager>();
        if(startPoint == thePlayer.currentMapName)
        {
            //맵이동을 할 때 카메라도 같이 캐릭터의 위치에서 시작
            theCamera.transform.position = new Vector3(this.transform.position.x, this.transform.position.y, theCamera.transform.position.z);
            thePlayer.transform.position = this.transform.position;
        }
        
    }
 
    // Update is called once per frame
    void Update()
    {
        
    }
}
 
cs


transferMap.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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
 
public class transferMap : MonoBehaviour
{
    public string transferMapName;
 
    private MovingObject thePlayer;
    private CameraManager theCamera;
 
    public Transform target;
 
    public bool flag;
    // Start is called before the first frame update
    void Start()
    {
        if(!flag)
            theCamera = FindObjectOfType<CameraManager>();
        thePlayer = FindObjectOfType<MovingObject>();
    }
    
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.name == "Player")
        {
            thePlayer.currentMapName = transferMapName;
            if(flag)
                SceneManager.LoadScene(transferMapName);
            else
            {
                theCamera.transform.position = new Vector3(target.transform.position.x, target.transform.position.y, theCamera.transform.position.z);
                thePlayer.transform.position = target.transform.position;
            }
            
 
        }
    }
    
}
 
cs



cameraManager.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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class CameraManager : MonoBehaviour
{
 
    static public CameraManager instance;
    public GameObject target;   //카메라가 따라갈 대상
    public float moveSpeed; //카메라의 속도
    private Vector3 targetPosition; //대상의 현재 위치
 
    // Start is called before the first frame update
    void Start()
    {
        if(instance == null)
        {
            instance = this;
            //맵을 이동해도 카메라를 파괴시키지 않는다.
            DontDestroyOnLoad(this.gameObject);
        }
        else
        {
            Destroy(this.gameObject);
        }
        
    }
 
    // 카메라는 매 프레임마다 업데이트 되어야하기 때문에 여기서
    void Update()
    {
        if(target.gameObject != null)
        {
            //this는 생략이 가능하고 카메라를 의미한다. 카메라의 z값은 타겟보다 멀리있어야 타겟이 화면에 나올 수 있다.
            targetPosition.Set(target.transform.position.x, target.transform.position.y, this.transform.position.z);
            //Time.deltaTime은 1초에 실행되는 프레임의 역수이며 1초에 moveSpeed만큼 이동하게 해준다. 
            //카메라의 위치를 변화시킨다. 
            this.transform.position = Vector3.Lerp(this.transform.position, targetPosition, moveSpeed * Time.deltaTime);
        }
        
    }
}
 
cs


movingObject.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class MovingObject : MonoBehaviour
{
    static public MovingObject instance;
 
    //transferMap 스크립트에 있는 trasferMapName 변수의 값을 가져온다. 
    public string currentMapName;
 
    private BoxCollider2D boxCollider;
    public LayerMask layerMask; //통과가 불가능한 레이어를 설정 
 
    public float speed;
 
    private Vector3 vector;
 
    public float runSpeed;
    private float applyRunSpeed;
    private bool applyRunFlag = false;
 
    public int walkCount;
    private int currentWalkCount;
 
    private bool canMove = true;
 
    private Animator animator;
 
 
 
    // Start is called before the first frame update
    void Start()
    {
        if(instance == null)
        {
            //맵을 이동해도 캐릭터를 파괴시키지 않는다.
            DontDestroyOnLoad(this.gameObject);
            boxCollider = GetComponent<BoxCollider2D>();
            animator = GetComponent<Animator>();
            instance = this;
        }
        else
        {
            Destroy(this.gameObject);
        }
        
    }
 
    IEnumerator MoveCoroutine()
    {
        while (Input.GetAxisRaw("Horizontal"!= 0 || Input.GetAxisRaw("Vertical"!= 0)
        {
            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);
 
            RaycastHit2D hit;   //레이저를 쏴서 방해물이 있으면 방해물을 리턴하고, 아무것도 없으면 null리턴
 
            Vector2 start = transform.position; //캐릭터의 현재위치
            //speed = 2.4 walkCount = 20 이므로 48픽셀만큼 이동
            Vector2 end = start + new Vector2(vector.x * speed * walkCount, vector.y * speed * walkCount);   //캐릭터가 이동하고자 하는 곳
 
            boxCollider.enabled = false;    //캐릭터 자신의 박스컬라이더를 인식못하게 해줌
            hit = Physics2D.Linecast(start, end, layerMask);
            boxCollider.enabled = true;
 
            if (hit.transform != null)    //부딪히면 다음 명령어들은 실행하지 않음
                break;
 
            animator.SetBool("Walking"true);
 
            while (currentWalkCount < walkCount)
            {
                if (vector.x != 0)
                {
                    transform.Translate(vector.x * (speed + applyRunSpeed), 00);
                }
                else if (vector.y != 0)
                {
                    transform.Translate(0, vector.y * (speed + applyRunSpeed), 0);
                }
                if (applyRunFlag)
                    currentWalkCount++;
                currentWalkCount++;
                yield return new WaitForSeconds(0.01f);
            }
            currentWalkCount = 0;
         
        }
        animator.SetBool("Walking"false);
        canMove = true;
 
 
    }
 
    // Update is called once per frame
    void Update()
    {
        if(canMove)
        {
            if (Input.GetAxisRaw("Horizontal"!= 0 || Input.GetAxisRaw("Vertical"!= 0)
            {
                canMove = false;
                StartCoroutine(MoveCoroutine());
            }
        }
 
    }
}
 
cs



2. 강좌



새로운 scene을 추가하고 새로만든 맵을 가져온다.

TransferMap이라는 스크립트를 생성한다.



원래의 scene으로 돌아와서 빈오브젝트를 생성하고, box collider TransferMap 스크립트를 추가한다.

 


Trigger 체크



이름을 Player로 바꿔주고 rigidbody 2D를 생성한다. 중력을 0으로 해주고 Z를 체크한다.

 


맵이동 오브젝트에서 이동할 맵을 school front로 지어준다.

 


이제 맵을 이동해도 캐릭터가 사라지지 않도록 하자.

DontDestroyOnLoad(this.gameObject);

를 카메라와 캐릭터 스크립트의 start에 추가시킨다.



school scene의 메인 카메라를 삭제한다.

 

이제 이동한 맵의 아래부분부터 시작하는 것을 구현할 것이다.



school scene에서 빈 객체를 생성하고 box collision 2D를 생성한다. 캐릭터가 시작할 위치에 놓고 스크립트(startPoint.cs)를 하나 생성한다.


이제부턴 같은 scene에서 맵이동을 하는 방법이다. 



start scene에 맵을 하나 더 추가한다.

 


TransferPoint 객체에 Target을 새로 생성한 오브젝트(startpoint)를 드래그한다. Flag가 체크안되어있으면 target으로 이동하고, 체크가 되어있으면 새로운 맵으로 이동한다.