본문 바로가기

GAME

[Unity]기초 3D게임만들기 - 2

728x90

 

 

카메라 조정 

지금 현재 카메라는 매우 불편하게 설정되어있습니다.

보통 게임은 플레이어를 따라다니죠 카메라가 (롤에서 y눌렀을 때 처럼)

그렇게 만들어보도록 합시다

 

현재 카메라의 상태입니다

고정되어있습니다.

 

 

위치 조절

일단 카메라가 공을 잘 보도록 만들어봅시다(1인칭 게임처럼)

 

대충 이정도면 될 것 같네요

 

 

스크립트

카메라 이동을 위해 카메라 오브젝트에 스크립트를 줍시다

카메라가 딱 저 각도와 위치를 유지하면서 공을 따라다녔으면 좋겠습니다.

CameraMoving.cs 라는 스크립트를 만들어 카메라에 적용시켰습니다.

 

 

먼저 플레이어의 위치정보를 스크립트로 가져와야 합니다

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

public class CameraMoving : MonoBehaviour
{

    Transform playerTransform; //플레이어의 위치정보 변수 
    Vector3 Offset;//고정값 ( 플레이어와 카메라 사이의 떨어진 정도 ) 

    // Start is called before the first frame update
    void Awake(){//초기화

        playerTransform = GameObject.FindGameObjectWithTag("Player").transform; 
        //플레이어의 위치정보를 Tag를 이용해 가져옴


        Offset = transform.position - playerTransform.position; 
        //자신의 위치 - 플레이어의 위치 = 플레이어와 자신의 떨어진 벡터값 
    }

    // Update is called once per frame
    void LateUpdate()
    {
        //카메라의 위치 = 플레이어의 위치 + 플레이어와 자신의 떨어진 고정값 
        transform.position = playerTransform.position + Offset;
    }
}

카메라의 이동은 모든 업데이트가 끝난 후 실행되는 이벤트이므로 LateUpdate 함수를 사용하는 것이 적절합니다.

 

 

GameObject.FindGameObjectWithTag("태그이름") 이 함수를 사용하시면 태그이름으로 오브젝트를 찾아낼 수 있습니다

우리는 오브젝트 자체가 필요한게 아니라 위치정보가 필요하므로 해당 오브젝트의 transform을 찾기위해 .transform을 붙여줬습니다

 

만약 카메라의 위치를 transform.position = PlayerTransform.position으로 두면,

FPS의 1인칭 게임처럼 자신의 캐릭터는 볼 수 없고 캐릭터의 시야로 볼 수 있게되는데

저희는 그것을 원하는 것이 아니므로 공의 위치에 지금 적절히 조절해둔 사이 거리 벡터만큼 카메라의 포지션을 더해줘야합니다

이 만큼 이를 Offset변수에 계산해 넣어줍니다. 

 

이제 실행해보면,

 

우리가 원하는 대로 됐네요

 

 

결승점

 

일단 겉모습부터 조절해주세요

위치 & 재질 마음대로 해주시면됩니다.

실린더 오브젝트를 이용해서 결승지점 구간을 만들어 주었습니다.

 

 

물리적으로 맞닿는 용도가 아니므로

is Trigger에 체크 해주시고요

Tag도 FinishPoint라고 달아주었습니다

추가적으로 크기를 조금 늘려줬습니다.

 

 

 

 

결승점과 공 아이템의 연동

 

마찬가지로 플레이어 스크립트에 게임방식을 코딩해봅시다

아이템을 다 먹고 FinishPoint에 들어오지 않으면 게임을 다시시작하고

아이템을 전부 다 먹고 FinishPoint에 들어오면 게임이 끝나는 방식

 

<GameManager>

Empty오브젝트를 하나 추가하여 GameManger를 만들어봅시다

GameManager : 형태가 없고 전반적인 로직을 가진 오베젝트를 매니저로 설정

보이지 않지만 게임의 구성요소를 관리하는 것

그리고 스크립트도 하나 추가해서 아이템의 갯수를 저장하도록 합시다

GameManagerLogic.cs 라고 이름을 지은 후

TotalItemCount변수를 부여합니다

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

public class GameManagerLogic : MonoBehaviour
{

    public int TotalItemCount;
}

 

public으로 지정했으니 컴포넌트에 보일 탠데 

저는 아이템이 총 3개라 3을 넣어주었습니다.

 

 

 

이제 플레이어 오브젝트의 스크립트를 보면,

위에 만든 GameManager를 통하여 변수에 접근해야 하므로 일단 변수로 만듭니다.

    public GameManagerLogic manager;

 

그렇게 되면 pulbic이므로 게임내에 Manager변수가 생겼을 탠데 

None으로 되어 있는것을  만들어 둔 GameManger오브젝트를 드래그 하여 넣어줍니다.

이렇게 되면 Fine WithTag로 접근하지 않고 변수명._____ 으로 접근이 가능해서 연산속도가 좋아집니다.

 

만들어둔 FinishPoint실린더와 충돌(Trigger)할 경우 

