전체 페이지뷰

2017년 11월 1일 수요일

How To Make Mario In Unity 5 by Jimmy Vegas, Part 4

Destroying Blocks



(동영상 5에 해당합니다)

이번 영상에서는 물음표 블럭을 쳤을때 튀어 올라가고 부수는 스크립트를 작성하고 파이프 아래 세상을 만드는 작업을 수행할 것입니다.

Assets>Scripts 폴더를 선택한 후, Create>C# Script를 눌러 BlockNonDestroy라는 이름으로 새로운 C# 스크립트를 하나 생성하고 에디터로 열어봅시다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BlockNonDestroy : MonoBehaviour
{
    private float xPos;
    private float yPos;
    private float zPos;
    
    private void Start()
    {
        xPos = transform.position.x;
        yPos = transform.position.y;
        zPos = transform.position.z;       
    }    
    
    IEnumerator OnTriggerEnter(Collider other)
    {        
        transform.GetComponent<Collider>().isTrigger = false;
        if (other.gameObject.tag == "Player")
        {            
            transform.position = new Vector3(xPos, yPos + 0.2f, zPos);
            yield return new WaitForSeconds(0.08f);                      
            transform.position = new Vector3(xPos, yPos, zPos);
            yield return new WaitForSeconds(0.25f);            
            transform.GetComponent<Collider>().isTrigger = true;              
        }
    }    
}
cs

자바스크립트와는 WaitForSeconds를 사용하는 방법이 달라 좀 수정이 가해졌습니다. 일단  변수들을 private으로 설정하고 Start() 메소드 내에서 연결해 주었기 때문에 인스펙터에는 나오지 않습니다. 그리고 OnTriggerEnter의 반환형을 IEnumerator로 선언하여 yield를 사용할 수 있도록 했습니다. 나머지는 대동소이합니다(쿨한척 뚝딱 해치운 척 했지만 몇시간 걸렸군요 또).

저장 후 유니티로 돌아갑니다.

우선 작성한 스크립트를 아래 그림처럼 첫번째 BrownBlock 오브젝트에 드래그해서 연결하고 BrownBlock의 인스펙터 창에서 Box Collider의 Is Trigger에 체크합니다. 이것들을 나중에 프리팹화해서 사용하게 되는지는 아직 모르겠습니다. 계속해서 따라가 봅니다.


다음으로 ThirdPersonController를 Hierarchy에서 선택하고 Tag를 Player로 지정합니다.


이제 플레이를 눌러 플레이어를 조작해보면,


헤딩 시 벽돌이 슬쩍 위로 올려집니다.

계속해서 진행하기에 앞서 텍스쳐 몇개를 더 가져오겠습니다. 링크에서 다운받아 Assets>Textures 폴더로 드래그해서 옮깁니다.

이제 다른 BrownBlock을 부서져서 없어지는 블럭으로 만들어 보려고 합니다. 이것은 마리오가 커졌을 때 벽돌을 부수는 효과를 표현한 것입니다. Scripts 폴더에 BlockDestroy라는 이름으로 새로운 C# 스크립트를 생성하고 에디터로 엽니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class BlockDestroy : MonoBehaviour
{
    public float waiting = 0.02f;
 
    private float xPos;
    private float yPos;
    private float zPos;
    
    void Start()
    {
        xPos = transform.position.x;
        yPos = transform.position.y;
        zPos = transform.position.z;
    }
 
    IEnumerator OnTriggerEnter(Collider other)
    {        
        if (other.gameObject.tag == "Player")
        {
            transform.position = new Vector3(xPos, yPos + 0.1f, zPos);
            yield return new WaitForSeconds(waiting);
            transform.position = new Vector3(xPos, yPos + 0.2f, zPos);
            yield return new WaitForSeconds(waiting);
            transform.GetComponent<Collider>().isTrigger = false;
            transform.position = new Vector3(xPos, yPos + 0.3f, zPos + 0.5f);
            yield return new WaitForSeconds(waiting);
            transform.position = new Vector3(xPos, yPos + 0.4f, zPos + 1.0f);
            yield return new WaitForSeconds(waiting);
            transform.position = new Vector3(xPos, yPos - 0.1f, zPos + 1.5f);
            yield return new WaitForSeconds(waiting);
            transform.position = new Vector3(xPos, yPos - 0.6f, zPos + 2.0f);
            yield return new WaitForSeconds(waiting);
            transform.position = new Vector3(xPos, yPos - 1.6f, zPos + 2.0f);
            yield return new WaitForSeconds(waiting);
            transform.position = new Vector3(xPos, yPos - 2.6f, zPos + 2.0f);
            yield return new WaitForSeconds(waiting);
            transform.position = new Vector3(xPos, yPos - 4.0f, zPos + 2.0f);
            yield return new WaitForSeconds(0.25f);
            transform.GetComponent<Collider>().isTrigger = true;
            Destroy(gameObject);
        }
    }
}
cs

별것 아닌 효과를 위한 코드가 이렇게 장황해진 것은 블럭이 살짝 튀어올랐다 떨어지면서 사라지는 효과를 주기 위해서입니다. 물론 애니메이션이 설정되어 있다면 이런 하드코딩을 할 이유가 없겠지만 여기서는 기본 에셋을 이용해서 공부하기 위한 것이기에 이렇게 처리한 것 같습니다.

스크립트를 저장하고 유니티로 돌아와서, 스크립트를 BrownBlock(1)에 연결하고 Is Trigger에 체크합니다.



실행해보면 가운데 블럭에 해딩했을 때 튀어올랐다 떨어지며 사라지는 것을확인할 수 있습니다.

다음으로 파이프를 통과해서 내려온 아래층을 만들겠습니다.

GroundSection의 큐브를 복제해서 만들어 보려고 하는데 영상을 보니 처음보다 GroundSection이 한 줄 더 늘어났군요. 전 42개의 큐브였는데 45개가 되어서 Ground(44)까지 생성되어 있습니다. 전과 마찬가지로 끝 세개의 큐브를 한번에 선택해서 Ctrl+D를 눌러 복제하고 Snap으로 이동해서 끝에 붙여서 바닥을 늘려주고 시작합시다.

파이프 아래에 와야 하므로 위치상으로 대략 Ground(34) 정도를 복제하면 편할 듯 싶습니다. 복제하고 Snap으로 Y 포지션이 -6이 될때까지 내립니다.



Ground(45)를 드래그해서 가장 아래로 내립니다(GroundSection의 child가 아니게 합니다). 그리고 이름을 DarkGround (0)으로 바꾸겠습니다.


그리고 Textures 폴더의 DarkGround001을 드래그해서 새로운 텍스쳐를 입힙니다. 하나더 복제해서 뒤에 붙이고,


너무 윗 층과 가까운것 같으니 둘을 동시 선택하고 Y축 -11.5로 이동시킵니다.


 이 두개를 동시 선택하여 복제, 오른쪽으로 붙이기를 반복 10줄을 만듭니다.


그리고 만들어진 것을 통째 복사해서 2층으로 만듭니다.


아래층의 기초가 마련되었습니다. 마치 레고나 마인크래프트를 하는 기분이군요. Jimmy는 거듭 오브젝트가 너무 많다는 걱정은 할 필요 없다고 말하고 있습니다. 그리고 이 게임은 세 개의 섹션으로 이루어지는데 하나의 섹션에 있을 때 다른 곳들은 disable 시킬 수 있다는 점을 말하고 있습니다.

댓글 없음:

댓글 쓰기