# 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.maxverse.io/unity/scene-manager.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
