Unity 2022.3.5f1 Google VR Cardboard - 02

VR/Google Cardboard VR (GVR) 2023. 9. 15. 13:36
반응형

https://github.com/googlevr/gvr-unity-sdk/releases

 

Releases · googlevr/gvr-unity-sdk

Google VR SDK for Unity. Contribute to googlevr/gvr-unity-sdk development by creating an account on GitHub.

github.com

2019이후 더이상 업데이트 안한다는 말인듯

Cardboard SDKs for ios, Android NDK, Unity XR Plugin을 사용해라 라는 말인듯 

 

 

다운로드 받고 설치

 

해당 부분을 제거하거나 주석 처리 (daydream관련)

//-----------------------------------------------------------------------
// <copyright file="EditorHeadsetProvider.cs" company="Google Inc.">
// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
//-----------------------------------------------------------------------

/// @cond
namespace Gvr.Internal
{
    using Gvr;
    using System.Collections.Generic;
#if UNITY_EDITOR
    using UnityEditor;
#endif // UNITY_EDITOR
    using UnityEngine;

    public class EditorHeadsetProvider : IHeadsetProvider
    {
        public const float DEFAULT_FLOOR_HEIGHT_3DOF = -1.6f;
        public static readonly Vector3 DEFAULT_RECENTER_TRANSFORM_POSITION = Vector3.zero;
        public static readonly Quaternion DEFAULT_RECENTER_TRANSFORM_ROTATION
                = Quaternion.identity;
        public const GvrSafetyRegionType DEFAULT_SAFETY_REGION_TYPE_3DOF
                = GvrSafetyRegionType.Cylinder;
        public const float DEFAULT_SAFETY_CYLINDER_ENTER_RADIUS_3DOF = 0.6f;
        public const float DEFAULT_SAFETY_CYLINDER_EXIT_RADIUS_3DOF = 0.7f;

        private HeadsetState dummyState;
#if UNITY_EDITOR
        private HashSet<string> printedErrorMessages = new HashSet<string>();
#endif // UNITY_EDITOR

        public bool SupportsPositionalTracking
        {
            get
            {
                return true;
            }
        }

        public void PollEventState(ref HeadsetState state)
        {
#if UNITY_ANDROID && UNITY_EDITOR
            if (InstantPreview.IsActive)
            {
                if (InstantPreview.Instance.events.Count > 0)
                {
                    InstantPreview.UnityGvrEvent eventState
                        = InstantPreview.Instance.events.Dequeue();
                    switch (eventState.type)
                    {
                        case InstantPreview.GvrEventType.GVR_EVENT_NONE:
                            state.eventType = GvrEventType.Invalid;
                            break;
                        case InstantPreview.GvrEventType.GVR_EVENT_RECENTER:
                            state.eventType = GvrEventType.Recenter;
                            break;
                        case InstantPreview.GvrEventType.GVR_EVENT_SAFETY_REGION_EXIT:
                            state.eventType = GvrEventType.SafetyRegionExit;
                            break;
                        case InstantPreview.GvrEventType.GVR_EVENT_SAFETY_REGION_ENTER:
                            state.eventType = GvrEventType.SafetyRegionEnter;
                            break;
                        case InstantPreview.GvrEventType.GVR_EVENT_HEAD_TRACKING_RESUMED:
                            // Currently not supported.
                            state.eventType = GvrEventType.Invalid;
                            break;
                        case InstantPreview.GvrEventType.GVR_EVENT_HEAD_TRACKING_PAUSED:
                            // Currently not supported.
                            state.eventType = GvrEventType.Invalid;
                            break;
                    }

                    state.eventFlags = (int)eventState.flags;
                    state.eventTimestampNs = eventState.timestamp;

                    // Only add recenter-specific fields if this is a recenter event.
                    if (eventState.type == InstantPreview.GvrEventType.GVR_EVENT_RECENTER)
                    {
                        switch (eventState.gvr_recenter_event_data.recenter_type)
                        {
                            case InstantPreview.GvrRecenterEventType.GVR_RECENTER_EVENT_NONE:
                                state.recenterEventType = GvrRecenterEventType.Invalid;
                                break;
                            case InstantPreview.GvrRecenterEventType.GVR_RECENTER_EVENT_RESTART:
                                state.recenterEventType = GvrRecenterEventType.RecenterEventRestart;
                                break;
                            case InstantPreview.GvrRecenterEventType.GVR_RECENTER_EVENT_ALIGNED:
                                state.recenterEventType = GvrRecenterEventType.RecenterEventAligned;
                                break;
                            case InstantPreview.GvrRecenterEventType.GVR_RECENTER_EVENT_DON:
                                // Currently not supported.
                                state.recenterEventType = GvrRecenterEventType.Invalid;
                                break;
                        }

                        state.recenterEventFlags
                            = eventState.gvr_recenter_event_data.recenter_event_flags;
                        GvrMathHelpers.GvrMatrixToUnitySpace(
                            eventState.gvr_recenter_event_data
                                .start_space_from_tracking_space_transform,
                            out state.recenteredPosition,
                            out state.recenteredRotation);
                    }
                }
                else
                {
                    state.eventType = GvrEventType.Invalid;
                }
            }

            return;
#endif // UNITY_ANDROID && UNITY_EDITOR
            // Events are unavailable through emulation.
        }

