본문 바로가기
개발/Unity

유니티 - OverlapSphere로 주변 콜라이더 탐색하기 (Check Collisions using OverlapSphere)

by 피로물든딸기 2022. 7. 21.
반응형

Unity 전체 링크

 

OverlapSphere를 이용하여 주변 콜라이더를 감지할 수 있다.

 

먼저 콜라이더를 감지할 오브젝트는 따로 색깔을 구분해두자.

아래의 보라색 Sphere에 OverlapSphereTest.cs를 추가한다.

그리고 Cube, Capsule, Sphere를 주변에 배치하자.

 

Cube, Capsule, Sphere는 미리 Layer를 추가해서 설정해두자.

아래는 Layer를 추가한 스크린샷이다.

 

Cube는 아래의 그림과 같이 Layer = Cube로 변경해두었다.

나머지도 마찬가지로 변경해두자.


OverlapSphereTest.cs를 검출의 중심이 되는 오브젝트에 추가하자.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OverlapSphereTest : MonoBehaviour
{
    public float radius = 0.1f;
    public Material detectedMat;

    void changeMaterial(GameObject go, Material changeMat)
    {
        Renderer rd = go.GetComponent<MeshRenderer>();
        Material[] mat = rd.sharedMaterials;
        mat[0] = changeMat;
        rd.materials = mat;
    }
    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawSphere(this.transform.position, radius);
    }

    void Update()
    {
        Collider[] colliders =
                    Physics.OverlapSphere(this.transform.position, radius);

        foreach (Collider col in colliders)
        {
            if (col.name == "Sphere" /* 자기 자신은 제외 */) continue;

            changeMaterial(col.gameObject, detectedMat);
        }
    }
}

 

OverlapSphere는 설정한 반지름(radius)을 기준으로 구(Sphere) 내에 있는 콜라이더를 검출한다.

그리고 검출된 콜라이더를 확인하기 위해 Material을 교체하도록 detectedMat을 선언하자.

 

    public float radius = 0.1f;
    public Material detectedMat;

 

OnDrawGizmosSelected는 OnDrawGizmos와 달리 개체를 선택한 경우만 Gizmos를 그린다.

    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawSphere(this.transform.position, radius);
    }

 

 

아래와 같이 보라색 Sphere가 선택된 경우만 Color.green인 Sphere를 그리는 것을 알 수 있다.

 

아래는 GameObject의 Material을 교체하는 코드다.

    void changeMaterial(GameObject go, Material changeMat)
    {
        Renderer rd = go.GetComponent<MeshRenderer>();
        Material[] mat = rd.sharedMaterials;
        mat[0] = changeMat;
        rd.materials = mat;
    }

 

public으로 선언된 radius를 변경하면서 검출을 확인하기 위해 Update에 OverlapSphere 코드를 넣었다.

매번 검출하는 것은 성능에 영향을 미치기 때문에 실제로는 이벤트나 충돌이 발생할 경우에 사용한다.

 

그리고 자기 자신도 검출이 되기 때문에 예외 처리가 필요하다면 예외 처리를 해야 한다.

    void Update()
    {
        Collider[] colliders =
                    Physics.OverlapSphere(this.transform.position, radius);

        foreach (Collider col in colliders)
        {
            if (col.name == "Sphere" /* 자기 자신은 제외 */) continue;

            changeMaterial(col.gameObject, detectedMat);
        }
    }

 

radius를 적당히 설정해두고, DetectedMat은 원하는 Material로 설정해두자.

 

Radius가 커질수록 멀리 있는 오브젝트가 DetectedMat(Red)로 변경되는 것을 알 수 있다.


이번에는 콜라이더가 있는 물체 중 큐브만 검출해보자.

 

LayerMask를 이용하면 설정된 Layer만 검출할 수 있다.

처음 테스트 환경을 만들 때 큐브에는 미리 "Cube" 레이어를 설정해두었다.

NameToLayer를 이용하여 cubeLayer 변수에 레이어를 받아올 수 있다.

    LayerMask cubeLayer;

    void Start()
    {
        cubeLayer = LayerMask.NameToLayer("Cube");
    }
    
    void Update()
    {
        int layerMask = (1 << cubeLayer);

        Collider[] colliders =
                    Physics.OverlapSphere(this.transform.position, radius, layerMask);

        foreach (Collider col in colliders)
        {
            if (col.name == "Sphere" /* 자기 자신은 제외 */) continue;

            changeMaterial(col.gameObject, detectedMat);
        }
    }

 

OverlapSphere에 layerMask를 추가하면 해당 layer만 검출한다.

layerMask는 레이어를 비트로 판단하기 때문에 (1 << cubeLayer)와 같이 설정해야 한다.

 

반대로 특정 레이어를 제외할 수도 있다. 

특정 비트를 제외하기 위해 " ~ " 비트 연산을 사용하면 된다.

int layerMask = ~(1 << cubeLayer);

 

이제 큐브만 제외하고 콜라이더들이 검출된 것을 볼 수 있다.

 

최종 코드는 다음과 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OverlapSphereTest : MonoBehaviour
{
    public float radius = 0.1f;
    public Material detectedMat;
    LayerMask cubeLayer;

    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawSphere(this.transform.position, radius);
    }

    void changeMaterial(GameObject go, Material changeMat)
    {
        Renderer rd = go.GetComponent<MeshRenderer>();
        Material[] mat = rd.sharedMaterials;
        mat[0] = changeMat;
        rd.materials = mat;
    }

    void Start()
    {
        cubeLayer = LayerMask.NameToLayer("Cube");
    }

    void Update()
    {
        int layerMask = ~(1 << cubeLayer);

        Collider[] colliders =
                    Physics.OverlapSphere(this.transform.position, radius, layerMask);

        foreach (Collider col in colliders)
        {
            if (col.name == "Sphere" /* 자기 자신은 제외 */) continue;

            changeMaterial(col.gameObject, detectedMat);
        }
    }
}

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글