> For the complete documentation index, see [llms.txt](https://docs.maxverse.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maxverse.io/unity/scene-manager.md).

# Scene Manager 설명

## SceneManager에서 필수 구성 요소 얻기&#x20;

아래는 SceneManager의 **필수 구성 요소**를 얻는 코드입니다.&#x20;

{% hint style="success" %}
**필수 구성 요소**

* XRManager
* XRCamera
* XRStudioController
* Trackable
  {% endhint %}

{% code title="MaxstSceneManager.cs" %}

```csharp
ARManager arManagr = FindObjectOfType<ARManager>();
if (arManagr == null)
{
    Debug.LogError("Can't find ARManager. You need to add ARManager prefab in scene.");
    return;
}
else
{
    arCamera = arManagr.gameObject;
}


VPSTrackable[] vPSTrackables = FindObjectsOfType<VPSTrackable>(true);
if (vPSTrackables != null)
{
    vPSTrackablesList.AddRange(vPSTrackables);
}
else
{
    Debug.LogError("You need to add VPSTrackables.");
}

foreach (GameObject eachObject in disableObjects)
{
    if(eachObject != null)
    {
        eachObject.SetActive(false);
    }
}

if (XRStudioController.Instance.ARMode)
{
    AndroidRuntimePermissions.Permission[] result = AndroidRuntimePermissions.RequestPermissions("android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.CAMERA", "android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION");
    if (result[0] == AndroidRuntimePermissions.Permission.Granted && result[1] == AndroidRuntimePermissions.Permission.Granted)
        Debug.Log("We have all the permissions!");
    else
        Debug.Log("Some permission(s) are not granted...");

    cameraBackgroundBehaviour = arManagr.GetCameraBackgroundBehaviour();
    if (cameraBackgroundBehaviour == null)
    {
        Debug.LogError("Can't find CameraBackgroundBehaviour.");
        return;
    }

    foreach (VPSTrackable vPSTrackable in vPSTrackablesList)
    {
        vPSTrackable.gameObject.SetActive(false);
    }
}
else
{
    this.enabled = false;

    if(startPov != null)
    {
        startPov.StartPlace();
    }
}
```

{% endcode %}

{% hint style="info" %}
**XRStudioController**로 위치 인식을 위한 서버 이름을 얻습니다.
{% endhint %}

## Occlusion (건물 메쉬에 의한 가려짐) 구현

렌더링하고자 하는 3D 오브젝트가 건물 메쉬에 의해 가려지는 효과를 Occlusion effect라고 합니다. Occlusion은 runtimeBuildingMaterial를 렌더링시 적용함으로써 구현됩니다.

{% code title="MaxstSceneManager.cs" %}

```bash
foreach (GameObject eachGameObject in occlusionObjects)
{
    Renderer[] cullingRenderer = eachGameObject.GetComponentsInChildren<Renderer>();
    foreach (Renderer eachRenderer in cullingRenderer)
    {
        eachRenderer.material.renderQueue = 1900;
        eachRenderer.material = runtimeBuildingMaterial;
    }
}
```

{% endcode %}

## 카메라 시작 / 시뮬레이션 시작&#x20;

스마트폰과 스마트 글래스와 같은 모바일 기기 환경에서는 아래 코드를 통해 하드웨어 카메라가 시작됩니다. MAC OS X와 Windows 환경에서는 XRStudioController를 통해 선택한 시뮬레이션 데이터가 시작됩니다. 이를 통해 현장에 직접 나가지 않아도 앱 개발이 가능합니다.

{% code title="MaxstSceneManager.cs" %}

```csharp
if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.WindowsEditor)
{
    string simulatePath = vPSStudioController.vpsSimulatePath;
    if (Directory.Exists(simulatePath))
    {
        CameraDevice.GetInstance().Start(simulatePath);
        MaxstAR.SetScreenOrientation((int)ScreenOrientation.Portrait);
    }
}
else
{
    if (CameraDevice.GetInstance().IsFusionSupported(CameraDevice.FusionType.ARCamera))
    {
        CameraDevice.GetInstance().Start();
    }
    else
    {
        TrackerManager.GetInstance().RequestARCoreApk();
    }
}

```

{% endcode %}

## XR Tracker 시작

XR Tracker를 시작해야 AR이 작동하게 됩니다. XRAPI.cs의 SetPlaceIdAndSpotId 함수를 통해서 POI와 Navigation을 얻기 위한 정보를 획득 합니다.

{% code title="MaxstSceneManager.cs" %}

```csharp
TrackerManager.GetInstance().StartTracker();
```

{% endcode %}

## XR 트래킹 결과 얻기&#x20;

트래킹 결과는 UpdateFrame()과 GetARFrame()을 통해서 얻을 수 있습니다. GetARFrame()을 통해 얻은 ARFrame의 인스턴스에는 현재 트래킹 상태, 이미지, 6자유도 자세를 포함되어 있습니다.

ARFrame의 GetARLocationRecognitionState()를 통해서 현재 위치 인식 상태를 얻을 수 있습니다. 이 상태 정보에 맞춰 증강시킬 3D Object의 활성화 여부를 결정합니다.

{% code title="MaxstSceneManager.cs" %}

```csharp
void Update()
{
    UpdateVisibleArrow(arCamera);

    if (!XRStudioController.Instance.ARMode)
    {
        return;
    }

    TrackerManager.GetInstance().UpdateFrame();

    ARFrame arFrame = TrackerManager.GetInstance().GetARFrame();

    TrackedImage trackedImage = arFrame.GetTrackedImage();

    if (trackedImage.IsTextureId())
    {
        IntPtr[] cameraTextureIds = trackedImage.GetTextureIds();
        cameraBackgroundBehaviour.UpdateCameraBackgroundImage(cameraTextureIds);
    }
    else
    {
        cameraBackgroundBehaviour.UpdateCameraBackgroundImage(trackedImage);
    }

    if (arFrame.GetARLocationRecognitionState() == ARLocationRecognitionState.ARLocationRecognitionStateNormal)
    {
        Matrix4x4 targetPose = arFrame.GetTransform();

        arCamera.transform.position = MatrixUtils.PositionFromMatrix(targetPose);
        arCamera.transform.rotation = MatrixUtils.QuaternionFromMatrix(targetPose);
        arCamera.transform.localScale = MatrixUtils.ScaleFromMatrix(targetPose);

        string localizerLocation = arFrame.GetARLocalizerLocation();

        if (currentLocalizerLocation != localizerLocation)
        {
            currentLocalizerLocation = localizerLocation;
            foreach (VPSTrackable eachTrackable in vPSTrackablesList)
            {
                bool isLocationInclude = false;
                foreach (string eachLocation in eachTrackable.localizerLocation)
                {
                    if (currentLocalizerLocation == eachLocation)
                    {
                        isLocationInclude = true;
                        currentLocalizerPlaceId = eachTrackable.placeId;
                        break;
                    }
                }
                eachTrackable.gameObject.SetActive(isLocationInclude);
            }
        }
    }
    else
    {
        foreach (VPSTrackable eachTrackable in vPSTrackablesList)
        {
            eachTrackable.gameObject.SetActive(false);
        }
        currentLocalizerLocation = "";
    }
}
```

{% endcode %}