        public bool TryGetFloorHeight(ref float floorHeight)
        {
#if UNITY_ANDROID && UNITY_EDITOR
            if (InstantPreview.IsActive)
            {
                if (InstantPreview.Instance.floorHeight.isValid)
                {
                    floorHeight = InstantPreview.Instance.floorHeight.value;
                }

                return InstantPreview.Instance.floorHeight.isValid;
            }
#endif // UNITY_ANDROID && UNITY_EDITOR
            floorHeight = DEFAULT_FLOOR_HEIGHT_3DOF;
            return true;
        }

        public bool TryGetRecenterTransform(ref Vector3 position, ref Quaternion rotation)
        {
#if UNITY_ANDROID && UNITY_EDITOR
            if (InstantPreview.IsActive)
            {
                if (InstantPreview.Instance.recenterTransform.isValid)
                {
                    GvrMathHelpers.GvrMatrixToUnitySpace(
                        InstantPreview.Instance.recenterTransform.value,
                        out position,
                        out rotation);
                }

                return InstantPreview.Instance.recenterTransform.isValid;
            }
#endif // UNITY_ANDROID && UNITY_EDITOR
            position = DEFAULT_RECENTER_TRANSFORM_POSITION;
            rotation = DEFAULT_RECENTER_TRANSFORM_ROTATION;
            return true;
        }

        public bool TryGetSafetyRegionType(ref GvrSafetyRegionType safetyType)
        {
#if UNITY_ANDROID && UNITY_EDITOR
            if (InstantPreview.IsActive)
            {
                if (InstantPreview.Instance.safetyRegionType.isValid)
                {
                    safetyType
                        = (GvrSafetyRegionType)InstantPreview.Instance.safetyRegionType.value;
                }

                return InstantPreview.Instance.safetyRegionType.isValid;
            }
#endif // UNITY_ANDROID && UNITY_EDITOR
            safetyType = DEFAULT_SAFETY_REGION_TYPE_3DOF;
            return true;
        }

        public bool TryGetSafetyCylinderInnerRadius(ref float innerRadius)
        {
#if UNITY_ANDROID && UNITY_EDITOR
            if (InstantPreview.IsActive)
            {
                if (InstantPreview.Instance.safetyCylinderEnterRadius.isValid)
                {
                    innerRadius = InstantPreview.Instance.safetyCylinderEnterRadius.value;
                }

                return InstantPreview.Instance.safetyCylinderEnterRadius.isValid;
            }
#endif // UNITY_ANDROID && UNITY_EDITOR
            innerRadius = DEFAULT_SAFETY_CYLINDER_ENTER_RADIUS_3DOF;
            return true;
        }