아이템을 다 먹은 경우 -> next Stage

아이템을 다 먹지 못한 경우 -> 현 스테이지 재시작 으로 코딩하도록 하겠습니다.

    void OnTriggerEnter(Collider other){

        if (other.tag == "Item"){ //충돌 오브젝트가 아이템일때
            
            //생략 

        }
        else if(other.tag == "FinishPoint"){ //FinishPoint와 충돌 할 경우 
            if(itemCount == manager.TotalItemCount){
                //게임 끝 (다음 레벨로)
                SceneManager.LoadScene("Stage2");
            }else{
                //재시작 
                SceneManager.LoadScene("Stage1");
            }
        }
    }

manager.TotalItemCount로 변수에 접근가능합니다

SceneManager로 Scene을 불러올 수 있는데 라이브러리를 하나 추가해주어야합니다.

using UnityEngine.SceneManagement;

맨 위 상단에 이 라이브러리를 추가하면 정상적으로 작동합니다.

 

이제 불러올 Scene을 만들어 주어야합니다.

 

현재 Scene폴더 인데 새로운 Scene을 만들어보도록 합시다

 

새로운 Scene2개를 만들고

지금 원래 Sample로 저장된 것을 Stage1으로 Rename해주고

새로 만든 두개는 이름을 Sample, Stage2로 한다음 

Stage2에는 Stage1의 오브젝트들을 그대로 복사해주었습니다.

 

Stage2 복사한 오브젝트들의 모습(실행하면 1과같은 것을 볼 수 있음)

 

 

 

 Stage2는 아이템을 한 5개로 늘려봅시다 배치를 조금바꾸고..

물론 게임메니저에서 아이템 갯수도 바꾸어주어야 합니다

 

 

Scene을 추가해주었으면 해주어야 하는 게 있는데 바로

File->BuildSetting입니다.

Scene 2개를 전부 체크해주어야 오류가 안납니다.

 

이제 실행해보시면, 

아이템을 다먹고가면 Stage2로 이동되고 , 다안먹으면 재시작하는 모습을 볼 수 있습니다

게임 SavePoint할때 좋겠네요 

 

 

 

<Stage관리>

void OnTriggerEnter(Collider other){

        if (other.tag == "Item"){ //충돌 오브젝트가 아이템일때
            itemCount++; // 점수 올리기 
            audio.Play(); // 사운드 재생 
            other.gameObject.SetActive(false); //아이템 비활성화 

        }
        else if(other.tag == "FinishPoint"){
            if(itemCount == manager.TotalItemCount){
                //게임 끝 (다음 레벨로)
                SceneManager.LoadScene("Stage2");
            }else{
                //재시작 
                SceneManager.LoadScene("Stage1");
            }
        }
    }

여기서 Stage때 마다 Stage1, 2를 적어주면 모든 스테이지별로 if문이 다 필요하겠죠

그런것보다는 자동으로 관리가 되는게 편할태니

 

GameManager스크립트에 Stage변수를 넣어 관리해봅시다.

public class GameManagerLogic : MonoBehaviour
{

    public int TotalItemCount;
    public int Stage; //Stage변수추가
}

그다음에 Scene1에는 1로, Scene2에는 2로 변수를 변경합시다.

Scene1

 

Scene2

 

이제 그럼 코드를 바꿀수 있겠네요

        else if(other.tag == "FinishPoint"){
            if(itemCount == manager.TotalItemCount){
                //게임 끝 (다음 레벨로)
                SceneManager.LoadScene("Stage"+(manager.Stage+1).ToString());
            }else{
                //재시작 
                SceneManager.LoadScene("Stage"+manager.Stage.ToString());
            }
        }

 

 

 

 

이제 기본적인 것은 완료 되었고 지형을 만들어 봅시다.

지형만들기

원래쓰던 Quad이름을 Floor_Sample로 변경해주고

큐브오브젝트를 이용해 Floor라고 이름지은 맵을 다시만들었습니다  (Tag 도 Floor로 지정해주어야 합니다)

 

Stage1

 

 

Stage2

개어렵네요 골드메탈님은 잘되던데 제겜은 족망겜인듯

 

 

이제 지형 아래로 떨어지면 다시 시작해봅시다

GameManager를 이용합니다

Box Collider라는 컴포넌트를 넣은다음 크기를 늘려줍니다(크게 해주셔야해요 안그러면 범위내로 안떨어져서 안태어나는 버그생김)

떨어져서 여기 닿으면 다시시작이라는 코드를 만들꺼니까 위치도 적당히 지정해주시고

Is Trigger체크하셔야합니다

 

GameManagerLogic.cs 에 추가해줍니다.

    void OnTriggerEnter(Collider other){

        if(other.gameObject.tag == "Player"){
            SceneManger.LoadScene("Stage"+Stage.toString());
        }
    }

 

이제 떨어지면 다시 시작됩니다.

 

 

 

UI꾸미기

 

캔버스 오브젝트를 하나 만들고

 

 

캔버스아래에다가 Image오브젝트를 만듭시다

