유니티를 활용한 3D 적 피하기 게임 만들기(1)

728x90

적을 피하면서 코인을 최대한 많이 획득하는 미니게임을 만들어보자.

이번 단계에서는 기본적인 플레이 환경을 세팅하고 플레이어 및 코인 세팅까지만 완료해보도록 하겠다.

플레이어가 활동할 Floor는 큐브로 만들어 주었다. 구글에서 따로 받은 floor texture을 머터리얼에 입힌 후 큐브에 넣어 다음과 같은 기반을 완성했다. 여기서 floor texture는 새로 생성한 머터리얼의 Albedo 옆 작은 사각형에 넣어주면 활성화가 된다. 기본 텍스처에 Albedo값을 조정해주면 다양한 색상으로 바꿀 수 있고 Metallic과 Smoothness도 함께 바꿔 효과를 더할 수 있다.

다음으로 Capsule을 사용하여 player를 만들어주었다. add component에서 capsule collider와 rigidbody를 추가해주었다. 그리고 Character Controller라는 콤포넌트를 추가해주었으며 Player 스크립트도 작성했다. 스크립트의 Game Manager는 뒷부분에서 설명하겠다.

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

public class Player : MonoBehaviour
{
    public CharacterController controller;
    public float speed = 0.2f;
    public float x_pos_move;
    public float z_pos_move;
    Vector3 direction; // x, y, z 방향성을 가지고 있는 벡터 변수
    public Game_manager gameManager;
    bool isAttack = false;
    public MeshRenderer meshRD;

    void PlayerMove()
    {
        isAttack = false;
        meshRD.material.color = Color.white;
    }
    void OnTriggerEnter(Collider other)
    {
        if (other.name == "coin")
        {
            gameManager.EnableCoin_Invoke();
            gameManager.SetScore(2);
        }
        else if (other.name.Contains("Enemy") && isAttack == false)
        {
            isAttack = true;
            meshRD.material.color = Color.red;
            Invoke("PlayerMove", 3f); //3초 후 playermove 함수 호출
        }
    }

player 스크립트의 내용이다. 위/아래는 움직이지 않기 때문에 y값은 제쳐두고 X, Z 값만 사용했다. 여기서 CharacterController는 유니티에서만 제공하는 고유의 함수이고 캐릭터의 방향 이동에 유용한 함수이니 참고하면 되겠다. 마지막에는 OntriggerEnter()함수와 Invoke()함수 사용했다. 캐릭터가 coin에 닿으면 코인이 잠깐 없어졌다가 생겨나는(invoke)되는 로직이다. 해당 부분은 coin스크립트와 연결되는 부분이니 뒷부분 coin스크립트와 함께 참고하면 되겠다.

다음은 코인 오브젝트를 생성해주었다. 기존에 구글에서 가져온 코인 프리팹과 머터리얼을 활용하였다. 기본적으로 box collider에 isTrigger를 체크해주었고 Rotate스크립트와 Game_manager 스크립트를 추가해주었다.

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

public class Rotate : MonoBehaviour
{
    public float speed = 1.2f;
    Transform coinTR; //코인의 트랜스폼 변수
    void Start()
    {
        //코인 컴포넌트에 접근하여 대입
        coinTR = gameObject.GetComponent<Transform>();
    }
    void Update()
    {
        //유니티 제공 함수 Transform.Rotate(방향 * 속도);
        coinTR.Rotate(new Vector3(0, 0, 1) * speed);
    }
}

코인이 자동으로 회전하고 있게 만드는 함수이다. coinTR이라는 Transform변수를 생성해주었고 new Vector3(0,0,1)로 z축을 중심으로 회전하게 로직을 구성하였다.

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

public class Game_manager : MonoBehaviour
{
    public GameObject coin;
    float random_x_position;
    float random_z_position;
    public Text scoreText;
    int currentScore = 0;
    public int playTime = 30;
    public Text timeText;
    public GameObject GameOver_Scene; //게임 종료 화면
    public Text resultScore; //최종 점수 출력 텍스트
    public GameObject enemy;
    float enemy_x_pos;
    float enemy_z_pos;
    public ParticleSystem coinParticle;
    public AudioSource coinSFX;

    void CreateEnemy()
    {
        enemy_x_pos = Random.Range(-4.5f, 4.5f);
        enemy_z_pos = Random.Range(-4.5f, 4.5f);
        Instantiate(enemy, new Vector3(enemy_x_pos, 5, enemy_z_pos), Quaternion.identity);
    }
    void CoinEffect()
    {
        coinParticle.transform.position = coin.transform.position;
        coinParticle.Play();
    }
    void Start()
    {
        InvokeRepeating("CreateEnemy", 0, 3f);
        InvokeRepeating("Time_Calc", 0, 1f);
        EnableCoin();
    }
    public void EnableCoin()
    {
        coin.SetActive(true);
        random_x_position = Random.Range(-4.5f, 4.5f);
        random_z_position = Random.Range(-4.5f, 4.5f);
        coin.transform.position = new Vector3(random_x_position, 1.5f, random_z_position);
    }
    //코인 게임 오브젝트의 위치를 랜덤하게 표시
    public void EnableCoin_Invoke()
    {
        coin.SetActive(false);
        Invoke("EnableCoin", 2f);
        CoinEffect(); //코인 획득 시 코인 이펙트 함수 호출
        coinSFX.Play(); //코인 획득시 효과음 재생
    }
    //코인을 시간 차를 두고 생성하기 위함

다음은 중요한 Game_manger 스크립트이다. 플레이어가 코인을 한번 먹으면 끝나는게 아니라 랜덤위치에 지속적으로 생성되게 하기 위한 로직을 구성했다. 먼저 EnableCoin()함수단를 사용하여 x축으로 -4.5~4.5 / z축으로 -4.5~4.5 (foor 안 범위) 안에서 Random.range로 생성되게 작성했다. 그리고 EnableCoin_Invoke()함수단을 사용하여 코인이 SetActive(false) 즉, 플레이어와 부딪혀 사라지면 2f(2초)있다가 다시 생성(Invoke("EnableCoin)될 수 있게 로직을 구성했다. 이를 통해 시간차를 두고 코인을 생성할 수 있게 되었다.

마지막으로 하이라키창에서 Create empty를 생성하고 GameManger로 이름을 변경한 후 게임매니저 스크립트를 넣어주었다. public으로 선언된 coin 부분에 코인 프리팹을 넣어주었고, 완성된 게임매니저 오브젝트를 플레이어 인스펙터 창의 플레이어 스크립트에 넣어주었다.

 

여기까지 완성되면 floor위에서 플레이어가 방향키로 자유롭게 움직일 수 있고, 자동으로 회전하는 코인이 생성되며, 플레이어와 닿을 경우 일시적으로 없어지지만 2초 후 다시 random한 위치로 새로운 코인이 생성되면 되겠다. 

728x90