        public bool TryGetSafetyCylinderOuterRadius(ref float outerRadius)
        {
#if UNITY_ANDROID && UNITY_EDITOR
            if (InstantPreview.IsActive)
            {
                if (InstantPreview.Instance.safetyCylinderExitRadius.isValid)
                {
                    outerRadius = InstantPreview.Instance.safetyCylinderExitRadius.value;
                }

                return InstantPreview.Instance.safetyCylinderExitRadius.isValid;
            }
#endif // UNITY_ANDROID && UNITY_EDITOR
            outerRadius = DEFAULT_SAFETY_CYLINDER_EXIT_RADIUS_3DOF;
            return true;
        }
    }
}

/// @endcond

 

 

 

 


에러가 나는 PermissionsDemoBuildProcessor 클래스도 해당 부분 제거 또는 주석 

 

//-----------------------------------------------------------------------
// <copyright file="PermissionsDemoBuildProcessor.cs" company="Google Inc.">
// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
//-----------------------------------------------------------------------

// Only invoke custom build processor when building for Android.
#if UNITY_ANDROID
namespace GoogleVR.Demos
{
    using System;
    using UnityEditor;
    using UnityEditor.Build;
#if UNITY_2018_1_OR_NEWER
    using UnityEditor.Build.Reporting;
#endif
    using UnityEditorInternal.VR;

#if UNITY_2018_1_OR_NEWER
    internal class PermissionsDemoBuildProcessor
        : IPreprocessBuildWithReport, IPostprocessBuildWithReport
#else
    internal class PermissionsDemoBuildProcessor : IPreprocessBuild, IPostprocessBuild
#endif
    {
        private const string SCENE_NAME_PERMISSIONS_DEMO = "PermissionsDemo";

        private bool cardboardAddedFromCode = false;

        public int callbackOrder
        {
            get { return 0; }
        }

#if UNITY_2018_1_OR_NEWER
        public void OnPreprocessBuild(BuildReport report)
        {
            OnPreprocessBuild(report.summary.platform, report.summary.outputPath);
        }
#endif

        /// <summary>A build preprocess operation for this module.</summary>
        /// <remarks><para>
        /// OnPreprocessBuild() is called right before the build process begins. If it detects that
        /// the first enabled scene in the build arrays is the PermissionsDemo, and Daydream is in
        /// the VR SDKs, it will add Cardboard to the VR SDKs. This is done because the
        /// PermissionsDemo needs a perm statement in the Manifest.  Other demos do not need this.
        /// </para><para>
        /// Adding Cardboard to VR SDKs will merge in the Manifest-Cardboard which has perm
        /// statement in it.
        /// </para></remarks>
        /// <param name="target">The BuildTarget to build.</param>
        /// <param name="path">The path to the BuildTarget.</param>
        public void OnPreprocessBuild(BuildTarget target, string path)
        {
            
        }

#if UNITY_2018_1_OR_NEWER
        /// @cond
        /// <summary>A build postprocess operation for this module.</summary>
        /// <param name="report">A report of the completed build.</param>
        public void OnPostprocessBuild(BuildReport report)
        {
            OnPostprocessBuild(report.summary.platform, report.summary.outputPath);
        }

        /// @endcond
#endif

        /// @cond
        /// <summary>A build postprocess operation for this module.</summary>
        /// <remarks>
        /// OnPostprocessBuild() is called after the build process. It does appropriate cleanup
        /// so that this script only affects build process for PermissionsDemo, not others.
        /// </remarks>
        /// <param name="target">The BuildTarget to run postprocess operations on.</param>
        /// <param name="path">The path to the BuildTarget.</param>
        public void OnPostprocessBuild(BuildTarget target, string path)
        {
           
        }

        /// @endcond
    }
}
#endif  // UNITY_ANDROID

 

 

에러 없이 패키지 import완료 


새씬을 생성하고 

 

Ground를 만들어 주고 Capsule 오브젝트를 만들고 자식으로

CameraOffset을 만들어 MainCamera를 넣고 다음과 같이 셋팅 한다 

 

 

