Unity용 ARCore SDK는 2021년에 지원 중단되었으며 더 이상 지원되지 않습니다. 또한 Unity용 ARCore SDK는 Unity 2020 이상에서 사용할 수 없습니다. 새 프로젝트를 시작하는 개발자는 대신 AR Foundation용 ARCore 확장 프로그램을 사용해야 합니다. 이 SDK는 AR Foundation으로 이전할 수 없는 기존 프로젝트에서 작업하는 개발자만 사용해야 합니다.

HelloAR 샘플 앱 코드 살펴보기

Unity용 ARCore SDK 샘플 앱 코드를 살펴보고 AR 장면에서 SDK 구성요소가 작동하는 방식을 알아보세요.

기본 요건

이 가이드에서는 Unity용 ARCore SDK를 다운로드하고 설치했다고 가정합니다. SDK를 처음 사용하는 경우 먼저 Unity용 ARCore SDK 빠른 시작 가이드를 참고하세요.

샘플 앱 둘러보기

HelloAR 샘플 장면에서 SDK 구성요소를 살펴보세요.

  1. Unity 프로젝트 창에서 Assets(애셋) > GoogleARCore > Example > HelloAR > scenes > HelloAR로 이동합니다.

  2. HelloAR 장면을 더블클릭하여 엽니다.

  3. Hierarchy 계층 구조를 사용하여 샘플 장면 탐색을 시작합니다. 다음과 같은 ARCore 게임 객체가 있습니다.

    게임 객체 설명
    ARCore 기기 ARCore 세션을 관리하는 Prefab

    1인칭 카메라 게임 객체를 보유합니다. 이 객체는 기기 뒷면의 카메라를 사용하여 실제 이미지를 캡처하고 AR 장면의 배경으로 사용할 수 있도록 합니다.
    주변광 Prefab: 카메라가 캡처하는 이미지의 평균 픽셀 밝기를 추정하여 AR 장면의 밝기를 조정합니다. 이렇게 하려면 각 프레임에서 다음을 수행합니다.
    • EnvironmentalLight 컨트롤러 스크립트는 캡처된 카메라 이미지의 LightEstimate 픽셀 강도 및 색상 보정 값을 가져옵니다.
    • 그러면 컨트롤러 스크립트는 이러한 값을 사용하여 다음을 수행합니다.
      • 정규화된 픽셀 강도 값을 생성합니다.
      • _GlobalColorCorrection 셰이더 값을 설정합니다.
    • MobileDiffuseWithLightEstimation 셰이더_GlobalColorCorrection 수정자를 사용하여 앤디 Android 객체의 머티리얼의 최종 색상을 조정합니다.

    포인트 클라우드 현재 프레임에서 감지된 특징 지점Prefab입니다.
    HelloAR 컨트롤러 컨트롤러 스크립트가 AR 장면을 관리하는 게임 객체.
    컨트롤러 스크립트에는 1인칭 카메라와 여러 프리패브에 대한 참조가 있습니다.
    PlaneDiscovery 사용자가 주변을 스캔하고 비행기를 발견할 수 있도록 하는 평면 검색 시각 요소를 제공하는 프리패브입니다. 이는 기기를 들고 있는 애니메이션과 기능 지점이 감지되도록 기기를 이동하는 방법을 나타내는 간단한 안내가 포함된 스낵바로 구성됩니다. 이러한 지형지물 지점은 감지될 때 피드백을 제공하는 팝업 효과를 제공합니다. 일정 시간이 지난 후에 평면을 찾을 수 없는 경우 스낵바에 누르면 버튼을 누르면 AR 경험을 개선하는 방법에 관한 자세한 안내가 포함된 버튼이 표시됩니다.

코드 살펴보기

이제 샘플 장면에서 기본 ARCore 게임 객체에 관한 아이디어를 얻었으므로 함께 작동하도록 만드는 코드를 단계별로 진행합니다.

