본문 바로가기

LiDAR

Unity AR iOS LiDAR 활용

728x90

이번에는 여러 위치의 LiDAR 거리 값을 가져오고 거리가 특정값보다 가까울 경우 해당 위치를 빨간색으로 나타내는 방법에 대한 글입니다.


이전의 경우 화면 가운데 위치의 LiDAR값만 가져왔었습니다. 그러나 가운데 위치뿐만 아니라 좀 더 넓은 범위의 정보를 가져올 필요가 있었습니다.

 

초기 구성은 다음과 같습니다 

 

사진의 파란 위치가 LiDAR 포인트를 가져올 위치입니다.

총 11개 point의 위치를 가져와야 하는데 이전처럼 하나하나 위치를 지정해서 코드를 짜는 것은 매우 비효율적이라 판단했습니다. 그래서 

 

위와 같이 가운데를 기준으로 가로X축, 세로Y축으로 설정하고 for문을 작성하기로 했습니다.

여러 위치에 대해 한번에 변수를 선언하기 위해 List형태인

/위치를 가질 변수 
    public List<Vector2> posVec = new List<Vector2>();

변수를 선언하고, 해당 변수에 값은 

//화면에 표기할 obj 위치 지정
        // i는 point 갯수 지정 
        for (int i = 0; i < 11; i++)
        {
            // z는 point의 높이 설정
            for (float z = 0.5f; z > 0.2; z = z - 0.1f)
            {
                if (z == 0.5f)
                {
                    //j는 x축 위치 설정 
                    for (float j = 0.1f; j < 1; j = j + 0.2f)
                    {
                        // 화면 넓이를 이용하여 point 위치를 지정 
                        posVec[i] = new Vector2(Screen.width * j, Screen.height * z);
                        i++;
                    }

                }

                else if (z == 0.4f)
                {

                    for (float j = 0.2f; j < 1; j = j + 0.2f)
                    {
                        posVec[i] = new Vector2(Screen.width * j, Screen.height * z);
                        i++;
                    }
                }
                else if (z == 0.3f)
                {
                    for (float j = 0.3f; j < 1; j = j + 0.4f)
                    {
                        posVec[i] = new Vector2(Screen.width * j, Screen.height * z);
                        i++;
                    }
                }

            }
        }

 

다음과 같이 11개의  포인트 위치를 for문으로 작성하였습니다.

 

각 point에 표시될 모양 또한 List 형태로 작성하였으며 코드는 아래와 같습니다.

// 화면의 LiDAR 사용 위치에 표시될 object
    public List<Transform> obj = new List<Transform>();

아래는 화면에 표시될 obj를 가지는 Pivot이며, 11개를 사진과 같이 구성하였습니다.

 

해당 방법은 순순스튜디오님의 강의에서 확인할 수 있습니다.

 

이제 각 point의 거리 값을 가져와야 하는데,
이전 처럼

void Update()
    {
        if (m_RaycastManager.Raycast(_centerVec, s_Hits))
        {
            Quaternion tRot = Quaternion.Euler(90f, 0, 0);
            // s_Hits의 위치를 저장 
            var hitPose = s_Hits[0].pose;
            // s_Hits의 거리를 저장
            float hitDis = s_Hits[0].distance;
            // 가져온 거리를 화면에 표시 
            c_resouceText.text = hitDis.ToString("#.##") + "m";

            _pivot.localScale = new Vector3(hitDis, hitDis, hitDis);
            _pivot.position = Vector3.Lerp(_pivot.position, hitPose.position, 0.2f);
            //디버깅을 위해 rotation값을 Quaternion.Lerp에 넣어 자연스럽게 회전하게 만듦 
            _pivot.rotation = Quaternion.Lerp(_pivot.rotation, hitPose.rotation, 0.2f);

            //s_Hits의 값 초기화
            s_Hits.Clear();
        }
    }
}

이렇게 일일이 작성하기에는 너무 번거로운 일이기 때문에

// LiDAR의 정보를 저장할 list
    static List<List<ARRaycastHit>> Hits = new List<List<ARRaycastHit>>();

이중 List를 이용하였습니다.

 

11개의 List를 사용하기 위해 Start 부분에 

 for (int k = 0; k < 11; k++)
        {
            List<ARRaycastHit> A = new List<ARRaycastHit>();
            Hits.Add(A);
        }

for문을 이용하여 내용을 추가했습니다.

 

LiDAR 거리값을 가져오는 방식은 이전과 같으나 

if (RaycastManager.Raycast(posVec[i], Hits[i]))
            {

                Quaternion tRot = Quaternion.Euler(90f, 0, 0);

                // s_Hits의 위치를 저장 
                var hitPose_1 = Hits[i];
                var hitPose = hitPose_1[0].pose;
                // s_Hits의 거리를 저장
                var hitDis_1 = Hits[i];
                float hitDis = hitDis_1[0].distance;

                //Debug.Log(i+"의 거리" + hitDis);
               

                obj[i].localScale = new Vector3(hitDis, hitDis, hitDis);
                obj[i].position = Vector3.Lerp(obj[i].position, hitPose.position, 0.2f);

                //디버깅을 위해 rotation값을 Quaternion.Lerp에 넣어 자연스럽게 회전하게 만듦
                obj[i].rotation = Quaternion.Lerp(obj[i].rotation, hitPose.rotation, 0.2f);
                // 거리가 1.3m보다 짧을 경우 원을 빨간색으로 변경 
                if (hitDis < 1.3f)
                {
                    color[i].material.color = Color.red;
                }
                else
                {
                    color[i].material.color = Color.white;
                }
            }


            else
            {
                Quaternion tRot = Quaternion.Euler(90f, 0, 0);
                obj[i].localScale = new Vector3(0.5f, 0.5f, 0.5f);
                obj[i].rotation = Quaternion.Lerp(obj[i].rotation, tRot, 0.5f);
                obj[i].localPosition = Vector3.Lerp(obj[i].localPosition, Vector3.zero, 0.5f);

            }

 

위와 같이 이중 List에서 값을 가져오는 형식으로 변경하였으며, 거리에 따라 표시되는 원의 색이 변하게 만들었습니다.

 

색에 대한 변수는 

public List<Renderer> color = new List<Renderer>();

를 이용하여 Render 정보를 가져와 내부의 색을 변경해주는 방식으로 작성했습니다!!

 

실행 결과

사진과 같이 제대로 작동하는 것을 확인할 수 있었습니다~!!! (영상으로 보고싶으신 분은 여기를 눌러주세요)

 

 

To Be Continued...

'LiDAR' 카테고리의 다른 글

Flutter + Unity AR  (0) 2024.02.27
Unity iOS notification  (0) 2024.02.27
Unity AR 메모리 누수 현상 잡기  (0) 2024.02.25
Unity AR 딥러닝 사용하기  (2) 2024.02.25
Unity AR camera with iOS LiDAR  (0) 2024.02.24