내일배움캠프_Unity_6기/TIL_최종프로젝트

TIL : 2024-12-05(목) :: 최종프로젝트 개발 일지(9) - OnTrigger를 사용하면서 Collider에 있는 Contact비슷하게 사용하기

BirdHead 2024. 12. 5. 23:33

Player,Enemy의 콜라이더를 IsTrigger 체크를 하여 사용하니 투사체에 있는 OnCollison 메서드가 동작하지 않았고

Collison의 ContactPoint를 OnTrigger 메서드 내에서 필요했다.

  protected void ProjectileCollison(Collision collision)
  {
      //Lock all axes movement and rotation
      rb.constraints = RigidbodyConstraints.FreezeAll;
      //speed = 0;
      if (lightSourse != null)
          lightSourse.enabled = false;
      col.enabled = false;
      projectilePS.Stop();
      projectilePS.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);

      ContactPoint contact = collision.contacts[0];
      Quaternion rot = Quaternion.FromToRotation(Vector3.up, contact.normal);
      Vector3 pos = contact.point + contact.normal * hitOffset;
   	
    //.....
  }

해당 코드는 OnCollison 메서드 내부의 있는 메서드인데 해당 함수에서 Collison.contacts를 호출해서 접촉한 면의 각도와 방향을 가져와서 투사체가 사라질때 피격 효과를 내고있었다.

 

이 피격효과를 내기 위해서는 충돌하는 객체의 데이터가 필요했다. 

 

그래서 Collider의 Docs에서 찾아보니 ClosestPoint 프로퍼티를 사용하면

 트리거와 충돌하는 물체의 가장 가까운 지점을 계산해주는 기능이 있었다. 

https://docs.unity3d.com/ScriptReference/Collider.ClosestPoint.html

 

Unity - Scripting API: Collider.ClosestPoint

This method computes the point on the Collider that is closest to a 3D location in the world. In the example below closestPoint is the point on the Collider and location is the point in 3D space. If location is in the Collider the closestPoint is inside. I

docs.unity3d.com

 

그래서 해당 프로퍼티를 사용하여 충돌시 동작하는메서드를 변경하여 사용하였다. 

 protected void ProjectileCollison(Collider other)
 {
     //Lock all axes movement and rotation
     rb.constraints = RigidbodyConstraints.FreezeAll;
     //speed = 0;
     if (lightSourse != null)
         lightSourse.enabled = false;
     col.enabled = false;
     projectilePS.Stop();
     projectilePS.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);

     Vector3 closetPoint = other.ClosestPoint(other.transform.position);

     //Spawn hit effect on collision
     if (hit != null)
     {
         //hit.transform.rotation = rot;
         hit.transform.position = closetPoint;
         if (UseFirePointRotation) { hit.transform.rotation = gameObject.transform.rotation * Quaternion.Euler(0, 180f, 0); }
         else if (rotationOffset != Vector3.zero) { hit.transform.rotation = Quaternion.Euler(rotationOffset); }
         //else { hit.transform.LookAt(contact.point + contact.normal); }
         else { hit.transform.LookAt(closetPoint); }
         hitPS.Play();
     }

     //Removing trail from the projectile on cillision enter or smooth removing. Detached elements must have "AutoDestroying script"
     foreach (var detachedPrefab in Detached)
     {
         if (detachedPrefab != null)
         {
             ParticleSystem detachedPS = detachedPrefab.GetComponent<ParticleSystem>();
             detachedPS.Stop();
         }
     }

     if (notDestroy)
         StartCoroutine(DisableTimer(hitPS.main.duration));
     else
     {
         gameObject.SetActive(false);
     }


     ObjectPoolManager.Instance.GetPool("playerProjectile", Utils.POOL_KEY_PLAYERPROJECTILE).GetObject();
 }

 

객체에 접촉하는 면의 데이터를 가져오는게 아니라 법선벡터라던가 각도를 제대로 측정하지는 못하지만

OnTrigger 메서드로 피격 효과의 좌표값 조정이 가능해졌다.