Vector2 jumpPw = new Vector2(0, jump);  // 점프벡터 생성
rbody.AddForce(jumpPw, ForceMode2D.Impulse); //순간적인 힘 가하기
goJump = false; // 점프플래그 끄기

플레이어 Tag지정하기

플레이어를 선택하고 Tag를 player를 선택합니다. player Tag는 기본적으로 있습니다.

 

점프 구현하기

스페이스바를 눌렀을때 캐릭터를 점프하게 만들어 보겠습니다.

Update()함수에 스페이스키를 체크되면 Jump()함수를 호출하는 코드가 추가되었습니다. 

Jump() 함수는 goJump 플래그를 true로 할 뿐입니다.

public void Jump() {
    goJump = true;
}

실제 점프 동작은 FixedUpdate()에서 if(onGround && goJump) 때 이루어 집니다. 

Vector2 jumpPw = new Vector2(0, jump);  // 점프벡터 생성
rbody.AddForce(jumpPw, ForceMode2D.Impulse); //순간적인 힘 가하기
goJump = false; // 점프플래그 끄기

플레이 해보면 스페이스바를 눌러도 캐릭터가 점프를 안하는데 LayerMask 변수인 groundLayer를 인스펙터뷰 playerController 스크립트 창에서 ground로 설정해야 합니다.

public LayerMask groundLayer; //착지할 수 있는 레이어
bool onGround = false;  //지면에 서 있는 플래그

Linecast가 캐릭터위치에서 0.1f 아래로 광선을 쏴서 goundLayer가 감지될경우만 onGround를 true시킵니다.

onGround = Physics2D.Linecast(transform.position, 
					transform.position - (transform.up * 0.1f), groundLayer);

Linecast(시작점, 종료점, 마스크)

 

아래는 playerController.cs 전체코드입니다.

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

public class PlayerController : MonoBehaviour{
    // Start is called before the first frame update
    Rigidbody2D rbody;  // Rigidbody 참조
    float axisH = 0.0f; //입력
    public float speed = 3.0f;  //이동속도

    public float jump = 9.0f; //점프력
    public LayerMask groundLayer; //착지할 수 있는 레이어
    bool goJump = false; //점프개시 플래그
    bool onGround = false;  //지면에 서 있는 플래그
    void Start(){
        rbody = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update(){
        axisH = Input.GetAxisRaw("Horizontal");
        if(axisH > 0.0f) {
            transform.localScale = new Vector2(1, 1);
        } else if (axisH <0.0f) {
            transform.localScale = new Vector2(-1, 1);
        }
        if (Input.GetButtonDown("Jump")) {
            Jump();
        }
    }
    private void FixedUpdate() {
        //착지판정
        onGround = Physics2D.Linecast(transform.position, transform.position - (transform.up * 0.1f), groundLayer);
        if(onGround || axisH !=0) {  //점프상태일 때는 전진 안함.
            rbody.velocity = new Vector2(speed * axisH, rbody.velocity.y);
        }
        if(onGround && goJump) {
            Vector2 jumpPw = new Vector2(0, jump);  // 점프벡터 생성
            rbody.AddForce(jumpPw, ForceMode2D.Impulse); //순간적인 힘 가하기
            goJump = false; // 점프플래그 끄기
        }
    }
    public void Jump() {
        goJump = true;
    }
}

 

이번에 만들 게임요소를 정리해 보겠습니다.

  • 규칙 : 오른쪽 끝의 골인 지점에 도착하면 게임 클리어
  • 적과 장애물 : 함정에 떨어지면 게임 오버
  • 간섭과 변화 : 점프로 함정 뛰어넘기
  • 보상 : 함정을 피해서 목표 지점에  도착

 

4.1 사이드뷰게임

사이드뷰는 게임 속 세상을 옆에서 바라본 시점의 게임 시스템입니다. 이동은 좌우나 점프를 위해 상하로 움직일 수 있습니다. 

 

사용할 게임 오브젝트와 스크립트 생각해보기

