본문 바로가기
Hello, World!/Unity

유니티 닷지 게임 만들어보자(5)

by 27일 낮 2022. 2. 28.
728x90
    void Update()
    {
        // bulletPrefab의 복제본을 transform.position 위치와 transform.rotation 회전으로 생성
        GameObject bullet = Instantiate(bulletPrefab, transform.position, transform.rotation);

        // 생성된 bullet 게임 오브젝트의 정면 방향이 target을 향하도록 회전
        bullet.transform.LookAt(target);

    }
  • Instantiate(오브젝트, 위치) 생성!!
    => 한 프레임당 한번씩 반복되기 때문에 1초에 60번씩 총알을 날리고 있다..!

 

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

public class BulletSpawner : MonoBehaviour
{
    // 생성할 탄알의 원본 프리팹
    public GameObject bulletPrefab;
    // 최소 생성 주기
    public float spawnRateMin = 0.5f;
    // 최대 생성 주기
    public float spawnRateMax = 3f;

    // 실제 생성 주기
    private float spawnRate;
    // 최근 생성 시점에서 지난 시간
    private float timeAfterSpawn;
    // 발사할 대상
    private Transform target;
    
    void Start()
    {
        // 최근 생성 이후의 누적 시간을 0으로 초기화
        timeAfterSpawn = 0f;
        // 탄알 생성 간격을 spawnRateMin과 spawnRateMax 사이에서 랜덤 값 지정
        spawnRate = Random.Range(spawnRateMin, spawnRateMax);

        // PlayerController 컴포넌트를 가진 게임 오브젝트를 찾아서
        // 그 오브젝트의 위치값을 가져와
        target = FindObjectOfType<PlayerController>().transform;
    }

    void Update()
    {
        // timeAfterSpawn 갱신
        timeAfterSpawn += Time.deltaTime;

        // 최근 생성 시점에서부터 누적된 시간이 생성 주기보다 크거나 같다면
        if (timeAfterSpawn >= spawnRate)
        {
            // bulletPrefab의 복제본을 transform.position 위치와 transform.rotation 회전으로 생성
            GameObject bullet = Instantiate(bulletPrefab, transform.position, transform.rotation);

            // 생성된 bullet 게임 오브젝트의 정면 방향이 target을 향하도록 회전
            bullet.transform.LookAt(target);

            // 다음번 생성 간격을 spawnRateMin, spawnRateMax 사이에서 랜덤 지정
            spawnRate = Random.Range(spawnRateMin, spawnRateMax);

            // 누적된 시간을 리셋
            timeAfterSpawn = 0f;
        }
    }
}

 

 

 

Bullet Spawner에 Script랑 Bullet Prefab 스윽

와~ 총알이 나온다!

이제 bullet을 prefab화 하고, 배치해보자

 

 

  • prefab?
    = 재사용하기 위해 리소스화한거
        = 오브젝트를 재활용하기 위한 리소스
           = 오브젝트의 리소스화

따란!

 

오돌오돌 총알이 나온당

 


와 다 했다! 는 아니고,

이건 기능적인 개발만 했던 것임.

 

  • 문제점?
    • 밋밋함
    • 경쟁요소가 없음
  • 개선해보자!
    • 경쟁요소가 없으니 score를 추가하자
    • 게임성 -> 시간을 두고 뒤에 판을 빙글뱅글 돌릴거임
    • 게임 재시작도 가능하게 해보자

+) 게임을 기획할 때 고려해야할 점

  • 장르 구분, 동일 게임 있는지 확인
  • 게임 규칙!!

 

 

우린 우선!

게임매니저 스크립트 지정해줄거임

 

 

그은데, 너무 지저분하니 Hierarchy, Project 뷰 정리부터 해보자

Bullet Spawner를 Level에 넣어줌

 

 

                                            (정리 전)                                                > > >                                                    (정리 후)

 

 

이제 마저 해보자!

 

 

Rotator.cs 생성 -> Level에 할당

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

public class Rotator : MonoBehaviour
{
    public float rotationSpeed = 60f;

    void Update()
    {
        // Rotate 메서드는 입력값(매개변수)로 x, y, z축에 대한 회전값을 받고,
        // 현재 회전 상태에서 입력된 값만큼 상대적으로 더 회전합니다.
        transform.Rotate(0f, rotationSpeed * Time.deltaTime, 0f);
    }
}

Time.deltaTime을 곱해주지 않으면 겁나게 돈다

 

 


ui/ux : 사용자 인터페이스 / 사용자 경험

 