GvrEditorEmulator를 검색해서 씬에 넣는다 

 

 

 

"Main Camera"의 Near 클리핑 평면이 0.3 미터로 설정되어 있어서 Daydream 컨트롤러의 렌더링이 예상치 못하게 잘릴 수 있다는 경고 메시지입니다. 이러한 경고를 해결하려면 다음 단계를 따르십시오:

Near 클리핑 평면 설정 변경:

Unity에서 "Main Camera"의 Near 클리핑 평면 값을 낮춥니다. Daydream 컨트롤러의 렌더링과 관련하여 0.1 미터 이하의 값으로 설정하는 것이 권장됩니다.
실제 필요에 맞게 조절:

Near 클리핑 평면의 값을 조절할 때 주의하세요. 이 값을 너무 낮게 설정하면 화면 일부가 잘릴 수 있으며, 사용 중인 VR 환경 및 카메라 설정에 따라 조절이 필요합니다.
테스트와 조정:

설정을 변경한 후에는 Daydream 컨트롤러 및 씬의 다른 요소가 올바르게 작동하는지 테스트하세요. 필요한 경우 값을 다시 조정할 수 있습니다.
이 경고는 Daydream 컨트롤러와 함께 VR 환경에서 작업할 때 중요합니다. Near 클리핑 평면을 적절하게 설정하면 VR 시스템이 컨트롤러를 정확하게 렌더링하고 사용자 경험을 향상시킬 수 있습니다.

 

 

DayDream 관련 경고이므로 무시 해도 됨 

 


실행 시 컨트롤 Alt키를 눌러 좌우로 회전이 되는지 확인한다 (Yaw/Pitch)
컨트롤키는 Roll에 해당한다

Main Camera에 Tracked Pose Driver컴포넌트를 부착 한다
빌드 후 기기테스트 한다

 

 


환경설정하기

Environment Model.unitypackage
13.64MB

 

스카이박스 준비 

Skybox.unitypackage
1.91MB

 

 

 


 

라이트맵 적용 

Enviroment의 Static 체크 

Yes를 눌러준다
New를 눌러 라이트 에셋을 만들고
다음과 같이 설정하고 Generate Lighting을 눌러준다

 

https://docs.unity3d.com/Manual/class-LightingSettings.html

 

Unity - Manual: Lighting Settings Asset

Lighting Settings Asset Switch to Scripting A Lighting Settings Asset represents a saved instance of the LightingSettings class, which stores data for the Baked Global IlluminationA group of techniques that model both direct and indirect lighting to provid

docs.unity3d.com


기존에 만들었던 캡슐과 Ground를 제거 하고 빈오브젝트를 만들어 Player라고 이름 짓고 위치를 설정한다 

 

그리고 Character Controller 컴포넌트를 추가 하고 Center의 y 값을 1로 설정 한다 

Character Controller의 Height가 2이므로 1로 설정 하면 바닥이 피봇 좌표에 정확히 일치 하게 된다 

 

플레이어의 자식으로 CameraRig 빈 오브젝트를 생성한다 

하고 위치를 잡아준다 

CameraRig는 카메라의 위치를 설정할 컨테이너 역할을 한다 

그리고 Main Camera를 자식으로 넣는다 

 

GvrEditorEmulator 프리팹이 강제로 Main Camera의 위치를 변경하기 때문에 CameraRig자식에 MainCamera를 넣는것

 

GvrEditorEmulator를 씬에 넣고 실행해본다 

 

Alt + 마우스 왼쪽 클릭 후 드레그 : Yaw + Pitch 기능 

Ctrl + 마우스 왼쪽 클릭 후 드레그 : Roll 기능 

 

 

 

GvrEditorEmulator 프리팹은 유니티에서 헤드 트레킹을 시뮬레이션 할수 있지만 MainCamera를 강제로 (0, 0, 0.08)위치로 이동시 고정 해버린다 

 

유니티 에디터에서 실행해보고 결과를 확인후 디바이스 빌드해서 확인해보자 

반응형
: