version 2.5.0
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67f99d00d315f5247a283247f1d1a046
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright HTC Corporation All Rights Reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Android;
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.Spectator.Helper
|
||||
{
|
||||
public static class AndroidProcessHelper
|
||||
{
|
||||
private static AndroidJavaObject _activity;
|
||||
|
||||
public static AndroidJavaObject Activity
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_activity != null)
|
||||
{
|
||||
return _activity;
|
||||
}
|
||||
|
||||
var unityPlayer = new AndroidJavaClass(ANDROID_CLASS_UNITY_PLAYER);
|
||||
_activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
|
||||
|
||||
return _activity;
|
||||
}
|
||||
}
|
||||
|
||||
// Reference: https://stackoverflow.com/q/58728596/10467387
|
||||
public static IEnumerator RequestPermission(Dictionary<string, PermissionCallbacks> permissions)
|
||||
{
|
||||
var permissionGranted = Enumerable.Repeat(false, permissions.Count).ToList();
|
||||
var permissionAsked = Enumerable.Repeat(false, permissions.Count).ToList();
|
||||
var permissionAction = new List<Action>();
|
||||
|
||||
for (var i = 0; i < permissions.Count; i++)
|
||||
{
|
||||
int currentCount = i;
|
||||
(string permission, PermissionCallbacks permissionCallbacks) = permissions.ElementAt(currentCount);
|
||||
permissionAction.Add(() =>
|
||||
{
|
||||
permissionGranted[currentCount] = Permission.HasUserAuthorizedPermission(permission);
|
||||
if (permissionGranted[currentCount] || permissionAsked[currentCount])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Permission.RequestUserPermission(permission, permissionCallbacks);
|
||||
permissionAsked[currentCount] = true;
|
||||
});
|
||||
}
|
||||
|
||||
for (var i = 0; i < permissions.Count;)
|
||||
{
|
||||
permissionAction[i].Invoke();
|
||||
if (permissionAsked[i])
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
yield return new WaitForEndOfFrame();
|
||||
}
|
||||
}
|
||||
|
||||
public const string ANDROID_CLASS_UNITY_PLAYER = "com.unity3d.player.UnityPlayer";
|
||||
public const string ANDROID_CLASS_MEDIA_STORE_IMAGE_MEDIA = "android.provider.MediaStore$Images$Media";
|
||||
public const string ANDROID_CLASS_GRAPHICS_BITMAP_FACTORY = "android.graphics.BitmapFactory";
|
||||
public const string ANDROID_CLASS_GRAPHICS_BITMAP_COMPRESS_FORMAT = "android.graphics.Bitmap$CompressFormat";
|
||||
public const string ANDROID_CLASS_OS_ENVIRONMENT = "android.os.Environment";
|
||||
public const string ANDROID_CLASS_OS_BUILD_VERSION = "android.os.Build$VERSION";
|
||||
public const string ANDROID_CLASS_CONTENT_INTENT = "android.content.Intent";
|
||||
public const string ANDROID_CLASS_CONTENT_VALUES = "android.content.ContentValues";
|
||||
public const string ANDROID_CLASS_NET_URI = "android.net.Uri";
|
||||
public const string JAVA_CLASS_IO_FILE = "java.io.File";
|
||||
public const string JAVA_CLASS_IO_OUTPUTSTREAM = "java.io.OutputStream";
|
||||
public const string JAVA_CLASS_IO_BYTEARRAYOUTPUTSTREAM = "java.io.ByteArrayOutputStream";
|
||||
public const string JAVA_CLASS_IO_BYTEARRAYINPUTSTREAM = "java.io.ByteArrayInputStream";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52cbc1ad9d288d348854b4e81d8aa57c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright HTC Corporation All Rights Reserved.
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.Spectator.Helper
|
||||
{
|
||||
public static class EditorHelper
|
||||
{
|
||||
// Microsoft definition
|
||||
// https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.metadata.conventions.backingfieldconvention?view=efcore-7.0#definition
|
||||
private const string BackingFieldConventionPrefix = "<";
|
||||
private const string BackingFieldConventionEndString = "k__BackingField";
|
||||
|
||||
public static void ShowDefaultInspector(SerializedObject obj)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
obj.UpdateIfRequiredOrScript();
|
||||
|
||||
SerializedProperty iterator = obj.GetIterator();
|
||||
for (bool enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false)
|
||||
{
|
||||
using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath))
|
||||
{
|
||||
string originalLabelText = iterator.name;
|
||||
if (originalLabelText.EndsWith(BackingFieldConventionEndString))
|
||||
{
|
||||
string fixLabelText = Regex.Replace(
|
||||
originalLabelText.Substring(
|
||||
1,
|
||||
originalLabelText.Length - 1 - BackingFieldConventionPrefix.Length -
|
||||
BackingFieldConventionEndString.Length),
|
||||
"([a-z])([A-Z])",
|
||||
"$1 $2");
|
||||
|
||||
EditorGUILayout.PropertyField(
|
||||
property: iterator,
|
||||
label: new GUIContent(fixLabelText),
|
||||
includeChildren: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(iterator, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
obj.ApplyModifiedProperties();
|
||||
EditorGUI.EndChangeCheck();
|
||||
}
|
||||
|
||||
public static string PropertyName(string propertyName)
|
||||
{
|
||||
// Microsoft definition
|
||||
// https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.metadata.conventions.backingfieldconvention?view=efcore-7.0#definition
|
||||
return $"<{propertyName}>k__BackingField";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2fb164a4bcc8f04e9337299f4c030d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,163 @@
|
||||
// Copyright HTC Corporation All Rights Reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.Spectator.Helper
|
||||
{
|
||||
public static class IOProcessHelper
|
||||
{
|
||||
#if UNITY_ANDROID
|
||||
/// <summary>
|
||||
/// Get the path of pictures folder in external storage in Android.
|
||||
/// </summary>
|
||||
/// <returns>Return Pictures folder directory if get successfully, otherwise return empty string</returns>
|
||||
public static string GetAndroidExternalStoragePicturesDirectory()
|
||||
{
|
||||
Debug.Log("GetAndroidExternalStoragePicturesDirectory called");
|
||||
|
||||
string path = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// Init the class in java code
|
||||
using (AndroidJavaClass environment =
|
||||
new AndroidJavaClass(AndroidProcessHelper.ANDROID_CLASS_OS_ENVIRONMENT))
|
||||
{
|
||||
// Call static method to get the path of pictures folder in external storage
|
||||
path = environment.CallStatic<AndroidJavaObject>("getExternalStoragePublicDirectory",
|
||||
environment.GetStatic<string>("DIRECTORY_PICTURES"))
|
||||
.Call<string>("getAbsolutePath");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Error on getting the path of pictures folder in external storage in Android: {e}");
|
||||
}
|
||||
|
||||
Debug.Log($"Get path in GetAndroidExternalStoragePicturesDirectory: {path}");
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public static string GetAndroidPrimaryExternalStorageDirectory()
|
||||
{
|
||||
Debug.Log("GetAndroidPrimaryExternalStorageDirectory called");
|
||||
|
||||
string path = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
using (AndroidJavaClass environment =
|
||||
new AndroidJavaClass(AndroidProcessHelper.ANDROID_CLASS_OS_ENVIRONMENT))
|
||||
{
|
||||
path = environment.CallStatic<AndroidJavaObject>("getExternalStorageDirectory")
|
||||
.Call<string>("getAbsolutePath");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Error on getting the path of pictures folder in external storage in Android: {e}");
|
||||
}
|
||||
|
||||
Debug.Log($"Get path in GetAndroidPrimaryExternalStorageDirectory: {path}");
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public static Dictionary<ExternalStorageType, string> GetAndroidAllExternalStorageDirectory()
|
||||
{
|
||||
Debug.Log("GetAndroidAllExternalStorageDirectory called");
|
||||
|
||||
// Get all available external file directories (emulated or removable (aka sd card))
|
||||
AndroidJavaObject[] externalFilesDirectories =
|
||||
AndroidProcessHelper.Activity.Call<AndroidJavaObject[]>("getExternalFilesDirs", (object)null);
|
||||
|
||||
var result = new Dictionary<ExternalStorageType, string>();
|
||||
using (var environment = new AndroidJavaClass(AndroidProcessHelper.ANDROID_CLASS_OS_ENVIRONMENT))
|
||||
{
|
||||
foreach (var item in externalFilesDirectories)
|
||||
{
|
||||
string directory = item.Call<string>("getAbsolutePath");
|
||||
Debug.Log($"Find the path in GetAndroidExternalStorageDirectory: {directory}");
|
||||
|
||||
if (environment.CallStatic<bool>("isExternalStorageRemovable", item))
|
||||
{
|
||||
result.Add(ExternalStorageType.Removable, directory);
|
||||
}
|
||||
else if (environment.CallStatic<bool>("isExternalStorageEmulated", item))
|
||||
{
|
||||
result.Add(ExternalStorageType.Emulated, directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public enum ExternalStorageType
|
||||
{
|
||||
Removable,
|
||||
Emulated
|
||||
}
|
||||
#endif
|
||||
|
||||
public static Task SaveByteDataToDisk(byte[] bytes, string saveDirectory, string fileNameWithFileExtension)
|
||||
{
|
||||
Directory.CreateDirectory(saveDirectory);
|
||||
|
||||
try
|
||||
{
|
||||
string fullPath = Path.Combine(saveDirectory, fileNameWithFileExtension);
|
||||
System.IO.File.WriteAllBytes(fullPath, bytes);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Error on writing byte data to disk: {e}");
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public static byte[] OpenFile(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
Debug.LogError("File not exist: " + path);
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] data = File.ReadAllBytes(path);
|
||||
if (data.Length == 0)
|
||||
{
|
||||
Debug.LogError("File is empty: " + path);
|
||||
return null;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public static byte[] OpenJpeg(string path)
|
||||
{
|
||||
byte[] data = OpenFile(path);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
Debug.LogError("Open Jpeg error");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (data[0] != 0xFF || data[1] != 0xD8)
|
||||
{
|
||||
Debug.LogError("File is not JPEG: " + path);
|
||||
return null;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d28163e4ec0b605478774041d1222262
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,102 @@
|
||||
// Copyright HTC Corporation All Rights Reserved.
|
||||
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
#endif
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.Spectator.Helper
|
||||
{
|
||||
public static class LayerMaskHelper
|
||||
{
|
||||
public static bool HasLayer(this LayerMask layerMask, int layer)
|
||||
{
|
||||
if (layerMask == (layerMask | (1 << layer)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool[] HasLayers(this LayerMask layerMask)
|
||||
{
|
||||
var hasLayers = new bool[32];
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
if (layerMask == (layerMask | (1 << i)))
|
||||
{
|
||||
Debug.Log($"LayerMask.LayerToName = {LayerMask.LayerToName(i)}");
|
||||
hasLayers[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasLayers;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public static class LayerMaskDrawer
|
||||
{
|
||||
public static int LayerMaskField(string label, int layermask)
|
||||
{
|
||||
return FieldToLayerMask(EditorGUILayout.MaskField(label, LayerMaskToField(layermask),
|
||||
InternalEditorUtility.layers));
|
||||
}
|
||||
|
||||
public static int LayerMaskField(Rect position, string label, int layermask)
|
||||
{
|
||||
return FieldToLayerMask(EditorGUI.MaskField(position, label, LayerMaskToField(layermask),
|
||||
InternalEditorUtility.layers));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts field LayerMask values to in game LayerMask values
|
||||
/// </summary>
|
||||
/// <param name="field"></param>
|
||||
/// <returns></returns>
|
||||
private static int FieldToLayerMask(int field)
|
||||
{
|
||||
if (field == -1) return -1;
|
||||
int mask = 0;
|
||||
var layers = InternalEditorUtility.layers;
|
||||
for (int c = 0; c < layers.Length; c++)
|
||||
{
|
||||
if ((field & (1 << c)) != 0)
|
||||
{
|
||||
mask |= 1 << LayerMask.NameToLayer(layers[c]);
|
||||
}
|
||||
else
|
||||
{
|
||||
mask &= ~(1 << LayerMask.NameToLayer(layers[c]));
|
||||
}
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts in game LayerMask values to field LayerMask values
|
||||
/// </summary>
|
||||
/// <param name="mask"></param>
|
||||
/// <returns></returns>
|
||||
private static int LayerMaskToField(int mask)
|
||||
{
|
||||
if (mask == -1) return -1;
|
||||
int field = 0;
|
||||
var layers = InternalEditorUtility.layers;
|
||||
for (int c = 0; c < layers.Length; c++)
|
||||
{
|
||||
if ((mask & (1 << LayerMask.NameToLayer(layers[c]))) != 0)
|
||||
{
|
||||
field |= 1 << c;
|
||||
}
|
||||
}
|
||||
|
||||
return field;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05c260c7d911cff49b0333f5ba628420
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,516 @@
|
||||
// Copyright HTC Corporation All Rights Reserved.
|
||||
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.Spectator.Helper
|
||||
{
|
||||
public class SpectatorCameraHelper
|
||||
{
|
||||
# region Attribute value range
|
||||
|
||||
public const float VERTICAL_FOV_MIN = 10f;
|
||||
public const float VERTICAL_FOV_MAX = 130f;
|
||||
|
||||
public const float FRUSTUM_LINE_WIDTH_MIN = .02f;
|
||||
public const float FRUSTUM_LINE_WIDTH_MAX = .05f;
|
||||
|
||||
public const float FRUSTUM_CENTER_LINE_WIDTH_MIN = .01f;
|
||||
public const float FRUSTUM_CENTER_LINE_WIDTH_MAX = .04f;
|
||||
|
||||
public const int PANORAMA_RESOLUTION_MIN = 512;
|
||||
public const int PANORAMA_RESOLUTION_MAX = 4096;
|
||||
|
||||
public const int SMOOTH_CAMERA_MOVEMENT_MIN = 8;
|
||||
public const int SMOOTH_CAMERA_MOVEMENT_MAX = 16;
|
||||
|
||||
public const float COMPARE_FLOAT_SUPER_SMALL_THRESHOLD = .001f;
|
||||
public const float COMPARE_FLOAT_EXTRA_SMALL_THRESHOLD = .01f;
|
||||
public const float COMPARE_FLOAT_SMALL_THRESHOLD = .1f;
|
||||
public const float COMPARE_FLOAT_MEDIUM_THRESHOLD = 1f;
|
||||
public const float COMPARE_FLOAT_LARGE_THRESHOLD = 10f;
|
||||
|
||||
public const float INTERVAL_SECOND_GET_SPECTATOR_HANDLER = .5f;
|
||||
public const float MAX_SECOND_GET_SPECTATOR_HANDLER = 5f;
|
||||
|
||||
public const float INTERVAL_SECOND_INTERNAL_SPECTATOR_CAMERA = 1f;
|
||||
public const float MAX_SECOND_GET_INTERNAL_SPECTATOR_CAMERA = 2f;
|
||||
|
||||
# endregion
|
||||
|
||||
public static readonly Vector3 SpectatorCameraSpherePrefabScaleDefault = new Vector3(.08f, .08f, .08f);
|
||||
|
||||
#region Attribute default value definition
|
||||
|
||||
public const int TEXTURE_WIDTH = 1920;
|
||||
public const int TEXTURE_HEIGHT = 1080;
|
||||
|
||||
public const CameraSourceRef CAMERA_SOURCE_REF_DEFAULT = CameraSourceRef.Hmd;
|
||||
public static readonly Vector3 PositionDefault = new Vector3(0f, 1.7f, 0f);
|
||||
public static readonly Quaternion RotationDefault = Quaternion.identity;
|
||||
public static readonly LayerMask LayerMaskDefault = -1;
|
||||
|
||||
public const bool IS_SMOOTH_CAMERA_MOVEMENT_DEFAULT = true;
|
||||
public const int SMOOTH_CAMERA_MOVEMENT_SPEED_DEFAULT = 10;
|
||||
|
||||
public const bool IS_FRUSTUM_SHOWED_DEFAULT = false;
|
||||
|
||||
public const float VERTICAL_FOV_DEFAULT = 60f;
|
||||
|
||||
public const SpectatorCameraPanoramaResolution PANORAMA_RESOLUTION_DEFAULT =
|
||||
SpectatorCameraPanoramaResolution._2048;
|
||||
|
||||
public const TextureProcessHelper.PictureOutputFormat PANORAMA_OUTPUT_FORMAT_DEFAULT =
|
||||
TextureProcessHelper.PictureOutputFormat.PNG;
|
||||
|
||||
public const TextureProcessHelper.PanoramaType PANORAMA_TYPE_DEFAULT =
|
||||
TextureProcessHelper.PanoramaType.Monoscopic;
|
||||
|
||||
public const float STEREO_SEPARATION_DEFAULT = 0.065f;
|
||||
|
||||
public const FrustumLineCount FRUSTUM_LINE_COUNT_DEFAULT =
|
||||
FrustumLineCount.Four;
|
||||
|
||||
public const FrustumCenterLineCount FRUSTUM_CENTER_LINE_COUNT_DEFAULT =
|
||||
FrustumCenterLineCount.Center;
|
||||
|
||||
public const float FRUSTUM_LINE_WIDTH_DEFAULT = .02f;
|
||||
public const float FRUSTUM_CENTER_LINE_WIDTH_DEFAULT = .01f;
|
||||
|
||||
public const float FRUSTUM_LINE_BEGIN_DEFAULT = .3f;
|
||||
|
||||
// Define by Unity: https://docs.unity3d.com/ScriptReference/Camera.CalculateFrustumCorners.html
|
||||
public const int FRUSTUM_OUT_CORNERS_COUNT = 4;
|
||||
|
||||
public static readonly Color LineColorDefault = Color.white;
|
||||
public const string LINE_SHADER_NAME_DEFAULT = "UI/Default";
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public const bool IS_DEBUG_SPECTATOR_CAMERA = true;
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#region Frustum game object name definition
|
||||
|
||||
public const string FRUSTUM_LINE_ROOT_NAME_DEFAULT = "FrustumLines";
|
||||
public const string FRUSTUM_LINE_NAME_PREFIX_DEFAULT = "Frustum";
|
||||
public const string FRUSTUM_CENTER_LINE_ROOT_NAME_DEFAULT = "FrustumCenterLines";
|
||||
public const string FRUSTUM_CENTER_LINE_NAME_PREFIX_DEFAULT = "FrustumCenter";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Save file definition
|
||||
|
||||
public const string SAVE_PHOTO360_ALBUM_NAME = "Screenshots";
|
||||
|
||||
public const string ATTRIBUTE_FILE_PREFIX_NAME = "SpectatorCameraAttribute";
|
||||
|
||||
public const string ATTRIBUTE_FILE_EXTENSION = "json";
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Load the attribute file from resource folder
|
||||
/// </summary>
|
||||
/// <param name="sceneName">The corresponding scene name of the attribute file</param>
|
||||
/// <param name="gameObjectName">The corresponding gameObject name of the attribute file</param>
|
||||
/// <param name="data">The attribute data which save in attribute file</param>
|
||||
/// <returns>True if get the attribute data successfully. Otherwise, return false.</returns>
|
||||
public static bool LoadAttributeFileFromResourcesFolder(
|
||||
in string sceneName,
|
||||
in string gameObjectName,
|
||||
out SpectatorCameraAttribute data)
|
||||
{
|
||||
Debug.Log("Get spectator camera attribute at resources folder");
|
||||
|
||||
data = new SpectatorCameraAttribute();
|
||||
TextAsset json;
|
||||
|
||||
// Name format: {PREFIX}_{SCENE NAME}_{GAME OBJECT NAME}.json
|
||||
var fileName = GetSpectatorCameraAttributeFileNamePattern(sceneName, gameObjectName, false);
|
||||
|
||||
try
|
||||
{
|
||||
json = Resources.Load<TextAsset>(fileName);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogWarning("Get attribute data from resources folder fail:");
|
||||
Debug.LogWarning($"{e}");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (json == null)
|
||||
{
|
||||
Debug.LogWarning("The attribute data at resources folder is empty or null");
|
||||
return false;
|
||||
}
|
||||
|
||||
Debug.Log($"The attribute value is: {json.text}");
|
||||
data = JsonUtility.FromJson<SpectatorCameraAttribute>(json.text);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
Debug.LogWarning("Convert attribute data from resources folder fail");
|
||||
return false;
|
||||
}
|
||||
|
||||
Debug.Log("Get attribute data from resources folder successful");
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load the attribute file from full path
|
||||
/// </summary>
|
||||
/// <param name="fullPathWithFileNameAndExtension">Full path</param>
|
||||
/// <param name="data">The attribute data which save in persistent folder</param>
|
||||
/// <returns>True if get the attribute data successfully. Otherwise, return false.</returns>
|
||||
public static bool LoadAttributeFileFromFolder(
|
||||
string fullPathWithFileNameAndExtension,
|
||||
out SpectatorCameraAttribute data)
|
||||
{
|
||||
Debug.Log($"Get spectator camera attribute at {fullPathWithFileNameAndExtension}");
|
||||
|
||||
return LoadAttributeData(fullPathWithFileNameAndExtension, out data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load the attribute file from persistent folder
|
||||
/// </summary>
|
||||
/// <param name="sceneName">The corresponding scene name of the attribute file</param>
|
||||
/// <param name="gameObjectName">The corresponding gameObject name of the attribute file</param>
|
||||
/// <param name="data">The attribute data which save in persistent folder</param>
|
||||
/// <returns>True if get the attribute data successfully. Otherwise, return false.</returns>
|
||||
public static bool LoadAttributeFileFromPersistentFolder(
|
||||
in string sceneName,
|
||||
in string gameObjectName,
|
||||
out SpectatorCameraAttribute data)
|
||||
{
|
||||
// Name format: {PREFIX}_{SCENE NAME}_{GAME OBJECT NAME}.json
|
||||
var fileNameWithExtension = GetSpectatorCameraAttributeFileNamePattern(sceneName, gameObjectName);
|
||||
|
||||
var attributeFileDirectoryAndFileNameWithExtension =
|
||||
Path.Combine(Application.persistentDataPath, fileNameWithExtension);
|
||||
|
||||
Debug.Log($"Get spectator camera attribute at {attributeFileDirectoryAndFileNameWithExtension}");
|
||||
|
||||
return LoadAttributeData(attributeFileDirectoryAndFileNameWithExtension, out data);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Save the spectator camera attribute as a JSON file to the resources folder located in the Unity project's assets folder.
|
||||
/// </summary>
|
||||
public static void SaveAttributeData2ResourcesFolder(
|
||||
in string sceneName,
|
||||
in string gameObjectName,
|
||||
in SpectatorCameraAttribute data)
|
||||
{
|
||||
// Name format: {PREFIX}_{SCENE NAME}_{GAME OBJECT NAME}.json
|
||||
var fileNameWithExtension = GetSpectatorCameraAttributeFileNamePattern(sceneName, gameObjectName);
|
||||
string resourcesFolderPath = Path.Combine(Application.dataPath, "Resources");
|
||||
SaveAttributeData(resourcesFolderPath, fileNameWithExtension, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Save the spectator camera attribute as a JSON file to a persistent folder.
|
||||
/// </summary>
|
||||
public static void SaveAttributeData2PersistentFolder(
|
||||
in string sceneName,
|
||||
in string gameObjectName,
|
||||
in SpectatorCameraAttribute data)
|
||||
{
|
||||
// Name format: {PREFIX}_{SCENE NAME}_{GAME OBJECT NAME}.json
|
||||
var fileNameWithExtension = GetSpectatorCameraAttributeFileNamePattern(sceneName, gameObjectName);
|
||||
|
||||
SaveAttributeData(Application.persistentDataPath, fileNameWithExtension, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load the spectator camera attribute as a JSON file on disk.
|
||||
/// </summary>
|
||||
/// <param name="fullPathWithFileNameAndExtension">The path (string) that include directory, file name and extension</param>
|
||||
/// <param name="data">The data of spectator camera attribute</param>
|
||||
/// <returns>True if get the attribute data successfully. Otherwise, return false.</returns>
|
||||
private static bool LoadAttributeData(
|
||||
string fullPathWithFileNameAndExtension,
|
||||
out SpectatorCameraAttribute data)
|
||||
{
|
||||
data = new SpectatorCameraAttribute();
|
||||
string json;
|
||||
try
|
||||
{
|
||||
json = File.ReadAllText(fullPathWithFileNameAndExtension);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogWarning($"Get attribute data from {fullPathWithFileNameAndExtension} failed: {e}");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(json))
|
||||
{
|
||||
Debug.LogWarning($"The attribute data at {fullPathWithFileNameAndExtension} is empty or null");
|
||||
return false;
|
||||
}
|
||||
|
||||
Debug.Log($"The attribute value is: {json}");
|
||||
data = JsonUtility.FromJson<SpectatorCameraAttribute>(json);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
Debug.LogWarning($"Convert attribute data from {fullPathWithFileNameAndExtension} failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
Debug.Log($"Get attribute data from {fullPathWithFileNameAndExtension} successful");
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the spectator camera attribute as a JSON file on disk.
|
||||
/// </summary>
|
||||
/// <param name="saveFileDirectory">The directory that the spectator camera attribute (JSON file) will save to</param>
|
||||
/// <param name="saveFileNameWithExtension">The file name of the spectator camera attribute (JSON file)</param>
|
||||
/// <param name="data">The data of spectator camera attribute</param>
|
||||
private static void SaveAttributeData(
|
||||
in string saveFileDirectory,
|
||||
in string saveFileNameWithExtension,
|
||||
in SpectatorCameraAttribute data)
|
||||
{
|
||||
if (string.IsNullOrEmpty(saveFileDirectory) || string.IsNullOrEmpty(saveFileNameWithExtension))
|
||||
{
|
||||
Debug.LogError("The saving file directory or name is null or empty");
|
||||
return;
|
||||
}
|
||||
|
||||
string fullPath = Path.Combine(saveFileDirectory, saveFileNameWithExtension);
|
||||
|
||||
// Convert to string format
|
||||
string json = JsonUtility.ToJson(data);
|
||||
|
||||
// Make sure the file path is exist
|
||||
if (!Directory.Exists(saveFileDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(saveFileDirectory);
|
||||
}
|
||||
|
||||
File.WriteAllText(fullPath, json);
|
||||
|
||||
Debug.Log($"The configuration save at {fullPath}");
|
||||
}
|
||||
|
||||
public static string GetSpectatorCameraAttributeFileNamePattern(
|
||||
in string sceneName,
|
||||
in string gameObjectName,
|
||||
bool withExtension = true)
|
||||
{
|
||||
var fileNamePattern = $"{ATTRIBUTE_FILE_PREFIX_NAME}_{sceneName}_{gameObjectName}";
|
||||
if (withExtension)
|
||||
{
|
||||
fileNamePattern += $".{ATTRIBUTE_FILE_EXTENSION}";
|
||||
}
|
||||
|
||||
return fileNamePattern;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check the panorama resolution is power of two or not. If not, convert to power of two.
|
||||
/// </summary>
|
||||
/// <param name="inputResolution">The panorama resolution</param>
|
||||
/// <returns></returns>
|
||||
public static int CheckAndConvertPanoramaResolution(in int inputResolution)
|
||||
{
|
||||
int result;
|
||||
|
||||
// Check is power of two
|
||||
if ((inputResolution != 0) && ((inputResolution & (inputResolution - 1)) == 0))
|
||||
{
|
||||
result = Mathf.Clamp(inputResolution, PANORAMA_RESOLUTION_MIN, PANORAMA_RESOLUTION_MAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If not power of two, convert to power of two
|
||||
int clampInputValue = Mathf.Clamp(inputResolution, PANORAMA_RESOLUTION_MIN, PANORAMA_RESOLUTION_MAX);
|
||||
var base2LogarithmOfClampInputValue = (int)System.Math.Log(clampInputValue, 2);
|
||||
|
||||
var base2LogarithmOfClampInputValueLowerStepValue =
|
||||
(int)System.Math.Pow(2, base2LogarithmOfClampInputValue);
|
||||
var base2LogarithmOfClampInputValueUpperStepValue =
|
||||
(int)System.Math.Pow(2, base2LogarithmOfClampInputValue + 1);
|
||||
|
||||
// Check which one is closer
|
||||
if (clampInputValue - base2LogarithmOfClampInputValueLowerStepValue <=
|
||||
base2LogarithmOfClampInputValueUpperStepValue - clampInputValue)
|
||||
{
|
||||
result = base2LogarithmOfClampInputValueLowerStepValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = base2LogarithmOfClampInputValueUpperStepValue;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#region Functions of changing camera culling mask
|
||||
|
||||
/// <summary>
|
||||
/// Set the layer that the camera can watch
|
||||
/// </summary>
|
||||
/// <param name="targetCullingMask">The camera culling mask</param>
|
||||
/// <param name="shownLayer">The layer number that you want to set the camera can watch</param>
|
||||
/// <returns>The new camera culling mask after modify</returns>
|
||||
public static LayerMask SetCameraVisualizationLayer(in LayerMask targetCullingMask, in int shownLayer)
|
||||
{
|
||||
LayerMask targetLayerMaskAfterModify = targetCullingMask;
|
||||
targetLayerMaskAfterModify |= 1 << shownLayer;
|
||||
return targetLayerMaskAfterModify;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the layer that the camera cannot watch
|
||||
/// </summary>
|
||||
/// <param name="targetCullingMask">The camera culling mask</param>
|
||||
/// <param name="hiddenLayer">The layer number that you want to set the camera cannot watch</param>
|
||||
/// <returns>The new camera culling mask after modify</returns>
|
||||
public static LayerMask SetCameraHiddenLayer(in LayerMask targetCullingMask, in int hiddenLayer)
|
||||
{
|
||||
LayerMask targetLayerMaskAfterModify = targetCullingMask;
|
||||
targetLayerMaskAfterModify &= ~(1 << hiddenLayer);
|
||||
return targetLayerMaskAfterModify;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inverse specific layer in camera culling mask
|
||||
/// </summary>
|
||||
/// <param name="targetCullingMask">The camera culling mask</param>
|
||||
/// <param name="inverseLayer">The layer number that you want to inverse</param>
|
||||
/// <returns>The new camera culling mask after modify</returns>
|
||||
public static LayerMask InverseCameraLayer(in LayerMask targetCullingMask, in int inverseLayer)
|
||||
{
|
||||
LayerMask targetLayerMaskAfterModify = targetCullingMask;
|
||||
targetLayerMaskAfterModify ^= 1 << inverseLayer;
|
||||
return targetLayerMaskAfterModify;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[System.Serializable]
|
||||
public class SpectatorCameraAttribute
|
||||
{
|
||||
#region Serializable class field
|
||||
|
||||
public CameraSourceRef source;
|
||||
public Vector3 position;
|
||||
public Quaternion rotation;
|
||||
public LayerMask layerMask;
|
||||
public bool isSmoothCameraMovement;
|
||||
public int smoothCameraMovementSpeed;
|
||||
public bool isFrustumShowed;
|
||||
public float verticalFov;
|
||||
public SpectatorCameraPanoramaResolution panoramaResolution;
|
||||
public TextureProcessHelper.PictureOutputFormat panoramaOutputFormat;
|
||||
public TextureProcessHelper.PanoramaType panoramaOutputType;
|
||||
public FrustumLineCount frustumLineCount;
|
||||
public FrustumCenterLineCount frustumCenterLineCount;
|
||||
public float frustumLineWidth;
|
||||
public float frustumCenterLineWidth;
|
||||
public Color frustumLineColor;
|
||||
public Color frustumCenterLineColor;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public SpectatorCameraAttribute()
|
||||
{
|
||||
}
|
||||
|
||||
public SpectatorCameraAttribute(
|
||||
CameraSourceRef source,
|
||||
Vector3 position,
|
||||
Quaternion rotation,
|
||||
LayerMask layerMask,
|
||||
bool isSmoothCameraMovement,
|
||||
int smoothCameraMovementSpeed,
|
||||
bool isFrustumShowed,
|
||||
float verticalFov,
|
||||
SpectatorCameraPanoramaResolution panoramaResolution,
|
||||
TextureProcessHelper.PictureOutputFormat panoramaOutputFormat,
|
||||
TextureProcessHelper.PanoramaType panoramaOutputType,
|
||||
FrustumLineCount frustumLineCount,
|
||||
FrustumCenterLineCount frustumCenterLineCount,
|
||||
float frustumLineWidth,
|
||||
float frustumCenterLineWidth,
|
||||
Color frustumLineColor,
|
||||
Color frustumCenterLineColor)
|
||||
{
|
||||
this.source = source;
|
||||
this.position = position;
|
||||
this.rotation = rotation;
|
||||
this.layerMask = layerMask;
|
||||
this.isSmoothCameraMovement = isSmoothCameraMovement;
|
||||
this.smoothCameraMovementSpeed = smoothCameraMovementSpeed;
|
||||
this.isFrustumShowed = isFrustumShowed;
|
||||
this.verticalFov = verticalFov;
|
||||
this.panoramaResolution = panoramaResolution;
|
||||
this.panoramaOutputFormat = panoramaOutputFormat;
|
||||
this.panoramaOutputType = panoramaOutputType;
|
||||
this.frustumLineCount = frustumLineCount;
|
||||
this.frustumCenterLineCount = frustumCenterLineCount;
|
||||
this.frustumLineWidth = frustumLineWidth;
|
||||
this.frustumCenterLineWidth = frustumCenterLineWidth;
|
||||
this.frustumLineColor = frustumLineColor;
|
||||
this.frustumCenterLineColor = frustumCenterLineColor;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region Enum definition
|
||||
|
||||
public enum CameraSourceRef
|
||||
{
|
||||
Hmd,
|
||||
Tracker
|
||||
}
|
||||
|
||||
public enum FrustumLineCount
|
||||
{
|
||||
None = 0,
|
||||
Four = 4,
|
||||
Eight = 8,
|
||||
Sixteen = 16,
|
||||
ThirtyTwo = 32,
|
||||
OneTwentyEight = 128,
|
||||
}
|
||||
|
||||
public enum FrustumCenterLineCount
|
||||
{
|
||||
None = 0,
|
||||
Center = 1,
|
||||
RuleOfThirds = 4,
|
||||
CenterAndRuleOfThirds = 5,
|
||||
}
|
||||
|
||||
public enum SpectatorCameraPanoramaResolution
|
||||
{
|
||||
_512 = 512,
|
||||
_1024 = 1024,
|
||||
_2048 = 2048,
|
||||
_4096 = 4096
|
||||
}
|
||||
|
||||
public enum AttributeFileLocation
|
||||
{
|
||||
ResourceFolder,
|
||||
PersistentFolder
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3136b6864f4cb9c4da5234953d3a75b4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09984648d0f364648af4f0ac5a03de55
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,127 @@
|
||||
// Copyright HTC Corporation All Rights Reserved.
|
||||
|
||||
using UnityEngine;
|
||||
using VIVE.OpenXR.Toolkits.Spectator.Helper;
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.Spectator
|
||||
{
|
||||
/// <summary>
|
||||
/// Name: ISpectatorCameraSetting.cs
|
||||
/// Role: Contract
|
||||
/// Responsibility: Define the setting attribute of the spectator camera.
|
||||
/// </summary>
|
||||
public interface ISpectatorCameraSetting
|
||||
{
|
||||
#region Property
|
||||
|
||||
/// <summary>
|
||||
/// The struct UnityEngine.LayerMask defines which layer the camera can see or not.
|
||||
/// </summary>
|
||||
LayerMask LayerMask { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to enable the feature of smoothing the spectator camera movement.
|
||||
/// </summary>
|
||||
bool IsSmoothCameraMovement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The speed factor to control the smoothing impact.
|
||||
/// </summary>
|
||||
int SmoothCameraMovementSpeed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// True if visualize the spectator camera vertical FOV.
|
||||
/// </summary>
|
||||
bool IsFrustumShowed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The spectator camera vertical FOV.
|
||||
/// </summary>
|
||||
float VerticalFov { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The panorama image resolution.
|
||||
/// </summary>
|
||||
SpectatorCameraHelper.SpectatorCameraPanoramaResolution PanoramaResolution { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The panorama image output format.
|
||||
/// </summary>
|
||||
TextureProcessHelper.PictureOutputFormat PanoramaOutputFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The panorama types.
|
||||
/// </summary>
|
||||
TextureProcessHelper.PanoramaType PanoramaOutputType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many frustum lines will be shown?
|
||||
/// </summary>
|
||||
SpectatorCameraHelper.FrustumLineCount FrustumLineCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many frustum center lines will be shown?
|
||||
/// </summary>
|
||||
SpectatorCameraHelper.FrustumCenterLineCount FrustumCenterLineCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Frustum line width.
|
||||
/// </summary>
|
||||
float FrustumLineWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Frustum center line width.
|
||||
/// </summary>
|
||||
float FrustumCenterLineWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Frustum line color.
|
||||
/// </summary>
|
||||
Color FrustumLineColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Frustum center line color.
|
||||
/// </summary>
|
||||
Color FrustumCenterLineColor { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Function
|
||||
|
||||
/// <summary>
|
||||
/// Reset the spectator camera setting to the default value.
|
||||
/// </summary>
|
||||
void ResetSetting();
|
||||
|
||||
/// <summary>
|
||||
/// Export the current spectator camera setting as a JSON file and then save it to the resource folder or persistent folder.
|
||||
/// </summary>
|
||||
/// <param name="attributeFileLocation">The enum SpectatorCameraHelper.AttributeFileLocation.</param>
|
||||
void ExportSetting2JsonFile(in SpectatorCameraHelper.AttributeFileLocation attributeFileLocation);
|
||||
|
||||
/// <summary>
|
||||
/// Load the setting (JSON) file via input full file path.
|
||||
/// </summary>
|
||||
/// <param name="jsonFilePath">The setting file’s full path (including file name and JSON extension).</param>
|
||||
void LoadSettingFromJsonFile(in string jsonFilePath);
|
||||
|
||||
/// <summary>
|
||||
/// Load the setting (JSON) file via input scene name, GameObject (hmd) name, and the file location (resource folder or persistent folder).
|
||||
/// </summary>
|
||||
/// <param name="sceneName">The scene name.</param>
|
||||
/// <param name="gameObjectName">The GameObject name.</param>
|
||||
/// <param name="attributeFileLocation"> The enum SpectatorCameraHelper.AttributeFileLocation.</param>
|
||||
void LoadSettingFromJsonFile(
|
||||
in string sceneName,
|
||||
in string gameObjectName,
|
||||
in SpectatorCameraHelper.AttributeFileLocation attributeFileLocation);
|
||||
|
||||
/// <summary>
|
||||
/// Apply the spectator camera setting to the current component.
|
||||
/// </summary>
|
||||
/// <param name="data">The data you want to apply.</param>
|
||||
void ApplyData(in SpectatorCameraHelper.SpectatorCameraAttribute data);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 913ccea163eb50d4e911f0e8cadaadeb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,748 @@
|
||||
// Copyright HTC Corporation All Rights Reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using VIVE.OpenXR.Toolkits.Spectator.Helper;
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.Spectator
|
||||
{
|
||||
/// <summary>
|
||||
/// Name: SpectatorCameraManager.Editor.cs
|
||||
/// Role: General script use in Unity Editor only
|
||||
/// Responsibility: Display the SpectatorCameraManager.cs in Unity Inspector
|
||||
/// </summary>
|
||||
public partial class SpectatorCameraManager
|
||||
{
|
||||
[SerializeField] private Material spectatorCameraViewMaterial;
|
||||
|
||||
/// <summary>
|
||||
/// Material that show the spectator camera view
|
||||
/// </summary>
|
||||
private Material SpectatorCameraViewMaterial
|
||||
{
|
||||
// get; private set;
|
||||
get => spectatorCameraViewMaterial;
|
||||
set
|
||||
{
|
||||
spectatorCameraViewMaterial = value;
|
||||
if (SpectatorCameraBased && value)
|
||||
{
|
||||
SpectatorCameraBased.SpectatorCameraViewMaterial = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[field: SerializeField] private bool IsShowHmdPart { get; set; }
|
||||
[field: SerializeField] private bool IsShowTrackerPart { get; set; }
|
||||
[field: SerializeField] private bool IsRequireLoadJsonFile { get; set; }
|
||||
|
||||
[CustomEditor(typeof(SpectatorCameraManager))]
|
||||
public class SpectatorCameraManagerEditor : UnityEditor.Editor
|
||||
{
|
||||
private static readonly Color HighlightRegionBackgroundColor = new Color(.2f, .2f, .2f, .1f);
|
||||
|
||||
private SerializedProperty IsShowHmdPart { get; set; }
|
||||
private SerializedProperty IsShowTrackerPart { get; set; }
|
||||
private SerializedProperty IsRequireLoadJsonFile { get; set; }
|
||||
private List<string> JsonFileList { get; set; }
|
||||
private Vector2 JsonFileScrollViewVector { get; set; }
|
||||
|
||||
private SerializedProperty IsSmoothCameraMovement { get; set; }
|
||||
private SerializedProperty SmoothCameraMovementSpeed { get; set; }
|
||||
private SerializedProperty PanoramaResolution { get; set; }
|
||||
private SerializedProperty PanoramaOutputFormat { get; set; }
|
||||
private SerializedProperty PanoramaOutputType { get; set; }
|
||||
|
||||
private SerializedProperty SpectatorCameraPrefab { get; set; }
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
IsShowHmdPart = serializedObject.FindProperty(EditorHelper.PropertyName("IsShowHmdPart"));
|
||||
IsShowTrackerPart = serializedObject.FindProperty(EditorHelper.PropertyName("IsShowTrackerPart"));
|
||||
IsRequireLoadJsonFile =
|
||||
serializedObject.FindProperty(EditorHelper.PropertyName("IsRequireLoadJsonFile"));
|
||||
JsonFileList = new List<string>();
|
||||
JsonFileScrollViewVector = Vector2.zero;
|
||||
|
||||
IsSmoothCameraMovement =
|
||||
serializedObject.FindProperty(EditorHelper.PropertyName("IsSmoothCameraMovement"));
|
||||
SmoothCameraMovementSpeed =
|
||||
serializedObject.FindProperty(EditorHelper.PropertyName("SmoothCameraMovementSpeed"));
|
||||
|
||||
PanoramaResolution = serializedObject.FindProperty(EditorHelper.PropertyName("PanoramaResolution"));
|
||||
PanoramaOutputFormat = serializedObject.FindProperty(EditorHelper.PropertyName("PanoramaOutputFormat"));
|
||||
PanoramaOutputType = serializedObject.FindProperty(EditorHelper.PropertyName("PanoramaOutputType"));
|
||||
|
||||
SpectatorCameraPrefab =
|
||||
serializedObject.FindProperty(EditorHelper.PropertyName("SpectatorCameraPrefab"));
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
// Just return if not "SpectatorCameraManager" class
|
||||
if (!(target is SpectatorCameraManager))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
DrawGUI();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void DrawGUI()
|
||||
{
|
||||
#region GUIStyle
|
||||
|
||||
var labelStyle = new GUIStyle()
|
||||
{
|
||||
richText = true,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
normal = new GUIStyleState
|
||||
{
|
||||
textColor = EditorGUIUtility.isProSkin ? Color.green : Color.black
|
||||
}
|
||||
};
|
||||
|
||||
var resetButtonStyle = new GUIStyle(GUI.skin.button)
|
||||
{
|
||||
fontStyle = FontStyle.Bold,
|
||||
normal = new GUIStyleState
|
||||
{
|
||||
textColor = EditorGUIUtility.isProSkin ? Color.yellow : Color.red
|
||||
},
|
||||
hover = new GUIStyleState
|
||||
{
|
||||
textColor = Color.red
|
||||
},
|
||||
active = new GUIStyleState
|
||||
{
|
||||
textColor = Color.cyan
|
||||
},
|
||||
};
|
||||
|
||||
var boldButtonStyle = new GUIStyle(GUI.skin.button)
|
||||
{
|
||||
fontStyle = FontStyle.Bold
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
var script = (SpectatorCameraManager)target;
|
||||
|
||||
// Button for reset value
|
||||
if (GUILayout.Button("Reset to default value", resetButtonStyle))
|
||||
{
|
||||
Undo.RecordObject(target, "Reset SpectatorCameraManager to default value");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.ResetSetting();
|
||||
}
|
||||
|
||||
// Button for export setting
|
||||
if (GUILayout.Button("Export Spectator Camera HMD Setting", boldButtonStyle))
|
||||
{
|
||||
script.ExportSetting2JsonFile(SpectatorCameraHelper.AttributeFileLocation.ResourceFolder);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
#region Load Setting From JSON File
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
EditorGUI.BeginDisabledGroup(IsRequireLoadJsonFile.boolValue);
|
||||
if (GUILayout.Button("Load Setting From JSON File in Resources Folder", boldButtonStyle) ||
|
||||
IsRequireLoadJsonFile.boolValue)
|
||||
{
|
||||
IsRequireLoadJsonFile.boolValue = true;
|
||||
var searchPattern =
|
||||
$"{SpectatorCameraHelper.ATTRIBUTE_FILE_PREFIX_NAME}*.{SpectatorCameraHelper.ATTRIBUTE_FILE_EXTENSION}";
|
||||
|
||||
if (JsonFileList == null)
|
||||
{
|
||||
JsonFileList = new List<string>();
|
||||
}
|
||||
|
||||
JsonFileList.Clear();
|
||||
|
||||
var dir = new DirectoryInfo(Path.Combine(Application.dataPath, "Resources"));
|
||||
var files = dir.GetFiles(searchPattern);
|
||||
foreach (var item in files)
|
||||
{
|
||||
JsonFileList.Add(item.Name);
|
||||
}
|
||||
|
||||
if (JsonFileList.Count == 0)
|
||||
{
|
||||
Debug.Log(
|
||||
"Can't find any JSON file related to the spectator camera setting in the Resources folder.");
|
||||
IsRequireLoadJsonFile.boolValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
if (IsRequireLoadJsonFile.boolValue)
|
||||
{
|
||||
if (GUILayout.Button("Cancel"))
|
||||
{
|
||||
IsRequireLoadJsonFile.boolValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (IsRequireLoadJsonFile.boolValue)
|
||||
{
|
||||
Rect r = EditorGUILayout.BeginVertical();
|
||||
|
||||
JsonFileScrollViewVector = EditorGUILayout.BeginScrollView(JsonFileScrollViewVector,
|
||||
GUILayout.Width(r.width),
|
||||
GUILayout.Height(80));
|
||||
|
||||
for (int i = 0; i < JsonFileList.Count; i++)
|
||||
{
|
||||
if (GUILayout.Button(JsonFileList[i]))
|
||||
{
|
||||
var path = Path.Combine(
|
||||
System.IO.Path.Combine(Application.dataPath, "Resources"),
|
||||
JsonFileList[i]);
|
||||
Undo.RecordObject(target, $"Load {JsonFileList[i]} setting to {target.name} SpectatorCameraManager");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.LoadSettingFromJsonFile(path);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
// Spectator camera prefab
|
||||
EditorGUILayout.PropertyField(SpectatorCameraPrefab, new GUIContent("Spectator Camera Prefab"));
|
||||
if (SpectatorCameraPrefab.objectReferenceValue != null &&
|
||||
PrefabUtility.GetPrefabAssetType(SpectatorCameraPrefab.objectReferenceValue) ==
|
||||
PrefabAssetType.NotAPrefab)
|
||||
{
|
||||
// The assign object is scene object
|
||||
Debug.Log("Please assign the object as prefab only.");
|
||||
SpectatorCameraPrefab.objectReferenceValue = null;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
EditorGUILayout.LabelField("<b>[ General Setting ]</b>", labelStyle);
|
||||
|
||||
// Setting of spectator camera reference source
|
||||
// EditorGUILayout.PropertyField(CameraSourceRef, new GUIContent("Camera Source"));
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentCameraSourceRef = (SpectatorCameraHelper.CameraSourceRef)
|
||||
EditorGUILayout.EnumPopup("Camera Source", script.CameraSourceRef);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, "Modified SpectatorCameraManager CameraSourceRef");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.CameraSourceRef = currentCameraSourceRef;
|
||||
}
|
||||
|
||||
#region Tracker Region
|
||||
|
||||
if (script.CameraSourceRef == SpectatorCameraHelper.CameraSourceRef.Tracker)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentFollowSpectatorCameraTracker = EditorGUILayout.ObjectField(
|
||||
"Tracker",
|
||||
script.FollowSpectatorCameraTracker,
|
||||
typeof(SpectatorCameraTracker),
|
||||
true) as SpectatorCameraTracker;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, "Modified SpectatorCameraManager FollowSpectatorCameraTracker");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FollowSpectatorCameraTracker = currentFollowSpectatorCameraTracker;
|
||||
}
|
||||
|
||||
if (script.FollowSpectatorCameraTracker == null)
|
||||
{
|
||||
// The assign object is null
|
||||
EditorGUILayout.HelpBox("Please assign the SpectatorCameraTracker", MessageType.Info, false);
|
||||
}
|
||||
else if (PrefabUtility.GetPrefabAssetType(script.FollowSpectatorCameraTracker) !=
|
||||
PrefabAssetType.NotAPrefab)
|
||||
{
|
||||
// Don't allow assign object is prefab
|
||||
Debug.Log("Please assign the scene object.");
|
||||
script.FollowSpectatorCameraTracker = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The assign object is scene object => ok
|
||||
EditorGUILayout.LabelField("\n");
|
||||
IsShowTrackerPart.boolValue =
|
||||
EditorGUILayout.Foldout(IsShowTrackerPart.boolValue, "Tracker Setting");
|
||||
if (IsShowTrackerPart.boolValue)
|
||||
{
|
||||
// If show the tracker setting
|
||||
Rect r = EditorGUILayout.BeginVertical();
|
||||
|
||||
SpectatorCameraTracker trackerObject = script.FollowSpectatorCameraTracker;
|
||||
|
||||
if (trackerObject != null)
|
||||
{
|
||||
EditorGUILayout.HelpBox(
|
||||
$"You are now editing the tracker setting in \"{trackerObject.gameObject.name}\" GameObject",
|
||||
MessageType.Info,
|
||||
true);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentTrackerObjectLayerMask =
|
||||
LayerMaskHelper.LayerMaskDrawer.LayerMaskField("Camera Layer Mask",
|
||||
trackerObject.LayerMask);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} LayerMask");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.LayerMask = currentTrackerObjectLayerMask;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentTrackerObjectIsSmoothCameraMovement=
|
||||
EditorGUILayout.Toggle("Enable Smoothing Camera Movement",
|
||||
trackerObject.IsSmoothCameraMovement);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} IsSmoothCameraMovement");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.IsSmoothCameraMovement = currentTrackerObjectIsSmoothCameraMovement;
|
||||
}
|
||||
|
||||
if (trackerObject.IsSmoothCameraMovement)
|
||||
{
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
EditorGUILayout.LabelField("<b>[ Smooth Camera Movement Speed Setting ]</b>",
|
||||
labelStyle);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentTrackerObjectSmoothCameraMovementSpeed =
|
||||
EditorGUILayout.IntSlider(
|
||||
new GUIContent("Speed of Smoothing Camera Movement"),
|
||||
trackerObject.SmoothCameraMovementSpeed,
|
||||
SpectatorCameraHelper.SMOOTH_CAMERA_MOVEMENT_MIN,
|
||||
SpectatorCameraHelper.SMOOTH_CAMERA_MOVEMENT_MAX);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} SmoothCameraMovementSpeed");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.SmoothCameraMovementSpeed = currentTrackerObjectSmoothCameraMovementSpeed;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Spectator camera frustum show/hide
|
||||
var currentTrackerObjectIsFrustumShowed =
|
||||
EditorGUILayout.Toggle("Enable Camera FOV Frustum", trackerObject.IsFrustumShowed);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} IsFrustumShowed");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.IsFrustumShowed = currentTrackerObjectIsFrustumShowed;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
#region VerticalFov
|
||||
|
||||
EditorGUILayout.LabelField("<b>[ Vertical FOV Setting ]</b>", labelStyle);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentTrackerObjectVerticalFov = EditorGUILayout.Slider(
|
||||
"Vertical FOV",
|
||||
trackerObject.VerticalFov,
|
||||
SpectatorCameraHelper.VERTICAL_FOV_MIN,
|
||||
SpectatorCameraHelper.VERTICAL_FOV_MAX);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} VerticalFov");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.VerticalFov = currentTrackerObjectVerticalFov;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
#region Setting related to panorama capturing of spectator camera
|
||||
|
||||
// Panorama resolution
|
||||
EditorGUILayout.LabelField("<b>[ Panorama Setting ]</b>", labelStyle);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Panorama output resolution
|
||||
var currentTrackerObjectPanoramaResolution =
|
||||
(SpectatorCameraHelper.SpectatorCameraPanoramaResolution)
|
||||
EditorGUILayout.EnumPopup("Resolution", trackerObject.PanoramaResolution);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} PanoramaResolution");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.PanoramaResolution = currentTrackerObjectPanoramaResolution;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Panorama output format
|
||||
var currentTrackerObjectPanoramaOutputFormat = (TextureProcessHelper.PictureOutputFormat)
|
||||
EditorGUILayout.EnumPopup("Output Format", trackerObject.PanoramaOutputFormat);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} PanoramaOutputFormat");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.PanoramaOutputFormat = currentTrackerObjectPanoramaOutputFormat;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Panorama output type
|
||||
var currentTrackerObjectPanoramaOutputType = (TextureProcessHelper.PanoramaType)
|
||||
EditorGUILayout.EnumPopup("Output Type", trackerObject.PanoramaOutputType);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} PanoramaOutputType");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.PanoramaOutputType = currentTrackerObjectPanoramaOutputType;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
#region Setting related to frustum
|
||||
|
||||
if (trackerObject.IsFrustumShowed)
|
||||
{
|
||||
EditorGUILayout.LabelField("<b>[ Frustum Setting ]</b>",
|
||||
labelStyle);
|
||||
|
||||
#region Count of frustum and frustum center line
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentTrackerObjectFrustumLineCount = (SpectatorCameraHelper.FrustumLineCount)
|
||||
EditorGUILayout.EnumPopup("Frustum Line Total", trackerObject.FrustumLineCount);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} FrustumLineCount");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.FrustumLineCount = currentTrackerObjectFrustumLineCount;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentTrackerObjectFrustumCenterLineCount =
|
||||
(SpectatorCameraHelper.FrustumCenterLineCount)
|
||||
EditorGUILayout.EnumPopup("Frustum Center Line Total",
|
||||
trackerObject.FrustumCenterLineCount);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} FrustumCenterLineCount");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.FrustumCenterLineCount = currentTrackerObjectFrustumCenterLineCount;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
#region Width of frustum and frustum center line
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentTrackerObjectFrustumLineWidth =
|
||||
EditorGUILayout.Slider(
|
||||
"Frustum Line Width",
|
||||
trackerObject.FrustumLineWidth,
|
||||
SpectatorCameraHelper.FRUSTUM_LINE_WIDTH_MIN,
|
||||
SpectatorCameraHelper.FRUSTUM_LINE_WIDTH_MAX);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} FrustumLineWidth");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.FrustumLineWidth = currentTrackerObjectFrustumLineWidth;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentTrackerObjectFrustumCenterLineWidth =
|
||||
EditorGUILayout.Slider(
|
||||
"Frustum Center Line Width",
|
||||
trackerObject.FrustumCenterLineWidth,
|
||||
SpectatorCameraHelper.FRUSTUM_CENTER_LINE_WIDTH_MIN,
|
||||
SpectatorCameraHelper.FRUSTUM_CENTER_LINE_WIDTH_MAX);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} FrustumCenterLineWidth");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.FrustumCenterLineWidth = currentTrackerObjectFrustumCenterLineWidth;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
#region Material of frustum and frustum center line
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentTrackerObjectFrustumLineColor = EditorGUILayout.ColorField(
|
||||
"Frustum Line Color", trackerObject.FrustumLineColor);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} FrustumLineColor");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.FrustumLineColor = currentTrackerObjectFrustumLineColor;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentTrackerObjectFrustumCenterLineColor = EditorGUILayout.ColorField(
|
||||
"Frustum Center Line Color",
|
||||
trackerObject.FrustumCenterLineColor);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(trackerObject, $"Modified {trackerObject.name} FrustumCenterLineColor");
|
||||
EditorUtility.SetDirty(trackerObject);
|
||||
trackerObject.FrustumCenterLineColor = currentTrackerObjectFrustumCenterLineColor;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
r = new Rect(r.x, r.y, r.width, r.height);
|
||||
EditorGUI.DrawRect(r, HighlightRegionBackgroundColor);
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region HMD Region
|
||||
|
||||
IsShowHmdPart.boolValue = EditorGUILayout.Foldout(IsShowHmdPart.boolValue, "HMD Setting");
|
||||
if (IsShowHmdPart.boolValue)
|
||||
{
|
||||
Rect r = EditorGUILayout.BeginVertical();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Setting of spectator camera layer mask
|
||||
var currentLayerMask =
|
||||
LayerMaskHelper.LayerMaskDrawer.LayerMaskField("Camera Layer Mask", script.LayerMask);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, "Modified SpectatorCameraManager LayerMask");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.LayerMask = currentLayerMask;
|
||||
}
|
||||
|
||||
// Setting of smooth spectator camera movement
|
||||
EditorGUILayout.PropertyField(IsSmoothCameraMovement,
|
||||
new GUIContent("Enable Smoothing Camera Movement"));
|
||||
if (IsSmoothCameraMovement.boolValue)
|
||||
{
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
EditorGUILayout.LabelField("<b>[ Smooth Camera Movement Speed Setting ]</b>", labelStyle);
|
||||
|
||||
// Setting of smooth spectator camera movement speed
|
||||
EditorGUILayout.IntSlider(
|
||||
SmoothCameraMovementSpeed,
|
||||
SpectatorCameraHelper.SMOOTH_CAMERA_MOVEMENT_MIN,
|
||||
SpectatorCameraHelper.SMOOTH_CAMERA_MOVEMENT_MAX,
|
||||
"Speed of Smoothing Camera Movement");
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Spectator camera frustum show/hide
|
||||
var currentIsFrustumShowed =
|
||||
EditorGUILayout.Toggle("Enable Camera FOV Frustum", script.IsFrustumShowed);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, "Modified SpectatorCameraManager IsFrustumShowed");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.IsFrustumShowed = currentIsFrustumShowed;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
#region VerticalFov
|
||||
|
||||
EditorGUILayout.LabelField("<b>[ Vertical FOV Setting ]</b>", labelStyle);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// FOV
|
||||
var currentVerticalFov = EditorGUILayout.Slider(
|
||||
"Vertical FOV",
|
||||
script.VerticalFov,
|
||||
SpectatorCameraHelper.VERTICAL_FOV_MIN,
|
||||
SpectatorCameraHelper.VERTICAL_FOV_MAX);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, "Modified SpectatorCameraManager VerticalFov");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.VerticalFov = currentVerticalFov;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
#region Setting related to panorama capturing of spectator camera
|
||||
|
||||
// Panorama resolution
|
||||
EditorGUILayout.LabelField("<b>[ Panorama Setting ]</b>", labelStyle);
|
||||
EditorGUILayout.PropertyField(PanoramaResolution, new GUIContent("Resolution"));
|
||||
|
||||
// Panorama output format
|
||||
EditorGUILayout.PropertyField(PanoramaOutputFormat, new GUIContent("Output Format"));
|
||||
|
||||
// Panorama output type
|
||||
EditorGUILayout.PropertyField(PanoramaOutputType, new GUIContent("Output Type"));
|
||||
|
||||
#endregion
|
||||
|
||||
#region Setting related to frustum
|
||||
|
||||
if (script.IsFrustumShowed)
|
||||
{
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
EditorGUILayout.LabelField("<b>[ Frustum Setting ]</b>", labelStyle);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Count of frustum line
|
||||
var currentFrustumLineCount = (SpectatorCameraHelper.FrustumLineCount)
|
||||
EditorGUILayout.EnumPopup("Frustum Line Total", script.FrustumLineCount);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, "Modified SpectatorCameraManager FrustumLineCount");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FrustumLineCount = currentFrustumLineCount;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Count of frustum center line
|
||||
var currentFrustumCenterLineCount = (SpectatorCameraHelper.FrustumCenterLineCount)
|
||||
EditorGUILayout.EnumPopup("Frustum Center Line Total", script.FrustumCenterLineCount);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, "Modified SpectatorCameraManager FrustumCenterLineCount");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FrustumCenterLineCount = currentFrustumCenterLineCount;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Width of frustum line
|
||||
var currentFrustumLineWidth =
|
||||
EditorGUILayout.Slider(
|
||||
"Frustum Line Width",
|
||||
script.FrustumLineWidth,
|
||||
SpectatorCameraHelper.FRUSTUM_LINE_WIDTH_MIN,
|
||||
SpectatorCameraHelper.FRUSTUM_LINE_WIDTH_MAX);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, "Modified SpectatorCameraManager FrustumLineWidth");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FrustumLineWidth = currentFrustumLineWidth;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Width of frustum center line
|
||||
var currentFrustumCenterLineWidth =
|
||||
EditorGUILayout.Slider(
|
||||
"Frustum Center Line Width",
|
||||
script.FrustumCenterLineWidth,
|
||||
SpectatorCameraHelper.FRUSTUM_CENTER_LINE_WIDTH_MIN,
|
||||
SpectatorCameraHelper.FRUSTUM_CENTER_LINE_WIDTH_MAX);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, "Modified SpectatorCameraManager FrustumCenterLineWidth");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FrustumCenterLineWidth = currentFrustumCenterLineWidth;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Color of frustum line
|
||||
var currentFrustumLineColor = EditorGUILayout.ColorField(
|
||||
"Frustum Line Color", script.FrustumLineColor);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, "Modified SpectatorCameraManager FrustumLineColor");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FrustumLineColor = currentFrustumLineColor;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Color of frustum center line
|
||||
var currentFrustumCenterLineColor = EditorGUILayout.ColorField(
|
||||
"Frustum Center Line Color",
|
||||
script.FrustumCenterLineColor);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, "Modified SpectatorCameraManager FrustumCenterLineColor");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FrustumCenterLineColor = currentFrustumCenterLineColor;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
r = new Rect(r.x, r.y, r.width, r.height);
|
||||
EditorGUI.DrawRect(r, HighlightRegionBackgroundColor);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
#region Test 360 Output
|
||||
|
||||
EditorGUILayout.LabelField("<b>[ Debug Setting ]</b>", labelStyle);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var currentSpectatorCameraViewMaterial = EditorGUILayout.ObjectField(
|
||||
"Spectator Camera View Material",
|
||||
script.SpectatorCameraViewMaterial,
|
||||
typeof(Material),
|
||||
false) as Material;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, "Modified SpectatorCameraManager SpectatorCameraViewMaterial");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.SpectatorCameraViewMaterial = currentSpectatorCameraViewMaterial;
|
||||
}
|
||||
|
||||
EditorGUILayout.HelpBox("Test - Output 360 photo", MessageType.Info, true);
|
||||
if (GUILayout.Button("Test - Output 360 photo"))
|
||||
{
|
||||
script.CaptureSpectatorCamera360Photo();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5a03d623c31c2344a1f99005572762a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fda46617f9e447e47863938d3006d5bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,374 @@
|
||||
// Copyright HTC Corporation All Rights Reserved.
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using VIVE.OpenXR.Toolkits.Spectator.Helper;
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.Spectator
|
||||
{
|
||||
/// <summary>
|
||||
/// Name: SpectatorCameraTracker.Editor.cs
|
||||
/// Role: General script use in Unity Editor only
|
||||
/// Responsibility: Display the SpectatorCameraTracker.cs in Unity Inspector
|
||||
/// </summary>
|
||||
public partial class SpectatorCameraTracker
|
||||
{
|
||||
[field: SerializeField] private bool IsRequireLoadJsonFile { get; set; }
|
||||
|
||||
[CustomEditor(typeof(SpectatorCameraTracker))]
|
||||
public class SpectatorCameraTrackerSettingEditor : UnityEditor.Editor
|
||||
{
|
||||
private SerializedProperty IsRequireLoadJsonFile { get; set; }
|
||||
private List<string> JsonFileList { get; set; }
|
||||
private Vector2 JsonFileScrollViewVector { get; set; }
|
||||
|
||||
private SerializedProperty IsSmoothCameraMovement { get; set; }
|
||||
private SerializedProperty SmoothCameraMovementSpeed { get; set; }
|
||||
private SerializedProperty PanoramaResolution { get; set; }
|
||||
private SerializedProperty PanoramaOutputFormat { get; set; }
|
||||
private SerializedProperty PanoramaOutputType { get; set; }
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
IsRequireLoadJsonFile =
|
||||
serializedObject.FindProperty(EditorHelper.PropertyName("IsRequireLoadJsonFile"));
|
||||
JsonFileList = new List<string>();
|
||||
JsonFileScrollViewVector = Vector2.zero;
|
||||
|
||||
IsSmoothCameraMovement =
|
||||
serializedObject.FindProperty(EditorHelper.PropertyName("IsSmoothCameraMovement"));
|
||||
SmoothCameraMovementSpeed =
|
||||
serializedObject.FindProperty(EditorHelper.PropertyName("SmoothCameraMovementSpeed"));
|
||||
PanoramaResolution = serializedObject.FindProperty(EditorHelper.PropertyName("PanoramaResolution"));
|
||||
PanoramaOutputFormat = serializedObject.FindProperty(EditorHelper.PropertyName("PanoramaOutputFormat"));
|
||||
PanoramaOutputType = serializedObject.FindProperty(EditorHelper.PropertyName("PanoramaOutputType"));
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
// Just return if not "SpectatorCameraTrackerSetting" class
|
||||
if (!(target is SpectatorCameraTracker))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
DrawGUI();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void DrawGUI()
|
||||
{
|
||||
#region GUIStyle
|
||||
|
||||
var labelStyle = new GUIStyle()
|
||||
{
|
||||
richText = true,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
normal = new GUIStyleState
|
||||
{
|
||||
textColor = EditorGUIUtility.isProSkin ? Color.green : Color.black
|
||||
}
|
||||
};
|
||||
|
||||
var resetButtonStyle = new GUIStyle(GUI.skin.button)
|
||||
{
|
||||
fontStyle = FontStyle.Bold,
|
||||
normal = new GUIStyleState
|
||||
{
|
||||
textColor = EditorGUIUtility.isProSkin ? Color.yellow : Color.red
|
||||
},
|
||||
hover = new GUIStyleState
|
||||
{
|
||||
textColor = Color.red
|
||||
},
|
||||
active = new GUIStyleState
|
||||
{
|
||||
textColor = Color.cyan
|
||||
},
|
||||
};
|
||||
|
||||
var boldButtonStyle = new GUIStyle(GUI.skin.button)
|
||||
{
|
||||
fontStyle = FontStyle.Bold
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
var script = (SpectatorCameraTracker)target;
|
||||
|
||||
// Button for reset value
|
||||
if (GUILayout.Button("Reset to default value", resetButtonStyle))
|
||||
{
|
||||
Undo.RecordObject(target, $"Reset {target.name} SpectatorCameraTracker to default value");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.ResetSetting();
|
||||
}
|
||||
|
||||
// Button for export setting
|
||||
if (GUILayout.Button("Export Spectator Camera Tracker Setting", boldButtonStyle))
|
||||
{
|
||||
script.ExportSetting2JsonFile(SpectatorCameraHelper.AttributeFileLocation.ResourceFolder);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
#region Load setting from JSON file
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
EditorGUI.BeginDisabledGroup(IsRequireLoadJsonFile.boolValue);
|
||||
if (GUILayout.Button("Load Setting From JSON File in Resources Folder", boldButtonStyle) ||
|
||||
IsRequireLoadJsonFile.boolValue)
|
||||
{
|
||||
IsRequireLoadJsonFile.boolValue = true;
|
||||
var searchPattern =
|
||||
$"{SpectatorCameraHelper.ATTRIBUTE_FILE_PREFIX_NAME}*.{SpectatorCameraHelper.ATTRIBUTE_FILE_EXTENSION}";
|
||||
|
||||
if (JsonFileList == null)
|
||||
{
|
||||
JsonFileList = new List<string>();
|
||||
}
|
||||
|
||||
JsonFileList.Clear();
|
||||
|
||||
var dir = new DirectoryInfo(Path.Combine(Application.dataPath, "Resources"));
|
||||
var files = dir.GetFiles(searchPattern);
|
||||
foreach (var item in files)
|
||||
{
|
||||
JsonFileList.Add(item.Name);
|
||||
}
|
||||
|
||||
if (JsonFileList.Count == 0)
|
||||
{
|
||||
Debug.Log(
|
||||
"Can't find any JSON file related to the spectator camera setting in the Resources folder.");
|
||||
IsRequireLoadJsonFile.boolValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
if (IsRequireLoadJsonFile.boolValue)
|
||||
{
|
||||
if (GUILayout.Button("Cancel"))
|
||||
{
|
||||
IsRequireLoadJsonFile.boolValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (IsRequireLoadJsonFile.boolValue)
|
||||
{
|
||||
Rect r = EditorGUILayout.BeginVertical();
|
||||
|
||||
JsonFileScrollViewVector = EditorGUILayout.BeginScrollView(JsonFileScrollViewVector,
|
||||
GUILayout.Width(r.width),
|
||||
GUILayout.Height(80));
|
||||
|
||||
for (int i = 0; i < JsonFileList.Count; i++)
|
||||
{
|
||||
if (GUILayout.Button(JsonFileList[i]))
|
||||
{
|
||||
var path = Path.Combine(
|
||||
Path.Combine(Application.dataPath, "Resources"),
|
||||
JsonFileList[i]);
|
||||
Undo.RecordObject(target, $"Load {JsonFileList[i]} setting to {target.name} SpectatorCameraTracker");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.LoadSettingFromJsonFile(path);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
#region Setting related to spectator camera and its frustum show/hide
|
||||
|
||||
EditorGUILayout.LabelField("<b>[ General Setting ]</b>", labelStyle);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Setting of spectator camera layer mask
|
||||
var currentLayerMask =
|
||||
LayerMaskHelper.LayerMaskDrawer.LayerMaskField("Camera Layer Mask", script.LayerMask);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, $"Modified {target.name} SpectatorCameraTracker LayerMask");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.LayerMask = currentLayerMask;
|
||||
}
|
||||
|
||||
// Setting of smooth spectator camera movement
|
||||
EditorGUILayout.PropertyField(IsSmoothCameraMovement,
|
||||
new GUIContent("Enable Smoothing Camera Movement"));
|
||||
if (IsSmoothCameraMovement.boolValue)
|
||||
{
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
EditorGUILayout.LabelField("<b>[ Smooth Camera Movement Speed Setting ]</b>", labelStyle);
|
||||
|
||||
EditorGUILayout.IntSlider(
|
||||
SmoothCameraMovementSpeed,
|
||||
SpectatorCameraHelper.SMOOTH_CAMERA_MOVEMENT_MIN,
|
||||
SpectatorCameraHelper.SMOOTH_CAMERA_MOVEMENT_MAX,
|
||||
"Speed of Smoothing Camera Movement");
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Spectator camera frustum show/hide
|
||||
var currentIsFrustumShowed =
|
||||
EditorGUILayout.Toggle("Enable Camera FOV Frustum", script.IsFrustumShowed);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, $"Modified {target.name} SpectatorCameraTracker IsFrustumShowed");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.IsFrustumShowed = currentIsFrustumShowed;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
#region VerticalFov
|
||||
|
||||
EditorGUILayout.LabelField("<b>[ Vertical FOV Setting ]</b>", labelStyle);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// FOV
|
||||
var currentVerticalFov = EditorGUILayout.Slider(
|
||||
"Vertical FOV",
|
||||
script.VerticalFov,
|
||||
SpectatorCameraHelper.VERTICAL_FOV_MIN,
|
||||
SpectatorCameraHelper.VERTICAL_FOV_MAX);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, $"Modified {target.name} SpectatorCameraTracker VerticalFov");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.VerticalFov = currentVerticalFov;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
#region Setting related to panorama capturing of spectator camera
|
||||
|
||||
// Panorama resolution
|
||||
EditorGUILayout.LabelField("<b>[ Panorama Setting ]</b>", labelStyle);
|
||||
EditorGUILayout.PropertyField(PanoramaResolution, new GUIContent("Resolution"));
|
||||
|
||||
// Panorama output format
|
||||
EditorGUILayout.PropertyField(PanoramaOutputFormat, new GUIContent("Output Format"));
|
||||
|
||||
// Panorama output type
|
||||
EditorGUILayout.PropertyField(PanoramaOutputType, new GUIContent("Output Type"));
|
||||
|
||||
#endregion
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
#region Setting related to frustum
|
||||
|
||||
if (script.IsFrustumShowed)
|
||||
{
|
||||
EditorGUILayout.LabelField("<b>[ Frustum Setting ]</b>", labelStyle);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Count of frustum line
|
||||
var currentFrustumLineCount = (SpectatorCameraHelper.FrustumLineCount)
|
||||
EditorGUILayout.EnumPopup("Frustum Line Total", script.FrustumLineCount);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, $"Modified {target.name} SpectatorCameraTracker FrustumLineCount");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FrustumLineCount = currentFrustumLineCount;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Count of frustum center line
|
||||
var currentFrustumCenterLineCount = (SpectatorCameraHelper.FrustumCenterLineCount)
|
||||
EditorGUILayout.EnumPopup("Frustum Center Line Total", script.FrustumCenterLineCount);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, $"Modified {target.name} SpectatorCameraTracker FrustumCenterLineCount");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FrustumCenterLineCount = currentFrustumCenterLineCount;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Width of frustum line
|
||||
var currentFrustumLineWidth =
|
||||
EditorGUILayout.Slider(
|
||||
"Frustum Line Width",
|
||||
script.FrustumLineWidth,
|
||||
SpectatorCameraHelper.FRUSTUM_LINE_WIDTH_MIN,
|
||||
SpectatorCameraHelper.FRUSTUM_LINE_WIDTH_MAX);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, $"Modified {target.name} SpectatorCameraTracker FrustumLineWidth");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FrustumLineWidth = currentFrustumLineWidth;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Width of frustum center line
|
||||
var currentFrustumCenterLineWidth =
|
||||
EditorGUILayout.Slider(
|
||||
"Frustum Center Line Width",
|
||||
script.FrustumCenterLineWidth,
|
||||
SpectatorCameraHelper.FRUSTUM_CENTER_LINE_WIDTH_MIN,
|
||||
SpectatorCameraHelper.FRUSTUM_CENTER_LINE_WIDTH_MAX);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, $"Modified {target.name} SpectatorCameraTracker FrustumCenterLineWidth");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FrustumCenterLineWidth = currentFrustumCenterLineWidth;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Color of frustum line
|
||||
var currentFrustumLineColor = EditorGUILayout.ColorField(
|
||||
"Frustum Line Color", script.FrustumLineColor);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, $"Modified {target.name} SpectatorCameraTracker FrustumLineColor");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FrustumLineColor = currentFrustumLineColor;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
// Color of frustum center line
|
||||
var currentFrustumCenterLineColor = EditorGUILayout.ColorField(
|
||||
"Frustum Center Line Color",
|
||||
script.FrustumCenterLineColor);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(target, $"Modified {target.name} SpectatorCameraTracker FrustumCenterLineColor");
|
||||
EditorUtility.SetDirty(target);
|
||||
script.FrustumCenterLineColor = currentFrustumCenterLineColor;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("\n");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 523f24465def2a246b2f27dca663a530
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,479 @@
|
||||
// Copyright HTC Corporation All Rights Reserved.
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using VIVE.OpenXR.Toolkits.Spectator.Helper;
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.Spectator
|
||||
{
|
||||
/// <summary>
|
||||
/// Name: SpectatorCameraTracker.cs
|
||||
/// Role: General script
|
||||
/// Responsibility: To implement the spectator camera tracker setting and I/O function
|
||||
/// </summary>
|
||||
public partial class SpectatorCameraTracker : MonoBehaviour, ISpectatorCameraSetting
|
||||
{
|
||||
private const int TryAddTrackerIntervalSecond = 1;
|
||||
|
||||
private SpectatorCameraManager SpectatorCameraManager => SpectatorCameraManager.Instance;
|
||||
public SpectatorCameraHelper.CameraSourceRef CameraSourceRef => SpectatorCameraHelper.CameraSourceRef.Tracker;
|
||||
|
||||
public Vector3 Position
|
||||
{
|
||||
get => transform.position;
|
||||
set => transform.position = value;
|
||||
}
|
||||
|
||||
public Quaternion Rotation
|
||||
{
|
||||
get => transform.rotation;
|
||||
set => transform.rotation = value;
|
||||
}
|
||||
|
||||
[SerializeField] private LayerMask layerMask = SpectatorCameraHelper.LayerMaskDefault;
|
||||
|
||||
public LayerMask LayerMask
|
||||
{
|
||||
get => layerMask;
|
||||
set
|
||||
{
|
||||
if (layerMask == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
layerMask = value;
|
||||
|
||||
if (Application.isPlaying &&
|
||||
SpectatorCameraManager != null &&
|
||||
SpectatorCameraManager.IsCameraSourceAsTracker() &&
|
||||
SpectatorCameraManager.IsFollowTrackerEqualTo(this))
|
||||
{
|
||||
SpectatorCameraManager.SpectatorCameraBased.SpectatorCamera.cullingMask = layerMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[field: SerializeField]
|
||||
public bool IsSmoothCameraMovement { get; set; } = SpectatorCameraHelper.IS_SMOOTH_CAMERA_MOVEMENT_DEFAULT;
|
||||
|
||||
[field: SerializeField]
|
||||
public int SmoothCameraMovementSpeed { get; set; } = SpectatorCameraHelper.SMOOTH_CAMERA_MOVEMENT_SPEED_DEFAULT;
|
||||
|
||||
[SerializeField] private bool isFrustumShowed = SpectatorCameraHelper.IS_FRUSTUM_SHOWED_DEFAULT;
|
||||
|
||||
public bool IsFrustumShowed
|
||||
{
|
||||
get => isFrustumShowed;
|
||||
set
|
||||
{
|
||||
if (isFrustumShowed == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
isFrustumShowed = value;
|
||||
|
||||
if (Application.isPlaying &&
|
||||
SpectatorCameraManager != null &&
|
||||
SpectatorCameraManager.IsCameraSourceAsTracker() &&
|
||||
SpectatorCameraManager.IsFollowTrackerEqualTo(this))
|
||||
{
|
||||
SpectatorCameraManager.SetupFrustum();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private float verticalFov = SpectatorCameraHelper.VERTICAL_FOV_DEFAULT;
|
||||
|
||||
public float VerticalFov
|
||||
{
|
||||
get => verticalFov;
|
||||
set
|
||||
{
|
||||
if (Math.Abs(verticalFov - value) < SpectatorCameraHelper.COMPARE_FLOAT_MEDIUM_THRESHOLD)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
verticalFov = Mathf.Clamp(
|
||||
value,
|
||||
SpectatorCameraHelper.VERTICAL_FOV_MIN,
|
||||
SpectatorCameraHelper.VERTICAL_FOV_MAX);
|
||||
|
||||
if (Application.isPlaying &&
|
||||
SpectatorCameraManager != null &&
|
||||
SpectatorCameraManager.IsCameraSourceAsTracker() &&
|
||||
SpectatorCameraManager.IsFollowTrackerEqualTo(this))
|
||||
{
|
||||
SpectatorCameraManager.SpectatorCameraBased.SpectatorCamera.fieldOfView = verticalFov;
|
||||
SpectatorCameraManager.SetupFrustum();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Panorama properties
|
||||
|
||||
[field: SerializeField]
|
||||
public SpectatorCameraHelper.SpectatorCameraPanoramaResolution PanoramaResolution { get; set; } =
|
||||
SpectatorCameraHelper.PANORAMA_RESOLUTION_DEFAULT;
|
||||
|
||||
[field: SerializeField]
|
||||
public TextureProcessHelper.PictureOutputFormat PanoramaOutputFormat { get; set; } =
|
||||
SpectatorCameraHelper.PANORAMA_OUTPUT_FORMAT_DEFAULT;
|
||||
|
||||
[field: SerializeField]
|
||||
public TextureProcessHelper.PanoramaType PanoramaOutputType { get; set; } =
|
||||
SpectatorCameraHelper.PANORAMA_TYPE_DEFAULT;
|
||||
|
||||
#endregion
|
||||
|
||||
[SerializeField] private SpectatorCameraHelper.FrustumLineCount frustumLineCount =
|
||||
SpectatorCameraHelper.FRUSTUM_LINE_COUNT_DEFAULT;
|
||||
|
||||
public SpectatorCameraHelper.FrustumLineCount FrustumLineCount
|
||||
{
|
||||
get => frustumLineCount;
|
||||
set
|
||||
{
|
||||
if (frustumLineCount == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
frustumLineCount = value;
|
||||
|
||||
if (Application.isPlaying &&
|
||||
SpectatorCameraManager != null &&
|
||||
SpectatorCameraManager.IsCameraSourceAsTracker() &&
|
||||
SpectatorCameraManager.IsFollowTrackerEqualTo(this))
|
||||
{
|
||||
SpectatorCameraManager.SetupFrustumLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private SpectatorCameraHelper.FrustumCenterLineCount frustumCenterLineCount =
|
||||
SpectatorCameraHelper.FRUSTUM_CENTER_LINE_COUNT_DEFAULT;
|
||||
|
||||
public SpectatorCameraHelper.FrustumCenterLineCount FrustumCenterLineCount
|
||||
{
|
||||
get => frustumCenterLineCount;
|
||||
set
|
||||
{
|
||||
if (frustumCenterLineCount == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
frustumCenterLineCount = value;
|
||||
|
||||
if (Application.isPlaying &&
|
||||
SpectatorCameraManager != null &&
|
||||
SpectatorCameraManager.IsCameraSourceAsTracker() &&
|
||||
SpectatorCameraManager.IsFollowTrackerEqualTo(this))
|
||||
{
|
||||
SpectatorCameraManager.SetupFrustumCenterLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private float frustumLineWidth = SpectatorCameraHelper.FRUSTUM_LINE_WIDTH_DEFAULT;
|
||||
|
||||
public float FrustumLineWidth
|
||||
{
|
||||
get => frustumLineWidth;
|
||||
set
|
||||
{
|
||||
if (Math.Abs(frustumLineWidth - value) < SpectatorCameraHelper.COMPARE_FLOAT_SUPER_SMALL_THRESHOLD)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
frustumLineWidth = Mathf.Clamp(
|
||||
value,
|
||||
SpectatorCameraHelper.FRUSTUM_LINE_WIDTH_MIN,
|
||||
SpectatorCameraHelper.FRUSTUM_LINE_WIDTH_MAX);
|
||||
|
||||
if (Application.isPlaying &&
|
||||
SpectatorCameraManager != null &&
|
||||
SpectatorCameraManager.IsCameraSourceAsTracker() &&
|
||||
SpectatorCameraManager.IsFollowTrackerEqualTo(this))
|
||||
{
|
||||
SpectatorCameraManager.SetupFrustumLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private float frustumCenterLineWidth = SpectatorCameraHelper.FRUSTUM_CENTER_LINE_WIDTH_DEFAULT;
|
||||
|
||||
public float FrustumCenterLineWidth
|
||||
{
|
||||
get => frustumCenterLineWidth;
|
||||
set
|
||||
{
|
||||
if (Math.Abs(frustumCenterLineWidth - value) <
|
||||
SpectatorCameraHelper.COMPARE_FLOAT_SUPER_SMALL_THRESHOLD)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
frustumCenterLineWidth = Mathf.Clamp(value, SpectatorCameraHelper.FRUSTUM_CENTER_LINE_WIDTH_MIN,
|
||||
SpectatorCameraHelper.FRUSTUM_CENTER_LINE_WIDTH_MAX);
|
||||
|
||||
if (Application.isPlaying &&
|
||||
SpectatorCameraManager != null &&
|
||||
SpectatorCameraManager.IsCameraSourceAsTracker() &&
|
||||
SpectatorCameraManager.IsFollowTrackerEqualTo(this))
|
||||
{
|
||||
SpectatorCameraManager.SetupFrustumCenterLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private Color frustumLineColor = SpectatorCameraHelper.LineColorDefault;
|
||||
|
||||
public Color FrustumLineColor
|
||||
{
|
||||
get => frustumLineColor;
|
||||
set
|
||||
{
|
||||
if (frustumLineColor == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
frustumLineColor = value;
|
||||
|
||||
if (Application.isPlaying &&
|
||||
SpectatorCameraManager != null &&
|
||||
SpectatorCameraManager.IsCameraSourceAsTracker() &&
|
||||
SpectatorCameraManager.IsFollowTrackerEqualTo(this))
|
||||
{
|
||||
SpectatorCameraManager.SetupFrustumLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private Color frustumCenterLineColor = SpectatorCameraHelper.LineColorDefault;
|
||||
|
||||
public Color FrustumCenterLineColor
|
||||
{
|
||||
get => frustumCenterLineColor;
|
||||
set
|
||||
{
|
||||
if (frustumCenterLineColor == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
frustumCenterLineColor = value;
|
||||
|
||||
if (Application.isPlaying &&
|
||||
SpectatorCameraManager != null &&
|
||||
SpectatorCameraManager.IsCameraSourceAsTracker() &&
|
||||
SpectatorCameraManager.IsFollowTrackerEqualTo(this))
|
||||
{
|
||||
SpectatorCameraManager.SetupFrustumCenterLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetSetting()
|
||||
{
|
||||
LayerMask = SpectatorCameraHelper.LayerMaskDefault;
|
||||
IsSmoothCameraMovement = SpectatorCameraHelper.IS_SMOOTH_CAMERA_MOVEMENT_DEFAULT;
|
||||
SmoothCameraMovementSpeed = SpectatorCameraHelper.SMOOTH_CAMERA_MOVEMENT_SPEED_DEFAULT;
|
||||
IsFrustumShowed = SpectatorCameraHelper.IS_FRUSTUM_SHOWED_DEFAULT;
|
||||
VerticalFov = SpectatorCameraHelper.VERTICAL_FOV_DEFAULT;
|
||||
PanoramaResolution = SpectatorCameraHelper.PANORAMA_RESOLUTION_DEFAULT;
|
||||
PanoramaOutputFormat = SpectatorCameraHelper.PANORAMA_OUTPUT_FORMAT_DEFAULT;
|
||||
PanoramaOutputType = SpectatorCameraHelper.PANORAMA_TYPE_DEFAULT;
|
||||
FrustumLineCount = SpectatorCameraHelper.FRUSTUM_LINE_COUNT_DEFAULT;
|
||||
FrustumCenterLineCount = SpectatorCameraHelper.FRUSTUM_CENTER_LINE_COUNT_DEFAULT;
|
||||
FrustumLineWidth = SpectatorCameraHelper.FRUSTUM_LINE_WIDTH_DEFAULT;
|
||||
FrustumCenterLineWidth = SpectatorCameraHelper.FRUSTUM_CENTER_LINE_WIDTH_DEFAULT;
|
||||
FrustumLineColor = SpectatorCameraHelper.LineColorDefault;
|
||||
FrustumCenterLineColor = SpectatorCameraHelper.LineColorDefault;
|
||||
}
|
||||
|
||||
public void ExportSetting2JsonFile(in SpectatorCameraHelper.AttributeFileLocation attributeFileLocation)
|
||||
{
|
||||
#if !UNITY_EDITOR
|
||||
if (attributeFileLocation is SpectatorCameraHelper.AttributeFileLocation.ResourceFolder)
|
||||
{
|
||||
Debug.LogError("It's not allowed to save setting to resource folder in runtime mode");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
var data = new SpectatorCameraHelper.SpectatorCameraAttribute(
|
||||
CameraSourceRef,
|
||||
Position,
|
||||
Rotation,
|
||||
LayerMask,
|
||||
IsSmoothCameraMovement,
|
||||
SmoothCameraMovementSpeed,
|
||||
IsFrustumShowed,
|
||||
VerticalFov,
|
||||
PanoramaResolution,
|
||||
PanoramaOutputFormat,
|
||||
PanoramaOutputType,
|
||||
FrustumLineCount,
|
||||
FrustumCenterLineCount,
|
||||
FrustumLineWidth,
|
||||
FrustumCenterLineWidth,
|
||||
FrustumLineColor,
|
||||
FrustumCenterLineColor);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (attributeFileLocation is SpectatorCameraHelper.AttributeFileLocation.ResourceFolder)
|
||||
{
|
||||
SpectatorCameraHelper.SaveAttributeData2ResourcesFolder(
|
||||
SceneManager.GetActiveScene().name,
|
||||
gameObject.name,
|
||||
data);
|
||||
}
|
||||
else if (attributeFileLocation is SpectatorCameraHelper.AttributeFileLocation.PersistentFolder)
|
||||
{
|
||||
SpectatorCameraHelper.SaveAttributeData2PersistentFolder(
|
||||
SceneManager.GetActiveScene().name,
|
||||
gameObject.name,
|
||||
data);
|
||||
}
|
||||
#else
|
||||
SpectatorCameraHelper.SaveAttributeData2PersistentFolder(
|
||||
SceneManager.GetActiveScene().name,
|
||||
gameObject.name,
|
||||
data);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void LoadSettingFromJsonFile(in string jsonFilePath)
|
||||
{
|
||||
bool loadSuccess = SpectatorCameraHelper.LoadAttributeFileFromFolder(
|
||||
jsonFilePath,
|
||||
out SpectatorCameraHelper.SpectatorCameraAttribute data);
|
||||
if (loadSuccess)
|
||||
{
|
||||
ApplyData(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"Load setting from {jsonFilePath} file to scene gameObject {gameObject.name} failed.");
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadSettingFromJsonFile(
|
||||
in string sceneName,
|
||||
in string trackerName,
|
||||
in SpectatorCameraHelper.AttributeFileLocation attributeFileLocation)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sceneName) || string.IsNullOrEmpty(trackerName))
|
||||
{
|
||||
Debug.LogError("sceneName or trackerName is null or empty");
|
||||
return;
|
||||
}
|
||||
|
||||
var loadSuccess = false;
|
||||
SpectatorCameraHelper.SpectatorCameraAttribute data = new SpectatorCameraHelper.SpectatorCameraAttribute();
|
||||
if (attributeFileLocation is SpectatorCameraHelper.AttributeFileLocation.ResourceFolder)
|
||||
{
|
||||
loadSuccess = SpectatorCameraHelper.LoadAttributeFileFromResourcesFolder(
|
||||
sceneName,
|
||||
trackerName,
|
||||
out data);
|
||||
}
|
||||
else if (attributeFileLocation is SpectatorCameraHelper.AttributeFileLocation.PersistentFolder)
|
||||
{
|
||||
loadSuccess = SpectatorCameraHelper.LoadAttributeFileFromPersistentFolder(
|
||||
sceneName,
|
||||
trackerName,
|
||||
out data);
|
||||
}
|
||||
|
||||
if (loadSuccess)
|
||||
{
|
||||
ApplyData(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
var fileDirectory = string.Empty;
|
||||
if (attributeFileLocation is SpectatorCameraHelper.AttributeFileLocation.ResourceFolder)
|
||||
{
|
||||
fileDirectory = System.IO.Path.Combine(Application.dataPath, "Resources");
|
||||
}
|
||||
else if (attributeFileLocation is SpectatorCameraHelper.AttributeFileLocation.PersistentFolder)
|
||||
{
|
||||
fileDirectory = Application.persistentDataPath;
|
||||
}
|
||||
|
||||
var fileName =
|
||||
SpectatorCameraHelper.GetSpectatorCameraAttributeFileNamePattern(sceneName, trackerName);
|
||||
|
||||
Debug.Log(
|
||||
$"Load setting from {fileDirectory}/{fileName} file to scene gameObject {gameObject.name} failed.");
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyData(in SpectatorCameraHelper.SpectatorCameraAttribute data)
|
||||
{
|
||||
Transform gameObjectTransform = transform;
|
||||
gameObjectTransform.position = data.position;
|
||||
gameObjectTransform.rotation = data.rotation;
|
||||
|
||||
LayerMask = data.layerMask;
|
||||
IsSmoothCameraMovement = data.isSmoothCameraMovement;
|
||||
SmoothCameraMovementSpeed = data.smoothCameraMovementSpeed;
|
||||
IsFrustumShowed = data.isFrustumShowed;
|
||||
VerticalFov = data.verticalFov;
|
||||
PanoramaResolution = data.panoramaResolution;
|
||||
PanoramaOutputFormat = data.panoramaOutputFormat;
|
||||
PanoramaOutputType = data.panoramaOutputType;
|
||||
FrustumLineCount = data.frustumLineCount;
|
||||
FrustumCenterLineCount = data.frustumCenterLineCount;
|
||||
FrustumLineWidth = data.frustumLineWidth;
|
||||
FrustumCenterLineWidth = data.frustumCenterLineWidth;
|
||||
FrustumLineColor = data.frustumLineColor;
|
||||
FrustumCenterLineColor = data.frustumCenterLineColor;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (SpectatorCameraManager != null)
|
||||
{
|
||||
SpectatorCameraManager.AddSpectatorCameraTracker(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
InvokeRepeating(nameof(AddTracker), TryAddTrackerIntervalSecond, TryAddTrackerIntervalSecond);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (SpectatorCameraManager != null)
|
||||
{
|
||||
SpectatorCameraManager.AddSpectatorCameraTracker(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (SpectatorCameraManager != null)
|
||||
{
|
||||
SpectatorCameraManager.RemoveSpectatorCameraTracker(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddTracker()
|
||||
{
|
||||
if (SpectatorCameraManager != null)
|
||||
{
|
||||
SpectatorCameraManager.AddSpectatorCameraTracker(this);
|
||||
CancelInvoke(nameof(AddTracker));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0b61457a6a405c49b000f7a3ed895bf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user