  • 플레이어 캐릭터 : 좌우이동과 점프를 할 수 있습니다. 이동이나 점프를 묘사할 애니메이션을 적용합니다.
  • 지면과 블록 :  플레이어가 올라가서 이동할 수 있는 지면과 점프해 올라갈 수 있는 발판이 되는 블록입니다.
  • 골인 지점과 게임 오버 : 게임 스테이지의 오른쪽 끝에 게임 오브젝트를 배치해 이곳에 접촉하면 스테이지 클리어되도록 목표지점을 만듭니다. 지면 아래로 떨어지면 게임 오버되는 처리도 추가합니다.
  • 상태 표시와 재시작 : 게임으 시작및 게임오버 클리어했을 때의 화면을 표시하고 다시 처음부터 시작할 수 있게 합니다. 

4.2 샘플 게임 실행해보기  

Jewlry Hunter폴더내의 프로젝트를 플레이 해보시면 됩니다.

4.3 게임 스테이지 만들기

지면 블록 만들기

이전에 연습했던 프로젝트를 사용합니다.

프로젝트뷰의 Block들을 끌어다 씬뷰에 배치합니다.

위와 같이 보이지 않을겁니다. 왜냐하면 Order in Layer가 밑에 있기 때문에 가려져서 그렇습니다.

하이라키에서 방금 끌어온 block들을 선택해고 인스펙터뷰의 Additional Settings의 Order in Layer를 2로 하면 위와 같이 블록들이 보입니다.

레이어로 게임 오브젝트를 그룹으로 분류하기 (레이어)

유니티는 게임오브젝트를 이름으로 식별할 수 있지만 "레이어"를 사용해 그룹으로 묶을 수도 있습니다. 바닥과 블록을 Ground라는 이름으로 그룹화해 플레이어 캐릭터가 레이어에 접촉할 때만 점프할 수 있도록 합니다.

인스펙터뷰의 레이어 Item을 눌러 Add Layer로 Ground 레이어를 추가합니다.  보통 0~5까지는 유니티가 사용중이므로 레이어6에 새로 만듭니다.

레이어 추가 메뉴는 게임오브젝트 메뉴와 독립적이라 돌아갈 수 없고 다시 하이라키의 게임오브젝트를 선택해야 합니다.

한꺼번에 레이어를 바꾸기 위해 하이라키에서 ground 와 블록3가지를 선택하고 인스펙트뷰에서 레이어를 6으로 바꿔줍니다.

씬뷰에 goal팻말을 배치하고 인스펙터뷰에서 Order in Layer를 2로 바꿔줍니다.

골인 지점 도달 판별하기

목표에 도달한것을 판별하기 위해 goal에 Box Collider2D 컴포넌트를 추가하고 Is Trigger를 체크합니다. Is Trigger는 물리적인 충돌없이 충돌 이벤트만 만듭니다.

 

게임오브젝트를 구별하는 방법(태그)

골인 지점에 도달했는지 판별하는 방법중 태그(Tag)도 있습니다. 

하이라키에서 goal을 선택후 인스펙트뷰에서 Tag를 눌러 Add Tag에서 Goal을 만들고 저장합니다. 이후 Goal에서 지정합니다.

게임오브젝트 재사용하기

유니티에서 프리팹은 재사용가능한 "클래스"같은 개념입니다. 하이라키의 ground,block1,2,3,goal등을 끌어다 프로젝트뷰에 끌어다 놓으면 자동으로 프리팹이 만들어 집니다. 하이라키의  ground,block1,2,3,goal등은 이미 파란색으로 바뀌었는데 이건 프리팹의 인스턴스라는 이야기 입니다. 프리팹을 사용하고 싶으면 아이콘을 끌어다 하이라키나 씬뷰에 놓으면 인스턴스가 만들어집니다.

프로젝트뷰의 프리팹은 런타임시 존재하지 않습니다. 씬뷰에서 인스턴스화 되었을때 비로서 런타임에서 존재하고 접근할 수 있습니다. 이점이 중요합니다. 클래스나 타입도 변수화 하지 않으면 아무것도 아닌것 처럼요.

프리팹을 변경하면 기본에 만들었던 모든 인스턴스에 영향을 미칩니다. 반대로 인스턴스를 변경해면 유니티에서 프리팹을 변경할건지 물어보는 개념도 있습니다. 이걸 오버라이드라고 합니다.

프리팹을 정리하기 위해 프로젝트뷰 Assets 폴더안에 Prefabs폴더를 만들고 만들어진 프리팹들을 끌어다 놓습니다.

 

프리팹을 배치해 지면 만들기

프리팹 폴더안의 프리팹들을 이용해 다음과 같이 지면과 블록을 더 배치 합니다. (이미지 폴더가 아닙니다.)

백그라운드는 back_title에서 back으로 바꾸었습니다. 길게보이는 그라운드는 확대한게 아니라 같은 그라운드를 2개 연결한것입니다.

 

게임 오브젝트 정렬하기

옮길 오브젝트를 살짝 클릭해서 선택해줍니다. 마우스클릭하지 않고 키보드 V를 눌러 맞추고 싶은 중앙이나 모서리를 클릭하면서 맞출곳에 가져가면 자석같이 붙습니다. 화면을 좀 크게하시는게 잘되고 한번에 안되면 옮긴후 다시 시도 하면 됩니다.

 

보이지 않는 충돌 판정 만들기

하이라키의 +를 눌러 Create Empty를 클릭합니다. 이름을 Wall로 합니다. Box Collider 2D를 2개 추가합니다.

Edit  Collider를 눌러 충돌영역의 위치를 화면 양옆으로 이동시킵니다. BoxCollider2D를 2개 추가했기 때문에 영역이 2개 입니다. 

플레이해보면 캐릭터가 왼쪽벽에 부딪쳐 가지 못합니다. 

 

게임오버 판별하기

현재는 구덩이쪽으로 가면 캐릭터가 빠져 계속 떨어지기 때문에 게임진행이 더 이상 불가능 합니다.

DeadZone이라는 빈게임오브젝트를 만들고 BoxCollider2D컴포넌트를 추가하고 Is Trigger를 체크합니다.  Edit Collider를 누루고 다음과 같이 화면 아래 배치합니다. 

Dead라는 Tag를 만들어 지정해 줍니다.

 

 

 

 

 

스크립트로 게임 오브젝트 조작하기

Rigidbody2D나 Box Collider등과 같은 컴포넌트들을 게임오브젝트에 추가했던것 처럼 스크립트를 컴포넌트처럼 추가할 수 있습니다.

 

스크립트 파일 만들기

게임오브젝트에서 Add Component에서 스크립트를 추가할 수도 있고 프로젝트뷰에서 스크립트를 만들어 나중에 추가할 수도 있습니다. 프로젝트뷰에서 Scripts폴더를 만든후 폴더안에서 우클릭후 Create>Script를 클릭후 이름을 PlayerController로 바꿔줍니다.

키 입력으로 게임 오브젝트를 조작하는 스크립트

Rigidbody2D rbody;  // Rigidbody2D의 참조입니다.

게임오브젝트 생성시 불리워지는 Start() 함수에서 rbody변수에 Rigidbody2D 참조를 연결합니다.

매 프레임 불리워지는 Update()에서 키보드입력을 받습니다. axisH = Input.GetAxisRaw("Horizontal");

일정한 간격으로 호출되는 FixedUpdate()에서 Rigidbody 2D컴포넌트를 사용중이므로  Rigidbody를 물리를 이용 객체의 위치를 변경시킵니다. rbody.velocity = new Vector2 (axisH * 3.0f, rbody.velocity.y);

Rigidbody를 사용하지 않을경우 Transform컴포넌트를 이용 객체를 이동시키나 Rigidbody를 사용시는 되도록 Rigidbody를 사용해야 합니다. 이는 Rigidbody가 Trnasform컴포넌트 보다 나중에 실행되어지기 때문입니다.

저장후 Pplayer_stop에 적용시켜줍니다. 플레이후 AD키를 누르면 좌우로 움직입니다.

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

public class PlayerController : MonoBehaviour
{
    // Start is called before the first frame update
    Rigidbody2D rbody;
    float axisH = 0.0f;
    void Start()
    {
        rbody = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {
        axisH = Input.GetAxisRaw("Horizontal");
    }
    private void FixedUpdate() {
        rbody.velocity = new Vector2 (axisH * 3.0f, rbody.velocity.y);
    }
}

변수부분에 public float speed = 3.0f; 를 추가하고 상수 3.0f대신 speed를 사용합니다.

캐릭터가 좌우로 움직일 경우 진행 방향을 바라보기 위해 transform.localScale을 이용합니다. 물리상 - Scale은 말이 안되지만 유니티에서는 반전을 뜻합니다.  (-1,1)은 x축만 반전 시키겠다는 의미입니다.

if(axisH > 0.0f) { //오른쪽 처리
    transform.localScale = new Vector2(1, 1);
} else if (axisH <0.0f) {  //왼쪽 처리
    transform.localScale = new Vector2(-1, 1);
}

저장하고 실행해보면  캐릭터가 진행방향에 따라 반전하는걸 알수 있습니다. 

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

public class PlayerController : MonoBehaviour{
    // Start is called before the first frame update
    Rigidbody2D rbody;
    float axisH = 0.0f;
    public float speed = 3.0f;
    void Start(){
        rbody = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update(){
        axisH = Input.GetAxisRaw("Horizontal");
        if(axisH > 0.0f) {
            transform.localScale = new Vector2(1, 1);
        } else if (axisH <0.0f) {
            transform.localScale = new Vector2(-1, 1);
        }
    }
    private void FixedUpdate() {
        rbody.velocity = new Vector2 (speed * axisH, rbody.velocity.y);
    }
}

실행해보면 좌우방향에 따라 캐릭터가 반전한다.

2.1 새프로젝트 만들기

2D 프로젝트 만들기

유니티 허브에서 우상 New project를 클릭후  2D템플릿을 선택후 이름을 UniSideGame으로 하겠습니다.

샘플 게임과 샘플 에셋 다운로드

아래 사이트에서 예제를 다운 받아  풀어보니까너무 커서 컴퓨터 멈출정도로 느리네요 ㅠㅠ  너무 커서 그냥 풀지 마시고 아래에서 그때  그때 필요한 파일을 올려드릴께요

https://bit.ly/unity2d_jpub

 

unity2d_jpub.zip

 

drive.google.com

 

2.2 게임화면 만들기

이미지 에셋을 프로젝트에 등록하기

압축파일을 풀어서 Playes, Images 폴더 통채로 Assets폴더로 복사합니다. 

Images.zip
2.11MB
Player.zip
0.36MB

이미지 에셋으로 게임화면 만들기

하이라키에 다음과 같이 Images/back, ground, Player폴더의 player_stop이미지를 끌어다 놓는다. 플레이해 보면 예상과 다르게 배경만 보인다. player_stop의 이름은 player로 바꿉니다.

트랜스폼

트랜스폼:  위치, 화면 크기를 조절하는 컴포넌트 입니다. 

스프라이트랜더러

스프라이트랜더러 :  이미지를 표시하는 컴포넌트입니다. 다음과 같은 값을 가지고 있습니다.

Sprite : 표시할 이미지에셋을 나타냅니다.

Color : 색감변경

Flip : 상하좌우로 반전시킬수 있습니다.

Sorting Layer: 게임오브젝트를 레이어라는 그룹으로 묶고 표시의 우성순위를 그룹별로 지정할 수 있습니다.

Order in Layer : Sorting Layer로 나눈 레이어 중 게임 오브젝트가 씬에 표시되는 순서를 정합니다. 값이 클수록 앞에 표시됩니다.

 

게임 오브젝트의 이미지 변경하기

스프라이트렌더러에는 이미지의 파일명이 표시된  Sprite라는 항목이 있습니다. Sprite를 클릭하면 프로젝트뷰에서 해당 이미지 에셋이 강조돼 어느 에셋이 사용되는지 확인할 수 있습니다.

이미지를 선택한후 Delete키를 클릭해 제거해 보면 씬뷰에서보이지 않게 되지만 하이라키뷰에서는 게임오브젝트가 남아 있습니다.

다시 이미지를 설정해 봅시다. 이미지가 제거 되었으니 계층뷰에서 게임오브젝트를 선택합니다. 프로젝트 뷰의 이미지를 선택해 Sprite의 오른쪽 텍스트박스에 드래그앤드롭합니다.

 

표시우선순위를 알아보기

지면이나 캐릭터 등은 항상 배경보다 앞에 표시돼야 해 표시 우선순위를 의도적으로 변경해야 합니다. 우선순위를 높이려면 Sprite Renderer 컴포넌트의 Additional Settings에서 Order in Layer의 값을 크게 합니다. 여기서는 배경 0, 플레이어는 3, 지면은 2로 설정했습니다. 드디어 보이네요

게임 오브젝트 재배치하기

title_back: (4,0,0), ground:(-5,-2,0), player_stop:(-5,0,0)

 

게임 오브젝트에 중력(Rigidbody 2D)추가하기

