프로그래밍-1/Unity3D

Unity3D에서 자주 쓰고 있는 C# 코드 (2) - 충돌 관련 부분 (1)

daslyee 2013. 8. 16. 10:33
728x90

※ 현재 유니티 개발을 하지않습니다. 참고용으로만 참조 부탁드립니다.



게임을 진행하다보면 플레이어와 물체가 부딫쳐야 하는 경우가 발생한다. 필자 같은 경우 크게 4가지를 고려한다.



1. OnCollisionEnter



충돌체 간의 충돌을 감지하여 충돌시 이벤트를 발생시키게끔 할 수 있다. Tag를 입히는 것 외에는 별다른 조건 없이 작동한다.


이해력을 돕기위해서 예시 소스를 준비하였다.



void OnCollisionEnter(Collision other){
		if(other.transform.tag == "cube" || other.transform.tag == "door" ){  //충돌한 tag가 cube 또는 door 라면 JumpB가 참.
			JumpB = true;
		}
		
		if(other.transform.tag == "JumpUp"){
                        /* 1.5와 jump변수값을 곱한 힘의 백터 위의 방향으로 힘을 가함.*/
			rigidbody.velocity = Vector3.up * jump * 1.5f *Time.deltaTime;
		}
}


전 설명에서 bool 변수 JumpB이 참이되는 조건을 생각해보라고 했었다. 다르게 생각할 수도 있지만 필자는 간단한 방식으로 JumpB의 참 조건을 유도해냈다. (물론 간단하다고 다 좋은 것은 아닌 것 같다.)



2.OnTriggerEnter



충돌체 간의 충돌을 감지하여 충돌시 이벤트를 발생시키게끔 할 수 있다. Tag와 Rigidbody 를 입히는 것, 그리고 Collider를 is Trigger 하는 것이 이 명령어의 조건이 된다. 충돌체간의 충돌시 서로를 통과하게끔 해야하기 때문에 투명한 Collider를 이용하여 사용한다.


아래 예시를 보자.



void OnTriggerEnter(Collider other){
		if(other.transform.tag == "Player"){ //충돌한 물체 tag가 Player라면, End 씬으로 씬을 넘긴다. 
			Application.LoadLevel("End");
		}
	}


is Trigger가 체크된 물체에 Player가 접근하면 이루어 지는 명령어이다.



3. Raycast



위에 두개와 더불어 많이 사용한 소스이다. 거리를 판단하고 명령어에 알맞은 수행을 하는 것부터 시작해서 응용분야가 매우 다양하다. 


아래 예시를 보자. 생각보다 복잡하기 때문에 반드시 각자가 사용해서 그 의미를 정확하게 알기를 바란다.



 RaycastHit hit_0; // RaycastHit 선언.
void Update () {
		Vector3 ray_position = transform.position; //현재 위치.
		Vector3 ray_direction_R = transform.TransformDirection(1, 0, 0); //x값이 1, y값이 0,  z값이 0 방향.

			if(Physics.Raycast(ray_position, ray_direction_R, out hit_0, 0.51f)) // 0.5거리가 떨어져있는 위치에 닿는 다면.{

				if(hit_0.collider.tag == "Block_R"){ //Block_R tag라면 -0.75 위치로 이동한다. (접근을 제한한 것.).
					float pos_x = hit_0.collider.transform.position.x -0.75f;
					transform.position = new Vector3(pos_x, 0, transform.position.z);
					transform.Translate (Vector3.right * h * Speed * Time.deltaTime);
				}
			}
}


Raycast는 응용 분야가 (필자가 생각하기에) 다양하기 때문에 국한되어 사용하는 실수를 범해서는 안된다고 생각한다. 


그렇다면 위 소스에서 왜 접근을 제한한 것일 까? 

물체간의 충돌시 Rigidbody 로 충분히 충돌을 감지하여 멈추게(접근을 제한하게) 할 수 있다. 

그렇지만 실제로 유니티 안에서 Rigidbody을 사용할 경우, 부자연스러운 충돌이 연속적으로 발생하는 것을 확인할 수 있을 것이다.



4. AddComponent for Rigidbody



물체에 Rigidbody를 넣지않고 필요할 때만 잠깐 동안 Rigidbody를 물체에 넣어주는 것이다. 게임 실행시 시스템 리소스를 조금이나마 아낄 수 있다.


아래 예시를 보자.



void AddRigidbody(){ //함수가 호출되면 Hierarchy 창 안에 있는 Box_s 안에 있는 box0~ 물체에 Rigidbody를 넣어준다.
GameObject.Find("Box_s/box"+i).AddComponent("Rigidbody");
}


이 것 또한 응용분야가 다양할거라 생각되기 때문에 사용자의 참신한 아이디어를 기대해본다.




728x90