쉬프트 눌러서 파란점까지 나오게 해서 끝에다 박아봅시다

 

아이템 몇개먹었는지 표시해 줄건데요 

 

 

글씨를 넣기 위해서 이제  Text 오브젝트를 캔버스 아래에 만들어주고 

이제 폰트를 넣어봅시다

폰트 폴더에 원하는 폰트를 드래그해서 불러옵시다

쿠키런 폰트를 가져왔습니다

 

쿠키런폰트로  먹은아이템수 / 총 아이템 수

이렇게 표현해주기로 합시다 

 

색을 다르게 하려고 텍스트 파일 2개만들었습니다

 

이제 시작해보면 다음과 같은 UI를 볼 수 있는데요

윽..구려

이제 실제로 데이터를 가지고 0/0수를 바꿔줍시다

 

마찬가지로 GameManager를 사용합니다.

GameManagerLogic.cs 에 먹은 갯수, 전체갯수 Text 2개의 객체를 만들어 주도록 합니다.

    public Text stageCountText; //스테이지 당 전체 아이템 수
    public Text playerCountText; //플레이어가 먹은 아이템 수

이 객체를 사용하려면 라이브러리를 추가해주어야 합니다.

using UnityEngine.UI;

이걸 맨 위에 적어주어야 하는데 오류가 나는 분들이 계셔서 (저도 나서 알아봤는데요..)

오류가나면 vscode의 버전을 1.13으로 내리면됩니다 

더보기

유니티에서

Window -> Package Manager

에서 Visual Studio Code Editor을 찾아줍니다

 

세모를 눌러서 여러가지 버전을 확인해 준 후

 

 1.1.3을 찾아서 Update to 1.1.3을 클릭해줍니다 (저는 이미 있어서 안나와서 1.1.2로 캡쳐했습니다)

 

이제 업데이트가 완료되면 유니티를 다 종료해주신다음에

프로젝트 폴더에 들어가서 

.sln .csproj 를 전부 삭제해주신 후

 

다시 유니티를 켜시면 정상적으로 작동될겁니다  

변수를 만들었으니 이제 어떤 객체를 가리키는지를 알려주셔야합니다. (변수명만 만들어진 상태임)

텍스트가 들어가야하는데 없는 상태이므로 우리가 만든 텍스트를 드래그해서 알맞게 넣어주면됩니다 (캔버스 밑에만든 텍스트들)

 

 

 

이제 값을 넣어봅시다.

전체 갯수는 이미 GameManager가 가지고있는 TotalItemCount를 사용하면 되겠네요

변수를 이용해 초기화 시켜주면됩니다.

    void Awake(){

        stageCountText.text = "/ "+TotalItemCount; 
     
    }

/도 여기에 넣어주었습니다

 

이제 playerCountText를 플레이어가 먹을 때 마다 변경해주어야 하므로 새로운 함수를 만들어 봅시다.

   
   //count를 매개변수로 받아서 PlayerCountText에 String으로 변환하여 넣어줌
   public void GetItem(int count){
        playerCountText.text = count.ToString();
    }

 

이제 이 함수를 플레이어(공)이 아이템을 먹을 때 마다 실행 count 로 알맞는 수를 넘겨주면되겠네요

플레이어가 아이템을 먹을때 수행되는 코드이므로

당연히 PlayerBall.cs에 써주셔야합니다.

    void OnTriggerEnter(Collider other){

        if (other.tag == "Item"){ //충돌 오브젝트가 아이템일때
            itemCount++; // 점수 올리기 
            audio.Play(); // 사운드 재생 
            other.gameObject.SetActive(false); //아이템 비활성화 
            manager.GetItem(itemCount); // UI텍스트 출력에 올라간 점수를 인자로 보냄 

        }
        else if(other.tag == "FinishPoint"){
            //생략
        }
    }

마지막 줄이 추가되었습니다.

ItemCount는 우리가 먹은 아이템의 수 (점수)이므로 이를 매개변수로 보내주었습니다.

 

 

이제 한번 실행해보면,

 

하나 먹을때마다 카운트가 올라가지는 것을 확인할 수 있습니다!

 

완성되었네요

 

 

저장

이제 컴퓨터용 게임으로 저장해봅시다

맥으론.. 맥용만 만들수 있나보네요... 여튼.. Build를 누르고 게임이름을 입력해봅시다

 

 

Save를 누르면 

 

 

 

저장이 완료되면

이렇게 생성이 됩니다 

클릭하면 게임을 실행해 볼 수 있는데요 

대체 어떻게 끄는건지 몰라서 강제종료했네요;

 

 

728x90

'GAME' 카테고리의 다른 글

[Unity2D]플레이어 이동/점프  (0) 2020.08.01
[Unity2D] 유니티 2D기본과 애니메이션  (0) 2020.07.31
[Unity]기초 3D게임 만들기-1  (4) 2020.07.30
[Unity]UI Setting  (0) 2020.07.17
[Unity]오브젝트 컨트롤  (0) 2020.07.17