 하이라키에서 player_stop을 선택하고 오른쪽 인스펙터부에서 Rigidbody 2D 컴포넌트를 추가합니다.

플레이해보면 플레이어가 아래로 떨어집니다.

 

충돌판정, ground에 Box Collider 2D 추가하기

하이라키에서 ground를 선택하고 Box Collider 2D를 선택 추가합니다. 

플레이 해보면 아직도 플레이어가 떨어집니다. 이제 플레이어에도 Box Collider 2D를 추가해보면  다음과 같이 사각형이 생기는데 Edit Collider를 누르면 사각형 색과 모양이 다음과 같이 바끼고 크기를 조정할 수 있습니다. Capsule Collider 2D를 선택하면 좀더 타이트하게 설정도 가능합니다. 가벼운 처리를 위해서는 Circle Collider 2D가 있습니다. 대량의 적 캐릭터의 충돌 판정에 적합합니다.

 

플레이 해보면 캐릭터가 그라운드 위에서 멈춥니다.

 

PlayerShooter 스크립트를 새로 만듭니다. 첨부된 파일을 Assets에 추가하셔도 됩니다.

PlayerShooter.cs
0.00MB

스크립트를 Player에 추가합니다. 플레이어에는 다음과 같이 3개의 스크립트가 추가되어 있고 다음과 같이 참조들이 연결되어 있어야 합니다.

GunShooter의 전체 스크립트입니다.

gun.Fire(),gun.Reload()가 있는 gun의 참조를 글로벌로 받아오고

입력을 받아올 playerInput컴포넌트를 playerInput 참조에 연결해줍니다.

 

Update() 에서 playerInput.fire가 참이면 gun.Fire()를 실행해 총알을 발사합니다. playerInput.fire가 참일경우 gun.Reload()를 실행합니다. Animatior가 있는 경우 애니메이션을 실행하나 여기서는 실행하지 않습니다. 마지막으로 UpdateUI()함수를 불러 UI를 업데이트 합니다. 아직 UI가 null이므로 실행하지는 않습니다.

using UnityEngine;

// 주어진 Gun 오브젝트를 쏘거나 재장전
// 알맞은 애니메이션을 재생하고 IK를 사용해 캐릭터 양손이 총에 위치하도록 조정
public class PlayerShooter : MonoBehaviour {
    public Gun gun; // 사용할 총
    public Transform gunPivot; // 총 배치의 기준점