HelloARController 스크립트는 ARCore 샘플 앱 환경의 중요한 측면을 구현합니다.

코드에 액세스

  1. HelloAR 장면에서 HelloAR 컨트롤러 게임 객체를 클릭합니다.

  2. Inspector(검사기) 창에서 HelloARController 스크립트를 더블클릭하여 편집기에서 엽니다.

단계별 코드 실행

코드를 확인합니다. HelloARController 스크립트에서 Update() 메서드는 각 프레임의 중요한 작업을 처리합니다.

모션 추적 확인

  • 모션 추적은 평면 감지를 제공합니다. Update() 메서드는 _UpdateApplicationLifecycle() 메서드를 호출하여 모션 추적을 확인합니다. 다음 코드는 _UpdateApplicationLifecycle()에 있습니다.
  // Check that motion tracking is tracking.
  if (Session.Status != SessionStatus.Tracking)
  {
      Screen.sleepTimeout = SleepTimeout.SystemSetting;
  }
  else
  {
      Screen.sleepTimeout = SleepTimeout.NeverSleep;
  }

실제 환경에서 새 평면 및 기존 평면 감지

  • ARCore는 실제 장면에서 추적할 새 비행기를 찾습니다.

  • 새 평면과 기존 비행기가 아직 감지되지 않는 한 PlaneDiscovery prefab은 시각적 가이드를 표시합니다. 평면이 하나 이상 추적되면 가이드 UI가 숨겨집니다.

가상 객체 배치를 위한 사용자 입력 처리

평면이 추적되면 Update() 메서드는 감지된 영역에 ARCore 폰 객체를 배치하기 위한 사용자 입력을 처리합니다.

  • 사용자가 화면을 탭하면 Frame.Raycast()은 탭 위치에서 레이캐스트를 사용하여 사용자가 비행기를 탭했는지 또는 방향성 포인트를 탭했는지 감지합니다.

  • 사용자가 평면이나 방향 표시된 지점의 영역을 탭하면 사용자가 탭한 TrackableHit 자세에서 ARCore 폰 객체가 인스턴스화됩니다.

  • 이 조회 자세는 앵커를 만드는 데 사용됩니다.

    • 앵커는 AR 게임 객체를 실제 세계와 동일한 위치에 유지합니다.
    • 더 이상 앵커가 필요하지 않으면 Unity의 GameObject Destroy() 메서드를 호출합니다. 이렇게 하면 ARCore에서 앵커 추적을 중지하라는 신호를 보냅니다.
  • 카메라 위치는 ARCore 폰의 변환을 조정하는 데 사용되므로 담보 대사를 기준으로 일관된 방향을 설정합니다.

  • 폰의 변환은 히트 앵커를 상속하므로, 사용자가 휴대전화를 움직일 때 폰 게임 객체가 사용자가 배치한 위치에 머무릅니다.

// Raycast against the location the player touched to search for planes.
TrackableHit hit;
TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
    TrackableHitFlags.FeaturePointWithSurfaceNormal;

if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit))
{
    // Use hit pose and camera pose to check if hittest is from the
    // back of the plane, if it is, no need to create the anchor.
    if ((hit.Trackable is DetectedPlane) &&
        Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position,
            hit.Pose.rotation * Vector3.up) < 0)
    {
        Debug.Log("Hit at back of the current DetectedPlane");
    }
    else
    {
        // Instantiate prefab at the hit pose.
        var gameObject = Instantiate(prefab, hit.Pose.position, hit.Pose.rotation);

        // Compensate for the hitPose rotation facing away from the raycast (i.e.
        // camera).
        gameObject.transform.Rotate(0, _prefabRotation, 0, Space.Self);

        // Create an anchor to allow ARCore to track the hitpoint as understanding of
        // the physical world evolves.
        var anchor = hit.Trackable.CreateAnchor(hit.Pose);

        // Make game object a child of the anchor.
        gameObject.transform.parent = anchor.transform;
    }
}