ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 평면의 방정식을 활용한 마인크래프트 블록 붙이기(Unity 활용)
    Algorithm with C/Math 2020. 11. 30. 17:24

     

    영상을 먼저 보자.

    마인크래프트에서 벽돌을 붙이는 작업을 해봤을 것이다.

    이 벽돌 붙이는 작업을 평면의 방정식을 활용해서 쉽게 구현할 수 있다.

    유니티 엔진에서는 레이 캐스트를 활용해서 충돌한 큐브의 정보를 얻어와서 그 큐브에서 충돌한 표면(평면)으로부터

    법선 벡터를 아주 쉽게 구할 수 있다. 

     

     

    캐릭터는 단순히 큐브로 표현을 한다.

    그리고 캐릭터의 걔층구조는 카메라이다.

    아래는 플레이어의 인스펙터이다.

     

    카메라의 설정은 아래와 같이 default로 설정되어 있다.

     

    그리고 아래와 같이 Cube를 Prefabs한다. 

    이 Cube가 인 게임에서 붙여질 블록이다.

    그리고 인 게임에서 설치해둔 기존의 블록에 Tag를 하나 만들어서 BLOCK이라고 세팅하자.

     

    아래의 스크립트는 플레이어에 붙이면 된다.

    아래의 문장이 핵심이다.

    아래에서 hit.normal이 평면의 법선벡터를 의미한다.

    hit.normal은 크기가 1인 단위벡터화 되어 있다.

    < Player.cs>

    더보기
    using UnityEngine;
    using System.Collections;
    
    public class Player : MonoBehaviour
    {
    	public float MoveSpeed = 3f;
    	public float RotSpeed = 1f;
    	float v;
    	float h;
    
    	void Update()
    	{
    		v = Input.GetAxis("Vertical");
    		h = Input.GetAxis("Horizontal");
    
    		transform.Translate(v * Vector3.forward * MoveSpeed * Time.deltaTime);
    
    		transform.Rotate(Vector3.up * h * RotSpeed);
    
    		//	마우스 우클릭 시
    		if (Input.GetMouseButtonDown(1))
    		{
    			RaycastHit hit;
    
    			Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    
    			//	스크린 화면 중앙에서 직선으로 래이 캐스트로 쏴서 충돌한 물체가 있다면
    			if (Physics.Raycast(ray, out hit, Mathf.Infinity) == true)
    			{
    				//	그 물체의 tag가 BLOCK (타일)라면
    				if (hit.collider.gameObject.tag == "BLOCK")
    				{
    					Vector3 SurfaceVec = hit.normal;		//	충돌한 큐브의 표면(평면)의 법선 벡터를 얻고
    
    					Vector3 hitCubePos = hit.transform.position;    //	충돌한 큐브의 위치를 얻고
    
    					Vector3 InstantiatedCubePos = SurfaceVec + hitCubePos;  //	생성할 큐브의 위치는 법선 벡터와 충돌한 큐브의 위치로 구한다.
    
    					//	그리고 큐브를 생성한다.
    					GameObject Obj =  Instantiate(Resources.Load("Prefabs/Cube"), 
    						InstantiatedCubePos, Quaternion.identity) as GameObject;
    
    					Obj.gameObject.tag = "BLOCK";
    				}
    			}
    		}
    	}
    }

     

     

    CameraMan.cs는 CameraMan에게 붙여준다.

    CameraMan.cs

    더보기
    using UnityEngine;
    using System.Collections;
    
    //	마우스의 위아래쪽만 움직임이 가능하게 만들어주는 스크립트.
    
    public class CameraMan : MonoBehaviour
    {
    	Vector3 Up_And_Down;
    	public float MouseSpeed = 2f;
    
    	void Update()
    	{
    		Up_And_Down.x += Input.GetAxis("Mouse Y") * (-1);
    
    		Up_And_Down.x = Mathf.Clamp(Up_And_Down.x, -45f, 45f);
    
    		transform.localRotation = Quaternion.Euler(new Vector3(Up_And_Down.x, 0f, 0f));
    	}
    }

     

    댓글

Designed by Tistory.