    private PlayerInput playerInput; // 플레이어의 입력
    //private Animator playerAnimator; // 애니메이터 컴포넌트

    private void Start() {
        // 사용할 컴포넌트들을 가져오기
        playerInput = GetComponent<PlayerInput>();
        //playerAnimator = GetComponent<Animator>();
    }

    private void OnEnable() {
        // 슈터가 활성화될 때 총도 함께 활성화
        gun.gameObject.SetActive(true);
    }

    private void OnDisable() {
        // 슈터가 비활성화될 때 총도 함께 비활성화
        gun.gameObject.SetActive(false);
    }

    private void Update() {
        // 입력을 감지하고 총 발사하거나 재장전
        if (playerInput.fire) {
            // 발사 입력 감지시 총 발사
            //Debug.Log("Player Shooter Input.fire");
            gun.Fire();
        } else if (playerInput.reload) {
            // 재장전 입력 감지시 재장전
            if (gun.Reload()) {
                // 재장전 성공시에만 재장전 애니메이션 재생
                //playerAnimator.SetTrigger("Reload");
                Debug.Log("Reload");
            }
        }

        // 남은 탄약 UI를 갱신
        //UpdateUI();
    }

    // 탄약 UI 갱신
    /*
    private void UpdateUI() {
        if (gun != null && UIManager.instance != null) {
            // UI 매니저의 탄약 텍스트에 탄창의 탄약과 남은 전체 탄약을 표시
            UIManager.instance.UpdateAmmoText(gun.magAmmo, gun.ammoRemain);
        }
    }
    */