유니티에서의 ui 는 두개가 있다

  • ugui <-- 우리능 이거!
  • ngui

 

 

Time Text 생성

 

 

 

짱 큰게 생겼다!

어떤 ui 요소를 만들면 Canvas 안에 생기고, EventSystem이 생김 히히

 

 

canvas 클릭하고 2d를 누르면 보기 좋게 바뀐다

왜 캔버스 크기가 저러죠?

-> Free Aspect 상태이기 때문!

 

 

모니터 사이즈에 맞춰서 Full HD로 바꿔주었다

 

 

텍스트를 손봐보자.

 

Time Text의 Inspector를 보면, Rect Transform 이당

일반적인 2d용 transform이라고 생각하면 됨! ui는 2d니까~

 

 

앵커프리셋 : 기준점을 잡아주는 거

alt + shift 누른 상태에서 중앙 상단을 눌러주자 (top-center)

 

위에 딱 붙음!

 

이제 내용을 수정해보자

근데 폰트가 키워도 키워도 작다....

16:9 Aspect로 바꿔주자!

Horizontal Overflow, Vertical Overflow를 Overflow로 지정해두지 않으면

글씨가 글상자를 넘어가면 보이지 않는다! Overflow로 해야함!

 

 

그림자도 주었당 ㅎㅎ



Time Text 복사해서 Gameover Text 로 이름 바꿔줌!

눈에 안 보여서 선도 넣어주었다 (Outline)

 

 

또 텍스트를 복사해서 Record Text를 만들어주자

그리고 Record Text는 Gameover Text 아래로 넣어주자

이제 죽었을 때만 저 메시지가 나와야하니까 Gameover Text 비활성화 해줌

 

 

그리고 게임 매니저 스크립트를 만들자!

C#스크립트로 새로 생성하는데, 이름을 GameManager로 해줘야함! 아이콘 바뀌어져있다

 

그리고 GameManager 오브젝트 생성 (Create Empty) 후 GameManager 스크립트 할당

 

 

작성해보자!

 

 

 

게임 ui 컨트롤, 게임 오버시 재시작 => 라이브러리를 써야함

using UnityEngine.UI;
using UnityEngine.SceneManagement;

이 둘을 선언해주자!

 

 

텍스트 필드가 문자열이라서 그냥 int를 쓰면 에러가 뜬다

 

 

또는

 

이렇게 문자열을 달아주자!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// UI 관련 라이브러리 사용할래~
using UnityEngine.UI;
// 씬 관리 관련 라이브러리 사용할래~
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour
{
    // 게임 오버 시 활성화할 텍스트 게임 오브젝트
    public GameObject gameOverText;
    // 생존 시간을 표시할 텍스트 컴포넌트
    public Text timeText;
    // 최고 기록을 표시할 텍스트 컴포넌트
    public Text recordText;

    // 실제 생존 시간
    private float surviveTime;
    // 게임 오버 상태
    private bool isGameOver;

    void Start()
    {
        // 생존 시간과 게임 오버 상태 초기화
        surviveTime = 0f;
        isGameOver = false;
    }

    void Update()
    {
        // 게임 오버가 아닌 동안
        if (!isGameOver)
        {
            // 생존 시간 갱신
            surviveTime += Time.deltaTime;
            // 갱신한 생존 시간을 timeText 컴포넌트를 이용해 표시
            timeText.text = "Time : " + (int)surviveTime;
        }
    }

    // 현재 게임을 게임 오버 상태로 변경하는 메서드
    public void EndGame()
    {
        // 현재 상태를 게임 오버 상태로 전환
        isGameOver = true;
    }
}

누가 게임 오버 상태로 전환하니!? -> 플레이어가 죽으면! 실행되어야하니까 플레이어!

 

 

PlayerController.cs

...
	public void Die()
    {
        my.SetActive(false);
        // gameObject.SetActive(false); = 위와 같음

        // 씬에 존재하는 GameManager 타입의 오브젝트를 찾아서 가져오기
        GameManager gameManager = FindObjectOfType<GameManager>();

        gameManager.EndGame();
    }
}

FindObjectOfType 모든 오브젝트를 열어서 확인함 -> 거기서 GameManager 를 찾고 가져와~

(얘는 많이 쓰면 안됨! 한번만!)

 

 

 

각각 텍스트 할당해주자

 

 

플레이 해보았다!!!!

죽으면 초가 안 올라간다!

근데 게임오버 안뜸!

 


시간은 멈췄는데 게임오버, 최고기록 텍스트가 안나옴

유니티가 제공해주는 player preference (json와 비슷한 형식)

댓글