본문 바로가기
프로그래밍/Unity & c#

Unity 3D 터치 이벤트_2

by 리뷰하는 (게임)프로그래머_리프TV 2014. 4. 9.

지난 포스팅에 이어 터치 관련 포스팅.

 

이번엔 화면을 터치하면 cube 를 생성하여, 정해진 위치까지 도착하게( 마치 하늘에서 내가 떨어트리듯이 )하는 것을 목표로 작성을 해보았다.

 

 

먼저 Hierarchy 와 Project를 다음과 같이 세팅해두자.

 

 

 

[ Hierarchy ]

* Dirctional light ( Dirctional light )

* Main Camera ( Main Camera )

* Plane( Plane )

* GameManager ( 빈 게임오브젝트 ) -> CsGameManager가 링크

 

[ Project ]

* CsCube( C# 스크립트 ) -> Cube 프리팹에 링크

* CsGameManager( C# 스크립트 ) -> GameManager에 삽입

* Cube( 프리팹 ) -> Create Cube를 통해 만든 Cube + CsCube

* Cube_Color( 큐브 매터리얼 ) -> 없어도 무관

* Plane_Color( 바닥 매터리얼 ) -> 없어도 무관

* Touch( Game Scene )

 

 

*기본적인 유니티의 프리팹 , C# 스크립트, 매터리얼 설정은 알고 있다는것을 전제로 작성되었습니다.

(그렇지 않으면 내용이 너무 길어져서)

 

이전 포스팅에서 사용했던 코드를 조금만 응용해서 추가로 작성해 보았습니다.

먼저 CSGameManager의 코드입니다.

 

 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;	// List 사용하기 위한 using 선언

public class CsGameManager : MonoBehaviour 
{
	public GameObject cube;

	private GameObject obj;
	private List< GameObject > cubeList = new List< GameObject >();

	Vector3 rayDir;

	// Update is called once per frame
	void Update () 
	{
		// 현재 터치되어 있는 카운트 가져오기
		int cnt = Input.touchCount;

		// 동시에 여러곳을 터치 할 수 있기 때문.
		for( int i=0; i<cnt; ++i )
		{
			// i 번째로 터치된 값 이라고 보면 된다. 
			Touch touch = Input.GetTouch(i);
			Vector2 pos = touch.position;

			// 조금 더 디테일하게!
			if( touch.phase == TouchPhase.Began )
			{
				Debug.Log( "터치 되었습니다." );
			}
			else if( touch.phase == TouchPhase.Ended )
			{
				Debug.Log( "터치가 종료 되었습니다. 프리팹을 생성 + 리스트에 삽입" );
				// 스크린 좌표로 ray를 가져와서
				Ray ray = Camera.main.ScreenPointToRay( pos );

				// 그 방향을 파악
				rayDir = ray.direction;

				// 터치 위치에 큐브를 생성
				Vector3 p = Camera.main.ScreenToWorldPoint( new Vector3( pos.x, pos.y, Camera.main.nearClipPlane ));
				// cube는 프리팹
				obj = (GameObject)Instantiate( cube, p, cube.transform.rotation );

				CsCube cubeScript = obj.GetComponent<CsCube>();

				Debug.Log( "Ray : " + rayDir );
				cubeScript.SetDir( rayDir );

				cubeList.Add( obj );

			}
			else if( touch.phase == TouchPhase.Moved )
			{
//				Debug.Log( "터치 후 이동 중입니다." );
			}
		}
	}
}​

 

 

코드로 내용을 보시면 알겠지만, 전에 터치로 좌표를 파악했던 코드에서 크게 변하지 않았습니다.

 

일단, List< GameObject > cubeList 가 추가되어 GameObject를 여러개 담아두기 위한 무언가가 추가가 되었군요.

 

* using System.Collections.Generic; 을 해주어야 LIST가 사용가능 하다는 점을 참고하세요.

 

그외 추가된것이라면 프리팹을 사용하여

해당 위치에 Cube를 생성,

Ray의 방향( Direction )을 가져 와서 그 위치를 SetDir 이라는 함수의 인자로 넣어줬을 뿐이죠.

 

내용 자체는 크게 많지 않지만,

 

터치 후 Ray를 지정, GetComponent를 사용하여 생성된 GameObject의 Function에 인자를 전달 하는 기능까지 한번에 활용해 보았습니다.

 

사실 이것만 가지고는 잘 모르 실 수 있으니 CsCube의 내용을 바로 보도록 하겠습니다.

 

 

using UnityEngine;
using System.Collections;

public class CsCube : MonoBehaviour {

	float fSpeed;		// 기본 큐브 이동 속도
	bool bMove;			// 내가 이동을 해야 하나 말아야 하나?
	Vector3 MoveDir;	// 어느 방향으로 이동해야 하나?

	public void SetDir( Vector3 vecDir )
	{
		Debug.Log( "Dir : " + vecDir );
		MoveDir = vecDir;
	}

	// Use this for initialization
	void Start () 
	{
		fSpeed = 15.0f;
		bMove = true;
	}
	
	// Update is called once per frame
	void Update () 
	{
		// 내가 아직 이동해야 한다면 
		if( bMove )
			this.transform.Translate( MoveDir * Time.smoothDeltaTime * fSpeed );

		// 바닥에 닿지 않고 나락으로 떨어지다.
		if( this.transform.position.y < 0.0f ) 
			Destroy( this.gameObject );	// 삭제. 
	}

	// 만약 어딘가에 부딪 혔다면 
	void OnCollisionEnter( Collision coll )
	{
		// 이제 그만 이동하라
		bMove = false;
	}
}​

 

 

보시는것과 같이 CsCube 또한 대단한 내용은 없습니다.

 

단지 public SetDir 이라는 Function을 통해 어디선가 Vector3의 인자값을 받고 있다는것,

 

OnCollisionEnter가 발생 시, bMove값을 false로 변경해 주는 정도겠네요.

나머지는 Update에서 해당 방향으로 이동시키는 일 뿐이고.

 

그럼 이제 실제로 플레이를 해보면 다음과 같이 진행됩니다.

 

* 동영상을 찍을까 했지만, 그냥 스크린샷으로 대체 합니다.