    // 애니메이터의 IK 갱신
}

'유니티좀비게임 > 총과슈터' 카테고리의 다른 글

GunData 스크립트  (0) 2023.04.28
총 게임오브젝트  (0) 2023.04.28
인터페이스  (0) 2023.04.28

테스트 하다보면 적이 어디서 나타났는지 찾기 어렵다. 마우스 우클릭을 하면 적을 보게 하겠다. 적을 고를 수는 없다.

첫번째 방법은 씬뷰상의 MONSTER TAG를 이용해 적을 찾은후 LookAt하는 방법이다.

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

public class RightClick : MonoBehaviour
{
    // Start is called before the first frame update
    public GameObject[] monster;  //컴포넌트의 캐시를 처리할 변수
    public int idx = 0;

    // Update is called once per frame
    void Update()
    {
        monster = GameObject.FindGameObjectsWithTag("MONSTER");
        if (Input.GetMouseButtonDown(1)) {
            idx = monster.Length-1;
            while (idx>=0 && monster[idx].GetComponent<MonsterCtrl>().state == MonsterCtrl.State.DIE) idx--;
            transform.LookAt(monster[idx].transform);
            Debug.Log(monster.Length);
        }
    }
}

2번째 방법은 GameManager MonsterPool을 이용해 active한걸 찾아 LookAt하는 방법이다

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

public class RightClick : MonoBehaviour
{
    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(1)) {
            GameObject _monster = FindMonster();
            if (_monster != null) {
                transform.LookAt(_monster.transform);
            }
        }
    }
    GameObject FindMonster() {
        foreach (var _monster in GameManager.instance.monsterPool) {
            if (_monster.activeSelf == true) {
                return _monster;
            }
        }
        return null;
    }
}

실행후 우클릭을 하면 적으로 자동 향합니다. 천천히 움직이지는 않습니다.

모든 Active한 Monster의 거리를 비교해 가장 가까운 몬스터를 향하게 할수도 있을듯.

이 책에서 개발할 게임은 3인칭 시점  슈팅(TPS, Third Person Shooting)게임 이다.

1인칭시점 슈팅(FPS, First Person Shooing)게임게임과 더불어 인기가 많은 장르의 게임으로, 주인공과 적캐릭터가 전투를 벌이는 단순한 시나리오의 게임이다.

 

프로젝트 생성

3D 템플릿을 선택한후 이름을 SpaceShooter로 하고 프로젝트를 생성한다.

프로젝트뷰에 Scenes, Scripts, Prefabs, Images, Models, Sounds, Animations폴더를 만들어둔다. 

 

캐릭터모델 임포트하기

사용할 주인공 캐릭터는 MADFINGER Games사의 ShadowGun:Daedzone게임의 에셋을 사용한다. 현재는 에셋에서 다운받을수 없어서 일부를 다음 깃 허브에서 다운 받는다.

 

https://github.com/IndieGameMaker/IndieGameMaker

 

GitHub - IndieGameMaker/IndieGameMaker

Contribute to IndieGameMaker/IndieGameMaker development by creating an account on GitHub.

github.com

출판사에서 다운로드해도 되는것 같다.

다운로드후 Resources/Models폴더에 있는 Player.unitypackage를 프로젝트뷰 끌어와 설치할 수 있다. unitypackage는 에셋과 그 메타데이터를 저장한 압축파일이다.

새로 설치된 Player폴더를 Models폴더 밑으로 넣는다.

 

무료리소스 내려받기

책에서는 여러가지 리소스를 다운받는 법을 써 놨는데 그냥 깃에서 다운받으면 편하고 정확하다.

https://github.com/IndieGameMaker/SpaceShooter2021

Assets Store에서 yughues metal검색한후 내려받았는데 교재랑 같은 그림을 내려받았는데 내부 내용이 교재와 다르다 그냥 깃에서 다운받기를 권장한다.

하늘을 표시할 Skybox Volume2(Nebula)도 내려 받는다 

마지막으로  Barrel을 검색해 다운받는다.

리소스들을 import한후 Barrel은 Models폴더로 Sky와 Metal은 Images폴더로 정리한다.

에셋스토어에서 Add한 에셋들은 PackageManager에서도 Download 후 import할수 있다.

Scenes폴더 안의 SampleScene을 선택후 F2를 눌러 이름을 Play로 바꾼다.  Reload할껀지 물어보면 [Realod]를 눌러 갱신한다.

 

게임엔진은 유니티외에도 언리얼, 크라이, 하복, 게임브리오 소스엔진 등이 있다. 

유니티는 게임엔진으로 개발되었으니 게임 이외의 분양에서도 널리 사용되기에 리얼타임 3D 플랫폼이라는 부재를 달고 통합 멀티미디어엔진으로 발전되고 있다. 이것이 유니티를 공부하게 된 주된 이유이다.

 

아담이라는 단편 애니메이션이 유니티5로 제작되었고 Adam the Mirror라는 단편영화도 2017버전으로 제작되었다. 블레이드러너2049의 특수 효과에도 유니티가 활용됐다. 최근 유니티데모팀이 The Heritic이라는 고해상도 파이프라인 (HDRP)과 VFX의 장점을 잘 보여주는 단편영화를 선보인바 있다.

 

https://www.youtube.com/results?search_query=The+Heritic 

 

https://www.youtube.com/results?search_query=The+Heritic

 

www.youtube.com

 

유니티의 기본적인 인터페이스는 많은 창이 보인다.

각 창은 뷰라고도 불리고 다음과 같은 중용한 뷰가 있다.

프로젝트뷰 : 콘텐츠 제작에 필요한 모든 리소스들을 모아두고 만드는 곳.

씬뷰 :  프로젝트의 리소스를 재배치하여 3D 스테이지를 디자인하고 게임을 설계하는 뷰

하이라키뷰 : 씬뷰에 배열된 오브젝트들을 Transform Sort방식으로 정렬해서 보여준다. 오브젝트들은 메뉴에서 이동 복사 삭제가 가능하다. Preference창에서 Alphanumeric Sorting으로 변경 가능하다.

인스펙터뷰 : 선택된 게임오브젝트와 에셋의 속성창, 컴포넌트의 삽입 삭제가 가능하다.

게임뷰 : 개발 진행 중에 게임을 실행해 미리 볼 수 있는 뷰. 메인 카메라의 시야로 렌더링해서 보여준다.

콘솔뷰 : 디버깅시 로그를 출력하는 뷰, 메시지는 정보, 경고, 오류등이 있다.

툴바 : 화면이동, 객체이동, 회전, 스케일,  UI객체의 이동,회전, 스케일, 트랜스폼, 단축키QWERTY 

 

피봇/센터

화면 우상에 위치한 십자가같은 모양, 객체의 중심좌표 표시기준, Pivot은 모델링때 설정한 원점좌표가 표시되며 Center는 원점좌표가 무시되며 모델의 중앙에 표시된다. Center는 잘 안 쓰인다.

 

로컬/글로벌

글로벌 좌표는 3차원 공간의 절대 좌표를 의미하며 변하지 않는 절대 기준 좌표이다. 반면 씬뷰에 있는 객체를 중심으로 한 좌표를 로컬좌표라고 한다.

 

단축키

F : 게임오브젝트를 하이라키에서 선택하거나 씬뷰에서 선택한후 F키를 누르면 해당 객체가 포커싱된다.

FF : F키를 더블클릭하던가 Shift+F로 게임을 실행하는 중 이동하는 게임오브젝트를 자동으로 따라가게 할수 있다.

마우스휠 또는 AL + 마우스우클릭 + 마우스이동 : 씬뷰 Zoom

마우스 우클릭 + WASDQE : 시야각 변화

Shift+Space : 뷰가 최대화/최소화 된다.

유니티의 단축키는 Edit>Shortcuts에서 확인 편집할 수 있다.

유니티는 언리얼과 더불어 유명한 게임엔진중 하나 이다.

유니티를 이용해 하루면 재미있게 게임을 만들 수도 있다.

우리가 Microsoft사의 Word나 Excel을 필요한 기능만 사용해 이용한다. 사실 Excel은 자격증이 있을 정도로 다양한 기능을 제공한다. 아마 Word나 Excel를 공부만 한다면 끝까지 못 읽고 다들 포기할 것이다.

유니티도 마찬가지 이다. 엄청난 기능을 갖추고 있다. 이걸 다 읽고 게임을 만들겠다고 생각하면 오산이다. 그냥 고시공부하는게 좋을지도 모른다.그러나 점점 개념이 잡히면서 책을 읽는 속도가 늘어난다.

유니티를 이용해 하루만에도 게임을 만들수도 있지만 처음하시는 분들에게 유니티는 쉽지 않을수도 있다.

게임을 만들수 있다는 기대감으로 처음 유니티를 공부할때는 책을 따라하기 조차 쉽지 않았다. 포기하고 유튜브를 보기도 했다.  되도록 간단히 공부가 끝나면 직접 게임을 만들어보고 부족한 부분을 구글링하면서 배워보시기 바랍니다. 그럼 점점 머리속에서 유니티가 정리되는 걸 느끼실 겁니다.

 

유니티는 3D게임엔진이라 3차원 개념의 이해가 필요하나 그때 그때 공부하시면 됩니다.

복잡한 벡터나 선형대수의 계산은 유니티가 알아서 해주니 걱정 안하셔도 됩니다. 수학을 모르니 게임을 못배운다고 구박하는 선생님도 있지만 그런 사람을 위해 계산기 있다고 생각합니다. 잘 사용하면 됩니다. 필요한건 게임을 만들겠다는 목표의식과 이를 뒷받침해줄 인내와 끈기와 입니다.

유니티를 공부만 하지 마시고 직접 게임을 만들어 보시기 바랍니다.  쌈을 많이 해본 사람이 쌈을 잘하는거죠. ㅎㅎ

그리고 가능하면 무료학원이나 게임잼 같은데 가보세요. 짧은 기간이라도 괜찮습니다. 남들이 열심히 하는걸 보면 자극이 됩니다.

물로 프로 게임프로그래머가 되기 위해서는 눈감고도 할 수 있는 정도가 되어야 한다. 남의 돈 받는게 쉽지 않다. 사실 프로게이머가 되기 위해서는 유니티 이외에도 인공지능, 알고리즘, 자료구조, 통신, 컴퓨터사이언스, 데이터베이스, Directx, 게임물리, 수학 할게 산넘고 산이다. 잘 생각해보시기 바란다. 가성비로는 그냥 다른 프로그래밍 분야가 페이는 훨 나을수도 있다. 그러나 아마 이 글을 일고 계신분들은 게임을 사랑하시는 분들이라 판단이 쉽지 않겠지만 직업은 직업일뿐이다.

솔직히 게임시장이 크지만 게임엔진의 발달로 너무나 많은 게임이 나와 경쟁이 무지무지해 이미 레드오션입니다. 대형게임사는 외국것 들여다 팔기 급급하거나 기존게임을 현질로 우려먹는다던지 솔직히 정체시기라고 생각합니다. 여기에 짜증난 유저들이 Youtube대거 이동했습니다. Youtube는 무료에 재미있을니까요.

하여간 그래도 게임엔진은 이제 활용도가 시뮬레이션 AR VR XR Metaverse 가상휴먼, 영화. 컨텐츠, 유튜브등 다양한 분야가 펼쳐지면서 유니티나 언리얼의 가능성은 커져가고 있다고 생각합니다. 꼭 유니티로 직업을 삼지 않더라고 한번쯤은 배워볼만한 분야라고 생각합니다. 대신 빡세게 빨리 열심히하시기 바랍니다. 다른것도 해야하니까요. 

 

이번 블로그는 위키북스출판사의 유명한 이재현님의 절대강좌유니티 2021판과 유니티 매뉴얼을 참조해서 정리했습니다. 초보자도 따라할 수 있게 정리했지만 중급자용이라고 생각합니다.

 

https://unity3dstudy.com/

 

IndieGameMaker

 

unity3dstudy.com

 

절대강좌! 유니티: 유니티 전문 개발자가 알려주는 효과적인 게임 제작 기법

유니티 2021 버전과 더불어 한층 더 충실하게 보강된 내용으로 돌아왔습니다! 유니티는 현재 가장 각광받고 있는 게임 개발 엔진이다. 국내외를 막론하고 출시되는 많은 모바일 게임은 물론 게임

wikibook.co.kr

 

용어설명은 유니티 매뉴얼을 참조했다.

https://docs.unity3d.com/kr/2021.3/Manual/UnityManual.html

 

Unity 사용자 매뉴얼 2021.3(LTS) - Unity 매뉴얼

Unity 에디터를 사용하여 2D 및 3D 게임, 앱 및 경험을 만들 수 있습니다. unity3d.com에서 에디터를 다운로드합니다.

docs.unity3d.com

 

+ Recent posts