Initial Commit
This commit is contained in:
8
Assets/Oculus/VR/AudioClips.meta
Normal file
8
Assets/Oculus/VR/AudioClips.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 095d7a3dae7d8ea4cb761651027164ce
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Oculus/VR/AudioClips/sfx_belt_in.wav
LFS
Normal file
BIN
Assets/Oculus/VR/AudioClips/sfx_belt_in.wav
LFS
Normal file
Binary file not shown.
22
Assets/Oculus/VR/AudioClips/sfx_belt_in.wav.meta
Normal file
22
Assets/Oculus/VR/AudioClips/sfx_belt_in.wav.meta
Normal file
@@ -0,0 +1,22 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d716392289ac6764994885f5821f7d7b
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 6
|
||||
defaultSettings:
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
preloadAudioData: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
5
Assets/Oculus/VR/Editor.meta
Normal file
5
Assets/Oculus/VR/Editor.meta
Normal file
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76c19abd24bec62459b5f0d26fdd9a85
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
21
Assets/Oculus/VR/Editor/AndroidManifest.OVRSubmission.xml
Normal file
21
Assets/Oculus/VR/Editor/AndroidManifest.OVRSubmission.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:installLocation="auto">
|
||||
<application
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/app_icon">
|
||||
<activity
|
||||
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
|
||||
android:configChanges="locale|fontScale|keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode"
|
||||
android:launchMode="singleTask"
|
||||
android:name="com.unity3d.player.UnityPlayerActivity"
|
||||
android:excludeFromRecents="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="false" />
|
||||
<meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a16cc136accf1f42bdc6f71f94b50ac
|
||||
timeCreated: 1475710636
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
262
Assets/Oculus/VR/Editor/OVRADBTool.cs
Normal file
262
Assets/Oculus/VR/Editor/OVRADBTool.cs
Normal file
@@ -0,0 +1,262 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
public class OVRADBTool
|
||||
{
|
||||
public bool isReady;
|
||||
|
||||
public string androidSdkRoot;
|
||||
public string androidPlatformToolsPath;
|
||||
public string adbPath;
|
||||
|
||||
public OVRADBTool(string androidSdkRoot)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(androidSdkRoot))
|
||||
{
|
||||
this.androidSdkRoot = androidSdkRoot;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.androidSdkRoot = String.Empty;
|
||||
}
|
||||
|
||||
if (this.androidSdkRoot.EndsWith("\\") || this.androidSdkRoot.EndsWith("/"))
|
||||
{
|
||||
this.androidSdkRoot = this.androidSdkRoot.Remove(this.androidSdkRoot.Length - 1);
|
||||
}
|
||||
androidPlatformToolsPath = Path.Combine(this.androidSdkRoot, "platform-tools");
|
||||
adbPath = Path.Combine(androidPlatformToolsPath, "adb.exe");
|
||||
isReady = File.Exists(adbPath);
|
||||
}
|
||||
|
||||
public static bool IsAndroidSdkRootValid(string androidSdkRoot)
|
||||
{
|
||||
OVRADBTool tool = new OVRADBTool(androidSdkRoot);
|
||||
return tool.isReady;
|
||||
}
|
||||
|
||||
public delegate void WaitingProcessToExitCallback();
|
||||
|
||||
public int StartServer(WaitingProcessToExitCallback waitingProcessToExitCallback)
|
||||
{
|
||||
string outputString;
|
||||
string errorString;
|
||||
|
||||
int exitCode = RunCommand(new string[] { "start-server" }, waitingProcessToExitCallback, out outputString, out errorString);
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
public int KillServer(WaitingProcessToExitCallback waitingProcessToExitCallback)
|
||||
{
|
||||
string outputString;
|
||||
string errorString;
|
||||
|
||||
int exitCode = RunCommand(new string[] { "kill-server" }, waitingProcessToExitCallback, out outputString, out errorString);
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
public int ForwardPort(int port, WaitingProcessToExitCallback waitingProcessToExitCallback)
|
||||
{
|
||||
string outputString;
|
||||
string errorString;
|
||||
|
||||
string portString = string.Format("tcp:{0}", port);
|
||||
|
||||
int exitCode = RunCommand(new string[] { "forward", portString, portString }, waitingProcessToExitCallback, out outputString, out errorString);
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
public int ReleasePort(int port, WaitingProcessToExitCallback waitingProcessToExitCallback)
|
||||
{
|
||||
string outputString;
|
||||
string errorString;
|
||||
|
||||
string portString = string.Format("tcp:{0}", port);
|
||||
|
||||
int exitCode = RunCommand(new string[] { "forward", "--remove", portString }, waitingProcessToExitCallback, out outputString, out errorString);
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
public List<string> GetDevices()
|
||||
{
|
||||
string outputString;
|
||||
string errorString;
|
||||
|
||||
RunCommand(new string[] { "devices" }, null, out outputString, out errorString);
|
||||
string[] devices = outputString.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
List<string> deviceList = new List<string>(devices);
|
||||
deviceList.RemoveAt(0);
|
||||
|
||||
for(int i = 0; i < deviceList.Count; i++)
|
||||
{
|
||||
string deviceName = deviceList[i];
|
||||
int index = deviceName.IndexOf('\t');
|
||||
if (index >= 0)
|
||||
deviceList[i] = deviceName.Substring(0, index);
|
||||
else
|
||||
deviceList[i] = "";
|
||||
|
||||
}
|
||||
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
private StringBuilder outputStringBuilder = null;
|
||||
private StringBuilder errorStringBuilder = null;
|
||||
|
||||
public int RunCommand(string[] arguments, WaitingProcessToExitCallback waitingProcessToExitCallback, out string outputString, out string errorString)
|
||||
{
|
||||
int exitCode = -1;
|
||||
|
||||
if (!isReady)
|
||||
{
|
||||
Debug.LogWarning("OVRADBTool not ready");
|
||||
outputString = string.Empty;
|
||||
errorString = "OVRADBTool not ready";
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
string args = string.Join(" ", arguments);
|
||||
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo(adbPath, args);
|
||||
startInfo.WorkingDirectory = androidSdkRoot;
|
||||
startInfo.CreateNoWindow = true;
|
||||
startInfo.UseShellExecute = false;
|
||||
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
startInfo.RedirectStandardOutput = true;
|
||||
startInfo.RedirectStandardError = true;
|
||||
|
||||
outputStringBuilder = new StringBuilder("");
|
||||
errorStringBuilder = new StringBuilder("");
|
||||
|
||||
Process process = Process.Start(startInfo);
|
||||
process.OutputDataReceived += new DataReceivedEventHandler(OutputDataReceivedHandler);
|
||||
process.ErrorDataReceived += new DataReceivedEventHandler(ErrorDataReceivedHandler);
|
||||
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
|
||||
try
|
||||
{
|
||||
do
|
||||
{
|
||||
if (waitingProcessToExitCallback != null)
|
||||
{
|
||||
waitingProcessToExitCallback();
|
||||
}
|
||||
} while (!process.WaitForExit(100));
|
||||
|
||||
process.WaitForExit();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarningFormat("[OVRADBTool.RunCommand] exception {0}", e.Message);
|
||||
}
|
||||
|
||||
exitCode = process.ExitCode;
|
||||
|
||||
process.Close();
|
||||
|
||||
outputString = outputStringBuilder.ToString();
|
||||
errorString = errorStringBuilder.ToString();
|
||||
|
||||
outputStringBuilder = null;
|
||||
errorStringBuilder = null;
|
||||
|
||||
if (!string.IsNullOrEmpty(errorString))
|
||||
{
|
||||
if (errorString.Contains("Warning"))
|
||||
{
|
||||
UnityEngine.Debug.LogWarning("OVRADBTool " + errorString);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.LogError("OVRADBTool " + errorString);
|
||||
}
|
||||
}
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
public Process RunCommandAsync(string[] arguments, DataReceivedEventHandler outputDataRecievedHandler)
|
||||
{
|
||||
if (!isReady)
|
||||
{
|
||||
Debug.LogWarning("OVRADBTool not ready");
|
||||
return null;
|
||||
}
|
||||
|
||||
string args = string.Join(" ", arguments);
|
||||
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo(adbPath, args);
|
||||
startInfo.WorkingDirectory = androidSdkRoot;
|
||||
startInfo.CreateNoWindow = true;
|
||||
startInfo.UseShellExecute = false;
|
||||
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
startInfo.RedirectStandardOutput = true;
|
||||
startInfo.RedirectStandardError = true;
|
||||
|
||||
Process process = Process.Start(startInfo);
|
||||
if (outputDataRecievedHandler != null)
|
||||
{
|
||||
process.OutputDataReceived += new DataReceivedEventHandler(outputDataRecievedHandler);
|
||||
}
|
||||
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
|
||||
return process;
|
||||
}
|
||||
|
||||
private void OutputDataReceivedHandler(object sendingProcess, DataReceivedEventArgs args)
|
||||
{
|
||||
// Collect the sort command output.
|
||||
if (!string.IsNullOrEmpty(args.Data))
|
||||
{
|
||||
// Add the text to the collected output.
|
||||
outputStringBuilder.Append(args.Data);
|
||||
outputStringBuilder.Append(Environment.NewLine);
|
||||
}
|
||||
}
|
||||
|
||||
private void ErrorDataReceivedHandler(object sendingProcess, DataReceivedEventArgs args)
|
||||
{
|
||||
// Collect the sort command output.
|
||||
if (!string.IsNullOrEmpty(args.Data))
|
||||
{
|
||||
// Add the text to the collected output.
|
||||
errorStringBuilder.Append(args.Data);
|
||||
errorStringBuilder.Append(Environment.NewLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Oculus/VR/Editor/OVRADBTool.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRADBTool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41c2cab7d83278a4f8f44a44b694770f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
669
Assets/Oculus/VR/Editor/OVRBuild.cs
Normal file
669
Assets/Oculus/VR/Editor/OVRBuild.cs
Normal file
@@ -0,0 +1,669 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
#if USING_XR_MANAGEMENT && USING_XR_SDK_OCULUS
|
||||
#define USING_XR_SDK
|
||||
#endif
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
#define REQUIRES_XR_SDK
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
/// <summary>
|
||||
/// Allows Oculus to build apps from the command line.
|
||||
/// </summary>
|
||||
partial class OculusBuildApp : EditorWindow
|
||||
{
|
||||
static void SetPCTarget()
|
||||
{
|
||||
if (EditorUserBuildSettings.activeBuildTarget != BuildTarget.StandaloneWindows)
|
||||
{
|
||||
EditorUserBuildSettings.SwitchActiveBuildTarget (BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows);
|
||||
}
|
||||
#if !USING_XR_SDK && !REQUIRES_XR_SDK
|
||||
UnityEditorInternal.VR.VREditor.SetVREnabledOnTargetGroup(BuildTargetGroup.Standalone, true);
|
||||
PlayerSettings.virtualRealitySupported = true;
|
||||
#endif
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
static void SetAndroidTarget()
|
||||
{
|
||||
EditorUserBuildSettings.androidBuildSubtarget = MobileTextureSubtarget.ASTC;
|
||||
EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle;
|
||||
|
||||
if (EditorUserBuildSettings.activeBuildTarget != BuildTarget.Android)
|
||||
{
|
||||
EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Android, BuildTarget.Android);
|
||||
}
|
||||
|
||||
#if !USING_XR_SDK && !REQUIRES_XR_SDK
|
||||
UnityEditorInternal.VR.VREditor.SetVREnabledOnTargetGroup(BuildTargetGroup.Standalone, true);
|
||||
PlayerSettings.virtualRealitySupported = true;
|
||||
#endif
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR_WIN && UNITY_ANDROID
|
||||
// Build setting constants
|
||||
const string REMOTE_APK_PATH = "/data/local/tmp";
|
||||
const float USB_TRANSFER_SPEED_THRES = 25.0f;
|
||||
const float USB_3_TRANSFER_SPEED = 32.0f;
|
||||
const int NUM_BUILD_AND_RUN_STEPS = 9;
|
||||
const int BYTES_TO_MEGABYTES = 1048576;
|
||||
|
||||
// Progress bar variables
|
||||
static int totalBuildSteps;
|
||||
static int currentStep;
|
||||
static string progressMessage;
|
||||
|
||||
// Build setting varaibles
|
||||
static string gradlePath;
|
||||
static string jdkPath;
|
||||
static string androidSdkPath;
|
||||
static string applicationIdentifier;
|
||||
static string productName;
|
||||
static string dataPath;
|
||||
|
||||
static string gradleTempExport;
|
||||
static string gradleExport;
|
||||
static bool showCancel;
|
||||
static bool buildFailed;
|
||||
|
||||
static double totalBuildTime;
|
||||
|
||||
static DirectorySyncer.CancellationTokenSource syncCancelToken;
|
||||
static Process gradleBuildProcess;
|
||||
static Thread buildThread;
|
||||
|
||||
static bool? apkOutputSuccessful;
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
// Fix progress bar window size
|
||||
minSize = new Vector2(500, 170);
|
||||
maxSize = new Vector2(500, 170);
|
||||
|
||||
// Show progress bar
|
||||
Rect progressRect = EditorGUILayout.BeginVertical();
|
||||
progressRect.height = 25.0f;
|
||||
float progress = currentStep / (float)totalBuildSteps;
|
||||
EditorGUI.ProgressBar(progressRect, progress, progressMessage);
|
||||
|
||||
// Show cancel button only after Unity export has finished.
|
||||
if (showCancel)
|
||||
{
|
||||
GUIContent btnTxt = new GUIContent("Cancel");
|
||||
var rt = GUILayoutUtility.GetRect(btnTxt, GUI.skin.button, GUILayout.ExpandWidth(false));
|
||||
rt.center = new Vector2(EditorGUIUtility.currentViewWidth / 2, progressRect.height * 2);
|
||||
if (GUI.Button(rt, btnTxt, GUI.skin.button))
|
||||
{
|
||||
CancelBuild();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
// Close window if progress has completed or Unity export failed
|
||||
if (progress >= 1.0f || buildFailed)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
// Force window update if not in focus to ensure progress bar still updates
|
||||
var window = EditorWindow.focusedWindow;
|
||||
if (window != null && window.ToString().Contains("OculusBuildApp"))
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void CancelBuild()
|
||||
{
|
||||
SetProgressBarMessage("Canceling . . .");
|
||||
|
||||
if (syncCancelToken != null)
|
||||
{
|
||||
syncCancelToken.Cancel();
|
||||
}
|
||||
|
||||
if (apkOutputSuccessful.HasValue && apkOutputSuccessful.Value)
|
||||
{
|
||||
buildThread.Abort();
|
||||
buildFailed = true;
|
||||
}
|
||||
|
||||
if (gradleBuildProcess != null && !gradleBuildProcess.HasExited)
|
||||
{
|
||||
var cancelThread = new Thread(delegate ()
|
||||
{
|
||||
CancelGradleBuild();
|
||||
});
|
||||
cancelThread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
void CancelGradleBuild()
|
||||
{
|
||||
Process cancelGradleProcess = new Process();
|
||||
string arguments = "-Xmx1024m -classpath \"" + gradlePath +
|
||||
"\" org.gradle.launcher.GradleMain --stop";
|
||||
var processInfo = new System.Diagnostics.ProcessStartInfo
|
||||
{
|
||||
WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal,
|
||||
FileName = jdkPath,
|
||||
Arguments = arguments,
|
||||
RedirectStandardInput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardError = true,
|
||||
RedirectStandardOutput = true,
|
||||
};
|
||||
|
||||
cancelGradleProcess.StartInfo = processInfo;
|
||||
cancelGradleProcess.EnableRaisingEvents = true;
|
||||
|
||||
cancelGradleProcess.OutputDataReceived += new DataReceivedEventHandler(
|
||||
(s, e) =>
|
||||
{
|
||||
if (e != null && e.Data != null && e.Data.Length != 0)
|
||||
{
|
||||
UnityEngine.Debug.LogFormat("Gradle: {0}", e.Data);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
apkOutputSuccessful = false;
|
||||
|
||||
cancelGradleProcess.Start();
|
||||
cancelGradleProcess.BeginOutputReadLine();
|
||||
cancelGradleProcess.WaitForExit();
|
||||
|
||||
buildFailed = true;
|
||||
}
|
||||
|
||||
[MenuItem("Oculus/OVR Build/OVR Build APK And Run %k", false, 20)]
|
||||
static void StartBuildAndRun()
|
||||
{
|
||||
EditorWindow.GetWindow(typeof(OculusBuildApp));
|
||||
|
||||
showCancel = false;
|
||||
buildFailed = false;
|
||||
totalBuildTime = 0;
|
||||
|
||||
InitializeProgressBar(NUM_BUILD_AND_RUN_STEPS);
|
||||
IncrementProgressBar("Exporting Unity Project . . .");
|
||||
|
||||
OVRPlugin.SetDeveloperMode(OVRPlugin.Bool.True);
|
||||
OVRPlugin.AddCustomMetadata("build_type", "ovr_build_and_run");
|
||||
|
||||
if (!CheckADBDevices())
|
||||
{
|
||||
buildFailed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Record OVR Build and Run start event
|
||||
OVRPlugin.SendEvent("ovr_build_and_run_start", "", "ovrbuild");
|
||||
|
||||
apkOutputSuccessful = null;
|
||||
syncCancelToken = null;
|
||||
gradleBuildProcess = null;
|
||||
|
||||
UnityEngine.Debug.Log("OVRBuild: Starting Unity build ...");
|
||||
|
||||
SetupDirectories();
|
||||
|
||||
// 1. Get scenes to build in Unity, and export gradle project
|
||||
var buildResult = UnityBuildPlayer();
|
||||
|
||||
if (buildResult.summary.result == UnityEditor.Build.Reporting.BuildResult.Succeeded)
|
||||
{
|
||||
foreach (var step in buildResult.steps)
|
||||
{
|
||||
// Only log top level build steps & specific nested steps to reduce the number of events sent
|
||||
if (step.depth == 1 ||
|
||||
(step.name.StartsWith("Packaging assets") && step.name.EndsWith(".assets")) ||
|
||||
step.name.Equals("Managed Stripping: (Mono)") ||
|
||||
step.name.Equals("Splitting assets") ||
|
||||
step.name.Equals("IL2CPP") ||
|
||||
step.name.Equals("Exporting project")
|
||||
)
|
||||
{
|
||||
OVRPlugin.SendEvent($"build_step_unity_build_player {step.name}", step.duration.TotalSeconds.ToString(), "ovrbuild");
|
||||
}
|
||||
}
|
||||
|
||||
OVRPlugin.SendEvent("build_step_unity_export", buildResult.summary.totalTime.TotalSeconds.ToString(), "ovrbuild");
|
||||
totalBuildTime += buildResult.summary.totalTime.TotalSeconds;
|
||||
|
||||
// Set static variables so build thread has updated data
|
||||
showCancel = true;
|
||||
gradlePath = OVRConfig.Instance.GetGradlePath();
|
||||
jdkPath = OVRConfig.Instance.GetJDKPath();
|
||||
androidSdkPath = OVRConfig.Instance.GetAndroidSDKPath();
|
||||
applicationIdentifier = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android);
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
productName = "launcher";
|
||||
#else
|
||||
productName = Application.productName;
|
||||
#endif
|
||||
dataPath = Application.dataPath;
|
||||
|
||||
buildThread = new Thread(delegate ()
|
||||
{
|
||||
OVRBuildRun();
|
||||
});
|
||||
buildThread.Start();
|
||||
return;
|
||||
}
|
||||
else if (buildResult.summary.result == UnityEditor.Build.Reporting.BuildResult.Cancelled)
|
||||
{
|
||||
UnityEngine.Debug.Log("Build cancelled.");
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.Log("Build failed.");
|
||||
}
|
||||
buildFailed = true;
|
||||
}
|
||||
|
||||
private static UnityEditor.Build.Reporting.BuildReport UnityBuildPlayer()
|
||||
{
|
||||
var sceneList = GetScenesToBuild();
|
||||
var buildPlayerOptions = new BuildPlayerOptions
|
||||
{
|
||||
scenes = sceneList.ToArray(),
|
||||
locationPathName = gradleTempExport,
|
||||
target = BuildTarget.Android,
|
||||
options = BuildOptions.AcceptExternalModificationsToPlayer |
|
||||
BuildOptions.Development |
|
||||
BuildOptions.AllowDebugging
|
||||
};
|
||||
|
||||
var buildResult = BuildPipeline.BuildPlayer(buildPlayerOptions);
|
||||
|
||||
UnityEngine.Debug.Log(UnityBuildPlayerSummary(buildResult));
|
||||
|
||||
return buildResult;
|
||||
}
|
||||
|
||||
private static string UnityBuildPlayerSummary(UnityEditor.Build.Reporting.BuildReport report)
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
|
||||
sb.Append($"Unity Build Player: Build {report.summary.result} ({report.summary.totalSize} bytes) in {report.summary.totalTime.TotalSeconds:0.00}s");
|
||||
|
||||
foreach (var step in report.steps)
|
||||
{
|
||||
sb.AppendLine();
|
||||
if (step.depth > 0)
|
||||
{
|
||||
sb.Append(new String('-', step.depth));
|
||||
sb.Append(' ');
|
||||
}
|
||||
sb.Append($"{step.name}: {step.duration:g}");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static void OVRBuildRun()
|
||||
{
|
||||
// 2. Process gradle project
|
||||
IncrementProgressBar("Processing gradle project . . .");
|
||||
if (ProcessGradleProject())
|
||||
{
|
||||
// 3. Build gradle project
|
||||
IncrementProgressBar("Starting gradle build . . .");
|
||||
if (BuildGradleProject())
|
||||
{
|
||||
OVRPlugin.SendEvent("build_complete", totalBuildTime.ToString(), "ovrbuild");
|
||||
// 4. Deploy and run
|
||||
if (DeployAPK())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
buildFailed = true;
|
||||
}
|
||||
|
||||
private static bool BuildGradleProject()
|
||||
{
|
||||
gradleBuildProcess = new Process();
|
||||
string arguments = "-Xmx4096m -classpath \"" + gradlePath +
|
||||
"\" org.gradle.launcher.GradleMain assembleDebug -x validateSigningDebug --profile";
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
var gradleProjectPath = gradleExport;
|
||||
#else
|
||||
var gradleProjectPath = Path.Combine(gradleExport, productName);
|
||||
#endif
|
||||
|
||||
var processInfo = new System.Diagnostics.ProcessStartInfo
|
||||
{
|
||||
WorkingDirectory = gradleProjectPath,
|
||||
WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal,
|
||||
FileName = jdkPath,
|
||||
Arguments = arguments,
|
||||
RedirectStandardInput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardError = true,
|
||||
RedirectStandardOutput = true,
|
||||
};
|
||||
|
||||
gradleBuildProcess.StartInfo = processInfo;
|
||||
gradleBuildProcess.EnableRaisingEvents = true;
|
||||
|
||||
DateTime gradleStartTime = System.DateTime.Now;
|
||||
DateTime gradleEndTime = System.DateTime.MinValue;
|
||||
|
||||
gradleBuildProcess.Exited += new System.EventHandler(
|
||||
(s, e) =>
|
||||
{
|
||||
UnityEngine.Debug.Log("Gradle: Exited");
|
||||
}
|
||||
);
|
||||
|
||||
gradleBuildProcess.OutputDataReceived += new DataReceivedEventHandler(
|
||||
(s, e) =>
|
||||
{
|
||||
if (e != null && e.Data != null &&
|
||||
e.Data.Length != 0 &&
|
||||
(e.Data.Contains("BUILD") || e.Data.StartsWith("See the profiling report at:")))
|
||||
{
|
||||
UnityEngine.Debug.LogFormat("Gradle: {0}", e.Data);
|
||||
if (e.Data.Contains("SUCCESSFUL"))
|
||||
{
|
||||
UnityEngine.Debug.LogFormat("APK Build Completed: {0}",
|
||||
Path.Combine(Path.Combine(gradleProjectPath, "build\\outputs\\apk\\debug"), productName + "-debug.apk").Replace("/", "\\"));
|
||||
if (!apkOutputSuccessful.HasValue)
|
||||
{
|
||||
apkOutputSuccessful = true;
|
||||
}
|
||||
gradleEndTime = System.DateTime.Now;
|
||||
}
|
||||
else if (e.Data.Contains("FAILED"))
|
||||
{
|
||||
apkOutputSuccessful = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
gradleBuildProcess.ErrorDataReceived += new DataReceivedEventHandler(
|
||||
(s, e) =>
|
||||
{
|
||||
if (e != null && e.Data != null &&
|
||||
e.Data.Length != 0)
|
||||
{
|
||||
UnityEngine.Debug.LogErrorFormat("Gradle: {0}", e.Data);
|
||||
}
|
||||
apkOutputSuccessful = false;
|
||||
}
|
||||
);
|
||||
|
||||
gradleBuildProcess.Start();
|
||||
gradleBuildProcess.BeginOutputReadLine();
|
||||
IncrementProgressBar("Building gradle project . . .");
|
||||
|
||||
gradleBuildProcess.WaitForExit();
|
||||
|
||||
// Add a timeout for if gradle unexpectedlly exits or errors out
|
||||
Stopwatch timeout = new Stopwatch();
|
||||
timeout.Start();
|
||||
while (apkOutputSuccessful == null)
|
||||
{
|
||||
if (timeout.ElapsedMilliseconds > 5000)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Gradle has exited unexpectedly.");
|
||||
apkOutputSuccessful = false;
|
||||
}
|
||||
System.Threading.Thread.Sleep(100);
|
||||
}
|
||||
|
||||
// Record time it takes to build gradle project only if we had a successful build
|
||||
double gradleTime = (gradleEndTime - gradleStartTime).TotalSeconds;
|
||||
if (gradleTime > 0)
|
||||
{
|
||||
OVRPlugin.SendEvent("build_step_building_gradle_project", gradleTime.ToString(), "ovrbuild");
|
||||
totalBuildTime += gradleTime;
|
||||
}
|
||||
|
||||
return apkOutputSuccessful.HasValue && apkOutputSuccessful.Value;
|
||||
}
|
||||
|
||||
private static bool ProcessGradleProject()
|
||||
{
|
||||
DateTime syncStartTime = System.DateTime.Now;
|
||||
DateTime syncEndTime = System.DateTime.MinValue;
|
||||
|
||||
try
|
||||
{
|
||||
var ps = System.Text.RegularExpressions.Regex.Escape("" + Path.DirectorySeparatorChar);
|
||||
// ignore files .gradle/** build/** foo/.gradle/** and bar/build/**
|
||||
var ignorePattern = string.Format("^([^{0}]+{0})?(\\.gradle|build){0}", ps);
|
||||
|
||||
var syncer = new DirectorySyncer(gradleTempExport,
|
||||
gradleExport, ignorePattern);
|
||||
|
||||
syncCancelToken = new DirectorySyncer.CancellationTokenSource();
|
||||
var syncResult = syncer.Synchronize(syncCancelToken.Token);
|
||||
syncEndTime = System.DateTime.Now;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.Log("OVRBuild: Processing gradle project failed with exception: " +
|
||||
e.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (syncCancelToken.IsCancellationRequested)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Record time it takes to sync gradle projects only if the sync was successful
|
||||
double syncTime = (syncEndTime - syncStartTime).TotalSeconds;
|
||||
if (syncTime > 0)
|
||||
{
|
||||
OVRPlugin.SendEvent("build_step_sync_gradle_project", syncTime.ToString(), "ovrbuild");
|
||||
totalBuildTime += syncTime;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static List<string> GetScenesToBuild()
|
||||
{
|
||||
var sceneList = new List<string>();
|
||||
foreach (var scene in EditorBuildSettings.scenes)
|
||||
{
|
||||
// Enumerate scenes in project and check if scene is enabled to build
|
||||
if (scene.enabled)
|
||||
{
|
||||
sceneList.Add(scene.path);
|
||||
}
|
||||
}
|
||||
return sceneList;
|
||||
}
|
||||
|
||||
public static bool DeployAPK()
|
||||
{
|
||||
// Create new instance of ADB Tool
|
||||
var adbTool = new OVRADBTool(androidSdkPath);
|
||||
|
||||
if (adbTool.isReady)
|
||||
{
|
||||
string apkPathLocal;
|
||||
string gradleExportFolder = Path.Combine(Path.Combine(gradleExport, productName), "build\\outputs\\apk\\debug");
|
||||
|
||||
// Check to see if gradle output directory exists
|
||||
gradleExportFolder = gradleExportFolder.Replace("/", "\\");
|
||||
if (!Directory.Exists(gradleExportFolder))
|
||||
{
|
||||
UnityEngine.Debug.LogError("Could not find the gradle project at the expected path: " + gradleExportFolder);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Search for output APK in gradle output directory
|
||||
apkPathLocal = Path.Combine(gradleExportFolder, productName + "-debug.apk");
|
||||
if (!System.IO.File.Exists(apkPathLocal))
|
||||
{
|
||||
UnityEngine.Debug.LogError(string.Format("Could not find {0} in the gradle project.", productName + "-debug.apk"));
|
||||
return false;
|
||||
}
|
||||
|
||||
string output, error;
|
||||
DateTime timerStart;
|
||||
|
||||
// Ensure that the Oculus temp directory is on the device by making it
|
||||
IncrementProgressBar("Making Temp directory on device");
|
||||
string[] mkdirCommand = { "-d shell", "mkdir -p", REMOTE_APK_PATH };
|
||||
if (adbTool.RunCommand(mkdirCommand, null, out output, out error) != 0) return false;
|
||||
|
||||
// Push APK to device, also time how long it takes
|
||||
timerStart = System.DateTime.Now;
|
||||
IncrementProgressBar("Pushing APK to device . . .");
|
||||
string[] pushCommand = { "-d push", "\"" + apkPathLocal + "\"", REMOTE_APK_PATH };
|
||||
if (adbTool.RunCommand(pushCommand, null, out output, out error) != 0) return false;
|
||||
|
||||
// Calculate the transfer speed and determine if user is using USB 2.0 or 3.0
|
||||
TimeSpan pushTime = System.DateTime.Now - timerStart;
|
||||
FileInfo apkInfo = new System.IO.FileInfo(apkPathLocal);
|
||||
double transferSpeed = (apkInfo.Length / pushTime.TotalSeconds) / BYTES_TO_MEGABYTES;
|
||||
bool informLog = transferSpeed < USB_TRANSFER_SPEED_THRES;
|
||||
UnityEngine.Debug.Log("OVRADBTool: Push Success");
|
||||
|
||||
// Install the APK package on the device
|
||||
IncrementProgressBar("Installing APK . . .");
|
||||
string apkPath = REMOTE_APK_PATH + "/" + productName + "-debug.apk";
|
||||
apkPath = apkPath.Replace(" ", "\\ ");
|
||||
string[] installCommand = { "-d shell", "pm install -r", apkPath };
|
||||
|
||||
timerStart = System.DateTime.Now;
|
||||
if (adbTool.RunCommand(installCommand, null, out output, out error) != 0) return false;
|
||||
TimeSpan installTime = System.DateTime.Now - timerStart;
|
||||
UnityEngine.Debug.Log("OVRADBTool: Install Success");
|
||||
|
||||
// Start the application on the device
|
||||
IncrementProgressBar("Launching application on device . . .");
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
string playerActivityName = "\"" + applicationIdentifier + "/com.unity3d.player.UnityPlayerActivity\"";
|
||||
#else
|
||||
string playerActivityName = "\"" + applicationIdentifier + "/" + applicationIdentifier + ".UnityPlayerActivity\"";
|
||||
#endif
|
||||
string[] appStartCommand = { "-d shell", "am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -S -f 0x10200000 -n", playerActivityName };
|
||||
if (adbTool.RunCommand(appStartCommand, null, out output, out error) != 0) return false;
|
||||
UnityEngine.Debug.Log("OVRADBTool: Application Start Success");
|
||||
|
||||
// Send back metrics on push and install steps
|
||||
OVRPlugin.AddCustomMetadata("transfer_speed", transferSpeed.ToString());
|
||||
OVRPlugin.SendEvent("build_step_push_apk", pushTime.TotalSeconds.ToString(), "ovrbuild");
|
||||
OVRPlugin.SendEvent("build_step_install_apk", installTime.TotalSeconds.ToString(), "ovrbuild");
|
||||
|
||||
IncrementProgressBar("Success!");
|
||||
|
||||
// If the user is using a USB 2.0 cable, inform them about improved transfer speeds and estimate time saved
|
||||
if (informLog)
|
||||
{
|
||||
var usb3Time = apkInfo.Length / (USB_3_TRANSFER_SPEED * BYTES_TO_MEGABYTES);
|
||||
UnityEngine.Debug.Log(string.Format("OVRBuild has detected slow transfer speeds. A USB 3.0 cable is recommended to reduce the time it takes to deploy your project by approximatly {0:0.0} seconds", pushTime.TotalSeconds - usb3Time));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.LogError("Could not find the ADB executable in the specified Android SDK directory.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool CheckADBDevices()
|
||||
{
|
||||
// Check if there are any ADB devices connected before starting the build process
|
||||
var adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath());
|
||||
if (adbTool.isReady)
|
||||
{
|
||||
List<string> devices = adbTool.GetDevices();
|
||||
if (devices.Count == 0)
|
||||
{
|
||||
OVRPlugin.SendEvent("no_adb_devices", "", "ovrbuild");
|
||||
UnityEngine.Debug.LogError("No ADB devices connected. Cannot perform OVR Build and Run.");
|
||||
return false;
|
||||
}
|
||||
else if(devices.Count > 1)
|
||||
{
|
||||
OVRPlugin.SendEvent("multiple_adb_devices", "", "ovrbuild");
|
||||
UnityEngine.Debug.LogError("Multiple ADB devices connected. Cannot perform OVR Build and Run.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OVRPlugin.SendEvent("ovr_adbtool_initialize_failure", "", "ovrbuild");
|
||||
UnityEngine.Debug.LogError("OVR ADB Tool failed to initialize. Check the Android SDK path in [Edit -> Preferences -> External Tools]");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void SetupDirectories()
|
||||
{
|
||||
gradleTempExport = Path.Combine(Path.Combine(Application.dataPath, "../Temp"), "OVRGradleTempExport");
|
||||
gradleExport = Path.Combine(Path.Combine(Application.dataPath, "../Temp"), "OVRGradleExport");
|
||||
if (!Directory.Exists(gradleExport))
|
||||
{
|
||||
Directory.CreateDirectory(gradleExport);
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitializeProgressBar(int stepCount)
|
||||
{
|
||||
currentStep = 0;
|
||||
totalBuildSteps = stepCount;
|
||||
}
|
||||
|
||||
private static void IncrementProgressBar(string message)
|
||||
{
|
||||
currentStep++;
|
||||
progressMessage = message;
|
||||
UnityEngine.Debug.Log("OVRBuild: " + message);
|
||||
}
|
||||
|
||||
private static void SetProgressBarMessage(string message)
|
||||
{
|
||||
progressMessage = message;
|
||||
UnityEngine.Debug.Log("OVRBuild: " + message);
|
||||
}
|
||||
#endif //UNITY_EDITOR_WIN && UNITY_ANDROID
|
||||
}
|
||||
8
Assets/Oculus/VR/Editor/OVRBuild.cs.meta
Normal file
8
Assets/Oculus/VR/Editor/OVRBuild.cs.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fef522d0247215a43be6b1a8819bd940
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
626
Assets/Oculus/VR/Editor/OVRBundleManager.cs
Normal file
626
Assets/Oculus/VR/Editor/OVRBundleManager.cs
Normal file
@@ -0,0 +1,626 @@
|
||||
#if UNITY_EDITOR_WIN && UNITY_ANDROID
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build.Reporting;
|
||||
|
||||
public class OVRBundleManager
|
||||
{
|
||||
public const string TRANSITION_APK_VERSION_NAME = "OVRTransitionAPKVersion";
|
||||
private const int BUNDLE_CHUNK_SIZE = 30;
|
||||
private const string TRANSITION_SCENE_RELATIVE_PATH = "Scenes/OVRTransitionScene.unity";
|
||||
private const string BUNDLE_MANAGER_OUTPUT_PATH = "OVRAssetBundles";
|
||||
private const string BUNDLE_MANAGER_MASTER_BUNDLE = "OVRMasterBundle";
|
||||
|
||||
private const string EXTERNAL_STORAGE_PATH = "/sdcard/Android/data";
|
||||
private const string ADB_TOOL_INITIALIZE_ERROR = "Failed to initialize ADB Tool. Please check Android SDK path in Preferences -> External Tools";
|
||||
|
||||
private static string externalSceneCache;
|
||||
private static string transitionScenePath;
|
||||
|
||||
private static string projectDefaultAppIdentifier;
|
||||
private static string projectDefaultVersion;
|
||||
private static ScriptingImplementation projectScriptImplementation;
|
||||
private static ManagedStrippingLevel projectManagedStrippingLevel;
|
||||
private static bool projectStripEngineCode;
|
||||
|
||||
public static void BuildDeployTransitionAPK(bool useOptionalTransitionApkPackage)
|
||||
{
|
||||
OVRBundleTool.PrintLog("Building and deploying transition APK . . . ", true);
|
||||
|
||||
if (!Directory.Exists(BUNDLE_MANAGER_OUTPUT_PATH))
|
||||
{
|
||||
Directory.CreateDirectory(BUNDLE_MANAGER_OUTPUT_PATH);
|
||||
}
|
||||
|
||||
PrebuildProjectSettingUpdate();
|
||||
|
||||
if (String.IsNullOrEmpty(transitionScenePath))
|
||||
{
|
||||
// Get current editor script's directory as base path
|
||||
string[] res = System.IO.Directory.GetFiles(Application.dataPath, "OVRBundleManager.cs", SearchOption.AllDirectories);
|
||||
if (res.Length > 1)
|
||||
{
|
||||
OVRBundleTool.PrintError("More than one OVRBundleManager editor script has been found, please double check your Oculus SDK import.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append Transition Scene's relative path to base path
|
||||
var OVREditorScript = Path.GetDirectoryName(res[0]);
|
||||
transitionScenePath = Path.Combine(OVREditorScript, TRANSITION_SCENE_RELATIVE_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
string[] buildScenes = new string[1] { transitionScenePath };
|
||||
string apkOutputPath = Path.Combine(BUNDLE_MANAGER_OUTPUT_PATH, "OVRTransition.apk");
|
||||
DateTime apkBuildStart = DateTime.Now;
|
||||
|
||||
var buildPlayerOptions = new BuildPlayerOptions
|
||||
{
|
||||
scenes = buildScenes,
|
||||
locationPathName = apkOutputPath,
|
||||
target = BuildTarget.Android,
|
||||
options = BuildOptions.Development |
|
||||
BuildOptions.AutoRunPlayer
|
||||
};
|
||||
|
||||
BuildReport report = BuildPipeline.BuildPlayer(buildPlayerOptions);
|
||||
|
||||
if (report.summary.result == BuildResult.Succeeded)
|
||||
{
|
||||
OVRBundleTool.PrintSuccess();
|
||||
}
|
||||
else if (report.summary.result == BuildResult.Failed)
|
||||
{
|
||||
OVRBundleTool.PrintError();
|
||||
}
|
||||
OVRPlugin.SendEvent("oculus_bundle_tool", "apk_build_time", (DateTime.Now - apkBuildStart).TotalSeconds.ToString());
|
||||
PostbuildProjectSettingUpdate();
|
||||
}
|
||||
|
||||
private static void PrebuildProjectSettingUpdate()
|
||||
{
|
||||
// Modify application identifier for transition APK
|
||||
projectDefaultAppIdentifier = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android);
|
||||
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android,
|
||||
projectDefaultAppIdentifier + GetTransitionApkOptionalIdentifier());
|
||||
|
||||
// Set VersionCode as a unique identifier for transition APK
|
||||
projectDefaultVersion = PlayerSettings.bundleVersion;
|
||||
PlayerSettings.bundleVersion = TRANSITION_APK_VERSION_NAME;
|
||||
|
||||
// Modify IL2CPP option as it strips script symbols that are necessary for the scenes at runtime
|
||||
projectScriptImplementation = PlayerSettings.GetScriptingBackend(EditorUserBuildSettings.selectedBuildTargetGroup);
|
||||
if (projectScriptImplementation != ScriptingImplementation.Mono2x)
|
||||
{
|
||||
// Show message in console to make it more clear to developers
|
||||
OVRBundleTool.PrintLog("Build will use Mono as scripting backend.");
|
||||
PlayerSettings.SetScriptingBackend(EditorUserBuildSettings.selectedBuildTargetGroup, ScriptingImplementation.Mono2x);
|
||||
}
|
||||
|
||||
// Avoid stripping managed code that are necessary for the scenes at runtime
|
||||
projectManagedStrippingLevel = PlayerSettings.GetManagedStrippingLevel(BuildTargetGroup.Android);
|
||||
if (projectManagedStrippingLevel != ManagedStrippingLevel.Disabled)
|
||||
{
|
||||
OVRBundleTool.PrintLog("Build will set Managed Stripping Level to Disabled.");
|
||||
PlayerSettings.SetManagedStrippingLevel(BuildTargetGroup.Android, ManagedStrippingLevel.Disabled);
|
||||
}
|
||||
|
||||
projectStripEngineCode = PlayerSettings.stripEngineCode;
|
||||
if (projectStripEngineCode)
|
||||
{
|
||||
PlayerSettings.stripEngineCode = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void PostbuildProjectSettingUpdate()
|
||||
{
|
||||
// Restore application identifier
|
||||
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android,
|
||||
projectDefaultAppIdentifier);
|
||||
|
||||
// Restore version setting
|
||||
PlayerSettings.bundleVersion = projectDefaultVersion;
|
||||
|
||||
// Restore scripting backend option
|
||||
if (PlayerSettings.GetScriptingBackend(EditorUserBuildSettings.selectedBuildTargetGroup) != projectScriptImplementation)
|
||||
{
|
||||
PlayerSettings.SetScriptingBackend(EditorUserBuildSettings.selectedBuildTargetGroup, projectScriptImplementation);
|
||||
}
|
||||
|
||||
// Restore managed stripping level
|
||||
if (PlayerSettings.GetManagedStrippingLevel(BuildTargetGroup.Android) != projectManagedStrippingLevel)
|
||||
{
|
||||
PlayerSettings.SetManagedStrippingLevel(BuildTargetGroup.Android, projectManagedStrippingLevel);
|
||||
}
|
||||
|
||||
if (PlayerSettings.stripEngineCode != projectStripEngineCode)
|
||||
{
|
||||
PlayerSettings.stripEngineCode = projectStripEngineCode;
|
||||
}
|
||||
}
|
||||
|
||||
// Build and deploy a list of scenes. It's suggested to only build and deploy one active scene that's being modified and
|
||||
// its dependencies such as scenes that are loaded additively
|
||||
public static void BuildDeployScenes(List<OVRBundleTool.EditorSceneInfo> sceneList, bool forceRestart)
|
||||
{
|
||||
externalSceneCache = EXTERNAL_STORAGE_PATH + "/" + PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android)
|
||||
+ GetTransitionApkOptionalIdentifier() + "/cache/scenes";
|
||||
|
||||
BuildSceneBundles(sceneList);
|
||||
if (DeploySceneBundles(sceneList))
|
||||
{
|
||||
if (forceRestart)
|
||||
{
|
||||
LaunchApplication();
|
||||
return;
|
||||
}
|
||||
OVRBundleTool.PrintSuccess();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Build assets that are used by scenes from the given list.
|
||||
// This function will automatically de-duplicated same asset file being referenced in multiple scenes.
|
||||
// Scene bundles will be created with name pattern: <SceneName>_<AssetTypeExtention><ChunckNumber>
|
||||
private static void BuildSceneBundles(List<OVRBundleTool.EditorSceneInfo> sceneList)
|
||||
{
|
||||
DateTime totalStart = DateTime.Now;
|
||||
// Keeps track of dependent assets across scenes
|
||||
// to ensure each asset is only packaged once in one of the scene bundles.
|
||||
// uniqueAssetInSceneBundle is a map from "asset unique identifier" to the first scene that references the asset.
|
||||
// It supports different assets with same file name as "asset unique identifier" contain full qualified asset file path
|
||||
Dictionary<string, string> uniqueAssetInSceneBundle = new Dictionary<string, string>();
|
||||
|
||||
// List of bundle targets for Unity's build pipeline to package
|
||||
List<AssetBundleBuild> assetBundleBuilds = new List<AssetBundleBuild>();
|
||||
// Map that contains "asset type" to list of assets that are of the asset type
|
||||
Dictionary<string, List<string>> extToAssetList = new Dictionary<string, List<string>>();
|
||||
|
||||
// Check if assets in Resources need to be packaged
|
||||
if (CheckForResources())
|
||||
{
|
||||
var resourceDirectories = Directory.GetDirectories("Assets", "Resources", SearchOption.AllDirectories).ToArray();
|
||||
// Fetch a list of all files in resource directory
|
||||
string[] resourceAssetPaths = AssetDatabase.FindAssets("", resourceDirectories).Select(x => AssetDatabase.GUIDToAssetPath(x)).ToArray();
|
||||
ProcessAssets(resourceAssetPaths, "resources", ref uniqueAssetInSceneBundle, ref extToAssetList);
|
||||
|
||||
AssetBundleBuild resourceBundle = new AssetBundleBuild();
|
||||
resourceBundle.assetNames = uniqueAssetInSceneBundle.Keys.ToArray();
|
||||
resourceBundle.assetBundleName = OVRSceneLoader.resourceBundleName;
|
||||
assetBundleBuilds.Add(resourceBundle);
|
||||
}
|
||||
|
||||
// Create scene bundle output directory
|
||||
string sceneBundleDirectory = Path.Combine(BUNDLE_MANAGER_OUTPUT_PATH, BUNDLE_MANAGER_MASTER_BUNDLE);
|
||||
if (!Directory.Exists(sceneBundleDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(sceneBundleDirectory);
|
||||
}
|
||||
|
||||
OVRBundleTool.PrintLog("Building scene bundles . . . ");
|
||||
DateTime labelingStart = DateTime.Now;
|
||||
foreach (var scene in sceneList)
|
||||
{
|
||||
// Get all the assets that the scene depends on and sort them by type
|
||||
DateTime getDepStart = DateTime.Now;
|
||||
string[] assetDependencies = AssetDatabase.GetDependencies(scene.scenePath);
|
||||
Debug.Log("[OVRBundleManager] - " + scene.sceneName + " - Calculated scene asset dependencies in: " + (DateTime.Now - getDepStart).TotalSeconds);
|
||||
ProcessAssets(assetDependencies, scene.sceneName, ref uniqueAssetInSceneBundle, ref extToAssetList);
|
||||
|
||||
// Add the scene into it's own bundle
|
||||
string[] sceneAsset = new string[1] { scene.scenePath };
|
||||
AssetBundleBuild sceneBuild = new AssetBundleBuild();
|
||||
sceneBuild.assetBundleName = "scene_" + scene.sceneName;
|
||||
sceneBuild.assetNames = sceneAsset;
|
||||
assetBundleBuilds.Add(sceneBuild);
|
||||
}
|
||||
|
||||
// Chunk the asset bundles by number of assets
|
||||
foreach (string ext in extToAssetList.Keys)
|
||||
{
|
||||
int assetCount = extToAssetList[ext].Count;
|
||||
int numChunks = (assetCount + BUNDLE_CHUNK_SIZE - 1) / BUNDLE_CHUNK_SIZE;
|
||||
//Debug.Log(ext + " has " + assetCount + " asset(s) that will be split into " + numChunks + " chunk(s)");
|
||||
for (int i = 0; i < numChunks; i++)
|
||||
{
|
||||
List<string> assetChunkList;
|
||||
if (i == numChunks - 1)
|
||||
{
|
||||
int size = BUNDLE_CHUNK_SIZE - (numChunks * BUNDLE_CHUNK_SIZE - assetCount);
|
||||
assetChunkList = extToAssetList[ext].GetRange(i * BUNDLE_CHUNK_SIZE, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
assetChunkList = extToAssetList[ext].GetRange(i * BUNDLE_CHUNK_SIZE, BUNDLE_CHUNK_SIZE);
|
||||
}
|
||||
AssetBundleBuild build = new AssetBundleBuild();
|
||||
build.assetBundleName = "asset_" + ext + i;
|
||||
build.assetNames = assetChunkList.ToArray();
|
||||
//Debug.Log("Chunk " + i + " has " + assetChunkList.Count + " asset(s)");
|
||||
assetBundleBuilds.Add(build);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log("[OVRBundleManager] - Created chucked scene bundles in: " + (DateTime.Now - labelingStart).TotalSeconds);
|
||||
|
||||
// Build asset bundles
|
||||
BuildPipeline.BuildAssetBundles(sceneBundleDirectory, assetBundleBuilds.ToArray(),
|
||||
BuildAssetBundleOptions.UncompressedAssetBundle, BuildTarget.Android);
|
||||
|
||||
double bundleBuildTime = (DateTime.Now - totalStart).TotalSeconds;
|
||||
Debug.Log("[OVRBundleManager] - Total Time: " + bundleBuildTime);
|
||||
OVRPlugin.SendEvent("oculus_bundle_tool", "bundle_build_time", bundleBuildTime.ToString());
|
||||
}
|
||||
|
||||
private static void ProcessAssets(string[] assetPaths,
|
||||
string assetParent,
|
||||
ref Dictionary<string, string> uniqueAssetInSceneBundle,
|
||||
ref Dictionary<string, List<string>> extToAssetList)
|
||||
{
|
||||
foreach (string asset in assetPaths)
|
||||
{
|
||||
string ext = Path.GetExtension(asset);
|
||||
if (!string.IsNullOrEmpty(ext))
|
||||
{
|
||||
ext = ext.Substring(1);
|
||||
if (!ext.Equals("cs") && !ext.Equals("unity"))
|
||||
{
|
||||
// Only process each asset once across all resource and scene bundles
|
||||
// Each asset is keyed by full path as a unique identifier
|
||||
if (!uniqueAssetInSceneBundle.ContainsKey(asset))
|
||||
{
|
||||
var assetObject = (UnityEngine.Object)AssetDatabase.LoadAssetAtPath(asset, typeof(UnityEngine.Object));
|
||||
if (assetObject == null || (assetObject.hideFlags & HideFlags.DontSaveInBuild) == 0)
|
||||
{
|
||||
uniqueAssetInSceneBundle[asset] = assetParent;
|
||||
|
||||
if (assetParent != "resources")
|
||||
{
|
||||
if (!extToAssetList.ContainsKey(ext))
|
||||
{
|
||||
extToAssetList[ext] = new List<string>();
|
||||
}
|
||||
extToAssetList[ext].Add(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool DeploySceneBundles(List<OVRBundleTool.EditorSceneInfo> sceneList)
|
||||
{
|
||||
// Create Temp directory on local machine if it does not exist
|
||||
string tempDirectory = Path.Combine(BUNDLE_MANAGER_OUTPUT_PATH, "Temp");
|
||||
if (!Directory.Exists(tempDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(tempDirectory);
|
||||
}
|
||||
string absoluteTempPath = Path.Combine(Path.Combine(Application.dataPath, ".."), tempDirectory);
|
||||
|
||||
OVRBundleTool.PrintLog("Deploying scene bundles to device . . . ");
|
||||
|
||||
OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath());
|
||||
if (adbTool.isReady)
|
||||
{
|
||||
DateTime transferStart = DateTime.Now;
|
||||
|
||||
OVRBundleTool.UpdateSceneBuildStatus(OVRBundleTool.SceneBundleStatus.TRANSFERRING);
|
||||
// Transfer all scene bundles that are relavent
|
||||
if (!TransferSceneBundles(adbTool, absoluteTempPath, externalSceneCache))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
OVRBundleTool.UpdateSceneBuildStatus(OVRBundleTool.SceneBundleStatus.DEPLOYED);
|
||||
|
||||
// Create file to tell transition scene APK which scene to load and push it to the device
|
||||
string sceneLoadDataPath = Path.Combine(tempDirectory, OVRSceneLoader.sceneLoadDataName);
|
||||
if (File.Exists(sceneLoadDataPath))
|
||||
{
|
||||
File.Delete(sceneLoadDataPath);
|
||||
}
|
||||
|
||||
StreamWriter writer = new StreamWriter(sceneLoadDataPath, true);
|
||||
// Write version and scene names
|
||||
long unixTime = (int)(DateTimeOffset.UtcNow.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
|
||||
writer.WriteLine(unixTime.ToString());
|
||||
for (int i = 0; i < sceneList.Count; i++)
|
||||
{
|
||||
writer.WriteLine(Path.GetFileNameWithoutExtension(sceneList[i].scenePath));
|
||||
}
|
||||
|
||||
writer.Close();
|
||||
|
||||
string absoluteSceneLoadDataPath = Path.Combine(absoluteTempPath, OVRSceneLoader.sceneLoadDataName);
|
||||
string[] pushCommand = { "-d push", "\"" + absoluteSceneLoadDataPath + "\"", "\"" + externalSceneCache + "\"" };
|
||||
string output, error;
|
||||
if (adbTool.RunCommand(pushCommand, null, out output, out error) == 0)
|
||||
{
|
||||
Debug.Log("[OVRBundleManager] Scene Load Data Pushed to Device.");
|
||||
OVRPlugin.SendEvent("oculus_bundle_tool", "transfer_bundle_time", (DateTime.Now - transferStart).TotalSeconds.ToString());
|
||||
return true;
|
||||
}
|
||||
OVRBundleTool.PrintError(string.IsNullOrEmpty(error) ? output : error);
|
||||
}
|
||||
else
|
||||
{
|
||||
OVRBundleTool.PrintError(ADB_TOOL_INITIALIZE_ERROR);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TransferSceneBundles(OVRADBTool adbTool, string absoluteTempPath, string externalSceneCache)
|
||||
{
|
||||
List<string> bundlesToTransfer = new List<string>();
|
||||
List<string> bundlesToDelete = new List<string>();
|
||||
string manifestFilePath = externalSceneCache + "/" + BUNDLE_MANAGER_MASTER_BUNDLE;
|
||||
|
||||
string[] pullManifestCommand = { "-d pull", "\"" + manifestFilePath + "\"", "\"" + absoluteTempPath + "\"" };
|
||||
|
||||
string output, error;
|
||||
if (adbTool.RunCommand(pullManifestCommand, null, out output, out error) == 0)
|
||||
{
|
||||
// An existing manifest file was found on device. Load hashes and upload bundles that have changed hashes.
|
||||
Debug.Log("[OVRBundleManager] - Scene bundle manifest file found. Decoding changes . . .");
|
||||
|
||||
// Load hashes from remote manifest
|
||||
AssetBundle remoteBundle = AssetBundle.LoadFromFile(Path.Combine(absoluteTempPath, BUNDLE_MANAGER_MASTER_BUNDLE));
|
||||
if (remoteBundle == null)
|
||||
{
|
||||
OVRBundleTool.PrintError("Failed to load remote asset bundle manifest file.");
|
||||
return false;
|
||||
}
|
||||
AssetBundleManifest remoteManifest = remoteBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
|
||||
|
||||
Dictionary<string, Hash128> remoteBundleToHash = new Dictionary<string, Hash128>();
|
||||
if (remoteManifest != null)
|
||||
{
|
||||
string[] assetBundles = remoteManifest.GetAllAssetBundles();
|
||||
foreach (string bundleName in assetBundles)
|
||||
{
|
||||
remoteBundleToHash[bundleName] = remoteManifest.GetAssetBundleHash(bundleName);
|
||||
}
|
||||
}
|
||||
remoteBundle.Unload(true);
|
||||
|
||||
// Load hashes from local manifest
|
||||
AssetBundle localBundle = AssetBundle.LoadFromFile(BUNDLE_MANAGER_OUTPUT_PATH + "\\" + BUNDLE_MANAGER_MASTER_BUNDLE
|
||||
+ "\\" + BUNDLE_MANAGER_MASTER_BUNDLE);
|
||||
if (localBundle == null)
|
||||
{
|
||||
OVRBundleTool.PrintError("<color=red>Failed to load local asset bundle manifest file.\n</color>");
|
||||
return false;
|
||||
}
|
||||
AssetBundleManifest localManifest = localBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
|
||||
|
||||
if (localManifest != null)
|
||||
{
|
||||
Hash128 zeroHash = new Hash128(0, 0, 0, 0);
|
||||
|
||||
// Build a list of dirty bundles that will have to be transfered
|
||||
string relativeSceneBundlesPath = Path.Combine(BUNDLE_MANAGER_OUTPUT_PATH, BUNDLE_MANAGER_MASTER_BUNDLE);
|
||||
bundlesToTransfer.Add(Path.Combine(relativeSceneBundlesPath, BUNDLE_MANAGER_MASTER_BUNDLE));
|
||||
string[] assetBundles = localManifest.GetAllAssetBundles();
|
||||
foreach (string bundleName in assetBundles)
|
||||
{
|
||||
if (!remoteBundleToHash.ContainsKey(bundleName))
|
||||
{
|
||||
bundlesToTransfer.Add(Path.Combine(relativeSceneBundlesPath, bundleName));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (remoteBundleToHash[bundleName] != localManifest.GetAssetBundleHash(bundleName))
|
||||
{
|
||||
bundlesToTransfer.Add(Path.Combine(relativeSceneBundlesPath, bundleName));
|
||||
}
|
||||
remoteBundleToHash[bundleName] = zeroHash;
|
||||
}
|
||||
}
|
||||
|
||||
OVRBundleTool.PrintLog(bundlesToTransfer.Count + " dirty bundle(s) will be transfered.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (output.Contains("does not exist"))
|
||||
{
|
||||
// Fresh install of asset bundles, transfer all asset bundles
|
||||
OVRBundleTool.PrintLog("Manifest file not found. Transfering all bundles . . . ");
|
||||
|
||||
string[] mkdirCommand = { "-d shell", "mkdir -p", "\"" + externalSceneCache + "\"" };
|
||||
if (adbTool.RunCommand(mkdirCommand, null, out output, out error) == 0)
|
||||
{
|
||||
string absoluteSceneBundlePath = Path.Combine(Path.Combine(Application.dataPath, ".."),
|
||||
Path.Combine(BUNDLE_MANAGER_OUTPUT_PATH, BUNDLE_MANAGER_MASTER_BUNDLE));
|
||||
|
||||
string[] assetBundlePaths = Directory.GetFiles(absoluteSceneBundlePath);
|
||||
if (assetBundlePaths.Length != 0)
|
||||
{
|
||||
foreach (string path in assetBundlePaths)
|
||||
{
|
||||
if (!path.Contains(".manifest"))
|
||||
{
|
||||
bundlesToTransfer.Add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OVRBundleTool.PrintError("Failed to locate scene bundles to transfer.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If any adb error occured during manifest calculation, print it and return false
|
||||
if (!string.IsNullOrEmpty(error) || output.Contains("error"))
|
||||
{
|
||||
OVRBundleTool.PrintError(string.IsNullOrEmpty(error) ? output : error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Transfer bundles to device
|
||||
DateTime transferStart = DateTime.Now;
|
||||
foreach (string bundle in bundlesToTransfer)
|
||||
{
|
||||
string absoluteBundlePath = Path.Combine(Path.Combine(Application.dataPath, ".."), bundle);
|
||||
string[] pushBundleCommand = { "-d push", "\"" + absoluteBundlePath + "\"", "\"" + externalSceneCache + "\"" };
|
||||
adbTool.RunCommandAsync(pushBundleCommand, null);
|
||||
}
|
||||
Debug.Log("[OVRBundleManager] - Transfer took " + (DateTime.Now - transferStart).TotalSeconds + " seconds.");
|
||||
|
||||
// Delete stale bundles on device
|
||||
if (bundlesToDelete.Count > 0)
|
||||
{
|
||||
foreach (string bundle in bundlesToDelete)
|
||||
{
|
||||
string bundlePath = externalSceneCache + "/" + bundle;
|
||||
string[] deleteBundleCommand = { "-d shell", "rm", "\"" + bundlePath + "\"" };
|
||||
adbTool.RunCommandAsync(deleteBundleCommand, null);
|
||||
}
|
||||
OVRBundleTool.PrintLog("Deleted " + bundlesToDelete.Count + " bundle(s) that were stale");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool LaunchApplication()
|
||||
{
|
||||
OVRBundleTool.PrintLog("Launching Application . . . ");
|
||||
|
||||
OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath());
|
||||
if (adbTool.isReady)
|
||||
{
|
||||
string output, error;
|
||||
string appPackagename = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android)
|
||||
+ GetTransitionApkOptionalIdentifier();
|
||||
string playerActivityName = "\"" + appPackagename + "/com.unity3d.player.UnityPlayerActivity\"";
|
||||
string[] appStartCommand = { "-d shell", "am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -S -f 0x10200000 -n", playerActivityName };
|
||||
if (adbTool.RunCommand(appStartCommand, null, out output, out error) == 0)
|
||||
{
|
||||
OVRBundleTool.PrintSuccess();
|
||||
OVRBundleTool.PrintLog("App package " + appPackagename + " is launched.");
|
||||
return true;
|
||||
}
|
||||
|
||||
string completeError = "Failed to launch application. Try launching it manually through the device.\n" + (string.IsNullOrEmpty(error) ? output : error);
|
||||
OVRBundleTool.PrintError(completeError);
|
||||
}
|
||||
else
|
||||
{
|
||||
OVRBundleTool.PrintError(ADB_TOOL_INITIALIZE_ERROR);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool UninstallAPK()
|
||||
{
|
||||
OVRBundleTool.PrintLog("Uninstalling Application . . .");
|
||||
|
||||
OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath());
|
||||
if (adbTool.isReady)
|
||||
{
|
||||
string output, error;
|
||||
string appPackagename = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android)
|
||||
+ GetTransitionApkOptionalIdentifier();
|
||||
string[] appStartCommand = { "-d shell", "pm uninstall", appPackagename };
|
||||
if (adbTool.RunCommand(appStartCommand, null, out output, out error) == 0)
|
||||
{
|
||||
OVRBundleTool.PrintSuccess();
|
||||
OVRBundleTool.PrintLog("App package " + appPackagename + " is uninstalled.");
|
||||
return true;
|
||||
}
|
||||
|
||||
OVRBundleTool.PrintError("Failed to uninstall APK.");
|
||||
}
|
||||
else
|
||||
{
|
||||
OVRBundleTool.PrintError(ADB_TOOL_INITIALIZE_ERROR);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void DeleteRemoteAssetBundles()
|
||||
{
|
||||
OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath());
|
||||
if (adbTool.isReady)
|
||||
{
|
||||
bool failure = false;
|
||||
string fileExistsError = "No such file or directory";
|
||||
OVRBundleTool.PrintLog("Deleting device bundles . . . ");
|
||||
string output, error;
|
||||
string[] deleteBundleCommand = { "-d shell", "rm -r", externalSceneCache };
|
||||
if (adbTool.RunCommand(deleteBundleCommand, null, out output, out error) != 0)
|
||||
{
|
||||
if (!(output.Contains(fileExistsError) || error.Contains(fileExistsError)))
|
||||
{
|
||||
failure = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (failure)
|
||||
{
|
||||
OVRBundleTool.PrintError(string.IsNullOrEmpty(error) ? output : error);
|
||||
OVRBundleTool.PrintError("Failed to delete scene bundle cache directory.");
|
||||
}
|
||||
else
|
||||
{
|
||||
OVRBundleTool.PrintSuccess();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OVRBundleTool.PrintError(ADB_TOOL_INITIALIZE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DeleteLocalAssetBundles()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(BUNDLE_MANAGER_OUTPUT_PATH))
|
||||
{
|
||||
OVRBundleTool.PrintLog("Deleting local bundles . . . ");
|
||||
Directory.Delete(BUNDLE_MANAGER_OUTPUT_PATH, true);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
OVRBundleTool.PrintError(e.Message);
|
||||
}
|
||||
OVRBundleTool.PrintSuccess();
|
||||
}
|
||||
|
||||
private static bool CheckForResources()
|
||||
{
|
||||
string[] resourceDirectories = Directory.GetDirectories("Assets", "Resources", SearchOption.AllDirectories);
|
||||
return resourceDirectories.Length > 0;
|
||||
}
|
||||
|
||||
private static string GetTransitionApkOptionalIdentifier()
|
||||
{
|
||||
string transitionApkOptionalIdentifier;
|
||||
// Check option value from editor UI
|
||||
if (OVRBundleTool.GetUseOptionalTransitionApkPackage())
|
||||
{
|
||||
// Append .transition to default app package name to optionally allow both
|
||||
// full build apk and transition apk to be installed on device
|
||||
transitionApkOptionalIdentifier = ".transition";
|
||||
}
|
||||
else
|
||||
{
|
||||
transitionApkOptionalIdentifier = "";
|
||||
}
|
||||
return transitionApkOptionalIdentifier;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/Oculus/VR/Editor/OVRBundleManager.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRBundleManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a46c155525da654c8ef823c069361d3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
491
Assets/Oculus/VR/Editor/OVRBundleTool.cs
Normal file
491
Assets/Oculus/VR/Editor/OVRBundleTool.cs
Normal file
@@ -0,0 +1,491 @@
|
||||
#if UNITY_EDITOR_WIN && UNITY_ANDROID
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
public class OVRBundleTool : EditorWindow
|
||||
{
|
||||
private static List<EditorSceneInfo> buildableScenes;
|
||||
private static Vector2 debugLogScroll = new Vector2(0, 0);
|
||||
private static bool invalidBuildableScene;
|
||||
|
||||
private static string toolLog;
|
||||
private static bool useOptionalTransitionApkPackage;
|
||||
private static GUIStyle logBoxStyle;
|
||||
private static Vector2 logBoxSize;
|
||||
private static float logBoxSpacing = 30.0f;
|
||||
|
||||
private bool forceRestart = false;
|
||||
private bool showBundleManagement = false;
|
||||
private bool showOther = false;
|
||||
|
||||
// Needed to ensure that APK checking does happen during editor start up, but will still happen when the window is opened/updated
|
||||
private static bool panelInitialized = false;
|
||||
|
||||
private enum ApkStatus
|
||||
{
|
||||
UNKNOWN,
|
||||
OK,
|
||||
NOT_INSTALLED,
|
||||
DEVICE_NOT_CONNECTED,
|
||||
};
|
||||
|
||||
public enum SceneBundleStatus
|
||||
{
|
||||
[Description("Unknown")]
|
||||
UNKNOWN,
|
||||
[Description("Queued")]
|
||||
QUEUED,
|
||||
[Description("Building")]
|
||||
BUILDING,
|
||||
[Description("Done")]
|
||||
DONE,
|
||||
[Description("Transferring")]
|
||||
TRANSFERRING,
|
||||
[Description("Deployed")]
|
||||
DEPLOYED,
|
||||
};
|
||||
|
||||
public class EditorSceneInfo
|
||||
{
|
||||
public string scenePath;
|
||||
public string sceneName;
|
||||
public SceneBundleStatus buildStatus;
|
||||
|
||||
public EditorSceneInfo(string path, string name)
|
||||
{
|
||||
scenePath = path;
|
||||
sceneName = name;
|
||||
buildStatus = SceneBundleStatus.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
private static ApkStatus currentApkStatus;
|
||||
|
||||
[MenuItem("Oculus/OVR Build/OVR Scene Quick Preview %l", false, 10)]
|
||||
static void Init()
|
||||
{
|
||||
currentApkStatus = ApkStatus.UNKNOWN;
|
||||
|
||||
EditorWindow.GetWindow(typeof(OVRBundleTool));
|
||||
|
||||
invalidBuildableScene = false;
|
||||
InitializePanel();
|
||||
|
||||
OVRPlugin.SetDeveloperMode(OVRPlugin.Bool.True);
|
||||
OVRPlugin.SendEvent("oculus_bundle_tool", "show_window");
|
||||
}
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
InitializePanel();
|
||||
}
|
||||
|
||||
public static void InitializePanel()
|
||||
{
|
||||
panelInitialized = true;
|
||||
GetScenesFromBuildSettings();
|
||||
EditorBuildSettings.sceneListChanged += GetScenesFromBuildSettings;
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
this.titleContent.text = "OVR Scene Quick Preview";
|
||||
|
||||
if (panelInitialized)
|
||||
{
|
||||
CheckForTransitionAPK();
|
||||
panelInitialized = false;
|
||||
}
|
||||
|
||||
if (logBoxStyle == null)
|
||||
{
|
||||
logBoxStyle = new GUIStyle();
|
||||
logBoxStyle.margin.left = 5;
|
||||
logBoxStyle.wordWrap = true;
|
||||
logBoxStyle.normal.textColor = logBoxStyle.focused.textColor = EditorStyles.label.normal.textColor;
|
||||
logBoxStyle.richText = true;
|
||||
}
|
||||
|
||||
GUILayout.Space(10.0f);
|
||||
|
||||
GUILayout.Label("Scenes", EditorStyles.boldLabel);
|
||||
GUIContent buildSettingsBtnTxt = new GUIContent("Open Build Settings");
|
||||
if (buildableScenes == null || buildableScenes.Count == 0)
|
||||
{
|
||||
string sceneErrorMessage;
|
||||
if (invalidBuildableScene)
|
||||
{
|
||||
sceneErrorMessage = "Invalid scene selection. \nPlease remove OVRTransitionScene in the project's build settings.";
|
||||
}
|
||||
else
|
||||
{
|
||||
sceneErrorMessage = "No scenes detected. \nTo get started, add scenes in the project's build settings.";
|
||||
}
|
||||
GUILayout.Label(sceneErrorMessage);
|
||||
|
||||
var buildSettingBtnRt = GUILayoutUtility.GetRect(buildSettingsBtnTxt, GUI.skin.button, GUILayout.Width(150));
|
||||
if (GUI.Button(buildSettingBtnRt, buildSettingsBtnTxt))
|
||||
{
|
||||
OpenBuildSettingsWindow();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (EditorSceneInfo scene in buildableScenes)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField(scene.sceneName, GUILayout.ExpandWidth(true));
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (scene.buildStatus != SceneBundleStatus.UNKNOWN)
|
||||
{
|
||||
string status = GetEnumDescription(scene.buildStatus);
|
||||
EditorGUILayout.LabelField(status, GUILayout.Width(70));
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
GUIContent sceneBtnTxt = new GUIContent("Build and Deploy Scene(s)");
|
||||
var sceneBtnRt = GUILayoutUtility.GetRect(sceneBtnTxt, GUI.skin.button, GUILayout.Width(200));
|
||||
if (GUI.Button(sceneBtnRt, sceneBtnTxt))
|
||||
{
|
||||
// Check the latest transition apk status
|
||||
CheckForTransitionAPK();
|
||||
// Show a dialog to prompt for building and deploying transition APK
|
||||
if (currentApkStatus != ApkStatus.OK &&
|
||||
EditorUtility.DisplayDialog("Build and Deploy OVR Transition APK?",
|
||||
"OVR Transition APK status not ready, it is required to load your scene bundle for quick preview.",
|
||||
"Yes",
|
||||
"No"))
|
||||
{
|
||||
PrintLog("Building OVR Transition APK");
|
||||
OVRBundleManager.BuildDeployTransitionAPK(useOptionalTransitionApkPackage);
|
||||
CheckForTransitionAPK();
|
||||
}
|
||||
|
||||
for (int i = 0; i < buildableScenes.Count; i++)
|
||||
{
|
||||
buildableScenes[i].buildStatus = SceneBundleStatus.QUEUED;
|
||||
}
|
||||
OVRBundleManager.BuildDeployScenes(buildableScenes, forceRestart);
|
||||
}
|
||||
|
||||
GUIContent forceRestartLabel = new GUIContent("Force Restart [?]", "Relaunch the application after scene bundles are finished deploying.");
|
||||
forceRestart = GUILayout.Toggle(forceRestart, forceRestartLabel, GUILayout.ExpandWidth(true));
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUILayout.Space(10.0f);
|
||||
GUIContent transitionContent = new GUIContent("Transition APK [?]", "Build and deploy an APK that will transition into the scene you are working on. This enables fast iteration on a specific scene.");
|
||||
GUILayout.Label(transitionContent, EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
GUIStyle statusStyle = EditorStyles.label;
|
||||
statusStyle.richText = true;
|
||||
GUILayout.Label("Status: ", statusStyle, GUILayout.ExpandWidth(false));
|
||||
|
||||
string statusMesssage;
|
||||
switch (currentApkStatus)
|
||||
{
|
||||
case ApkStatus.OK:
|
||||
statusMesssage = "<color=green>APK installed. Ready to build and deploy scenes.</color>";
|
||||
break;
|
||||
case ApkStatus.NOT_INSTALLED:
|
||||
statusMesssage = "<color=red>APK not installed. Press build and deploy to install the transition APK.</color>";
|
||||
break;
|
||||
case ApkStatus.DEVICE_NOT_CONNECTED:
|
||||
statusMesssage = "<color=red>Device not connected via ADB. Please connect device and allow debugging.</color>";
|
||||
break;
|
||||
case ApkStatus.UNKNOWN:
|
||||
default:
|
||||
statusMesssage = "<color=red>Failed to get APK status!</color>";
|
||||
break;
|
||||
}
|
||||
GUILayout.Label(statusMesssage, statusStyle, GUILayout.ExpandWidth(true));
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
GUIContent btnTxt = new GUIContent("Build and Deploy App");
|
||||
var rt = GUILayoutUtility.GetRect(btnTxt, GUI.skin.button, GUILayout.Width(200));
|
||||
if (GUI.Button(rt, btnTxt))
|
||||
{
|
||||
OVRBundleManager.BuildDeployTransitionAPK(useOptionalTransitionApkPackage);
|
||||
CheckForTransitionAPK();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(10.0f);
|
||||
GUILayout.Label("Utilities", EditorStyles.boldLabel);
|
||||
|
||||
showBundleManagement = EditorGUILayout.Foldout(showBundleManagement, "Bundle Management");
|
||||
if (showBundleManagement)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
GUIContent clearDeviceBundlesTxt = new GUIContent("Delete Device Bundles");
|
||||
var clearDeviceBundlesBtnRt = GUILayoutUtility.GetRect(clearDeviceBundlesTxt, GUI.skin.button, GUILayout.ExpandWidth(true));
|
||||
if (GUI.Button(clearDeviceBundlesBtnRt, clearDeviceBundlesTxt))
|
||||
{
|
||||
OVRBundleManager.DeleteRemoteAssetBundles();
|
||||
}
|
||||
|
||||
GUIContent clearLocalBundlesTxt = new GUIContent("Delete Local Bundles");
|
||||
var clearLocalBundlesBtnRt = GUILayoutUtility.GetRect(clearLocalBundlesTxt, GUI.skin.button, GUILayout.ExpandWidth(true));
|
||||
if (GUI.Button(clearLocalBundlesBtnRt, clearLocalBundlesTxt))
|
||||
{
|
||||
OVRBundleManager.DeleteLocalAssetBundles();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
showOther = EditorGUILayout.Foldout(showOther, "Other");
|
||||
if (showOther)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
GUIContent useOptionalTransitionPackageLabel = new GUIContent("Use optional APK package name [?]",
|
||||
"This allows both full build APK and transition APK to be installed on device. However, platform services like Entitlement check may fail.");
|
||||
|
||||
EditorGUILayout.LabelField(useOptionalTransitionPackageLabel, GUILayout.ExpandWidth(false));
|
||||
bool newToggleValue = EditorGUILayout.Toggle(useOptionalTransitionApkPackage);
|
||||
|
||||
if (newToggleValue != useOptionalTransitionApkPackage)
|
||||
{
|
||||
useOptionalTransitionApkPackage = newToggleValue;
|
||||
// Update transition APK status after changing package name option
|
||||
CheckForTransitionAPK();
|
||||
}
|
||||
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
GUIContent launchBtnTxt = new GUIContent("Launch App");
|
||||
var launchBtnRt = GUILayoutUtility.GetRect(launchBtnTxt, GUI.skin.button, GUILayout.ExpandWidth(true));
|
||||
if (GUI.Button(launchBtnRt, launchBtnTxt))
|
||||
{
|
||||
OVRBundleManager.LaunchApplication();
|
||||
}
|
||||
|
||||
var buildSettingBtnRt = GUILayoutUtility.GetRect(buildSettingsBtnTxt, GUI.skin.button, GUILayout.ExpandWidth(true));
|
||||
if (GUI.Button(buildSettingBtnRt, buildSettingsBtnTxt))
|
||||
{
|
||||
OpenBuildSettingsWindow();
|
||||
}
|
||||
|
||||
GUIContent uninstallTxt = new GUIContent("Uninstall APK");
|
||||
var uninstallBtnRt = GUILayoutUtility.GetRect(uninstallTxt, GUI.skin.button, GUILayout.ExpandWidth(true));
|
||||
if (GUI.Button(uninstallBtnRt, uninstallTxt))
|
||||
{
|
||||
OVRBundleManager.UninstallAPK();
|
||||
CheckForTransitionAPK();
|
||||
}
|
||||
|
||||
GUIContent clearLogTxt = new GUIContent("Clear Log");
|
||||
var clearLogBtnRt = GUILayoutUtility.GetRect(clearLogTxt, GUI.skin.button, GUILayout.ExpandWidth(true));
|
||||
if (GUI.Button(clearLogBtnRt, clearLogTxt))
|
||||
{
|
||||
PrintLog("", true);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUILayout.Space(10.0f);
|
||||
GUILayout.Label("Log", EditorStyles.boldLabel);
|
||||
|
||||
if (!string.IsNullOrEmpty(toolLog))
|
||||
{
|
||||
debugLogScroll = EditorGUILayout.BeginScrollView(debugLogScroll, GUILayout.ExpandHeight(true));
|
||||
EditorGUILayout.SelectableLabel(toolLog, logBoxStyle, GUILayout.Height(logBoxSize.y + logBoxSpacing));
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
}
|
||||
|
||||
private static void OpenBuildSettingsWindow()
|
||||
{
|
||||
EditorWindow.GetWindow(System.Type.GetType("UnityEditor.BuildPlayerWindow,UnityEditor"));
|
||||
}
|
||||
|
||||
public static void UpdateSceneBuildStatus(SceneBundleStatus status, int index = -1)
|
||||
{
|
||||
if (index >= 0 && index < buildableScenes.Count)
|
||||
{
|
||||
buildableScenes[index].buildStatus = status;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update status for all scenes
|
||||
for (int i = 0; i < buildableScenes.Count; i++)
|
||||
{
|
||||
buildableScenes[i].buildStatus = status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void GetScenesFromBuildSettings()
|
||||
{
|
||||
invalidBuildableScene = false;
|
||||
buildableScenes = new List<EditorSceneInfo>();
|
||||
for (int i = 0; i < EditorBuildSettings.scenes.Length; i++)
|
||||
{
|
||||
EditorBuildSettingsScene scene = EditorBuildSettings.scenes[i];
|
||||
if (scene.enabled)
|
||||
{
|
||||
if (Path.GetFileNameWithoutExtension(scene.path) != "OVRTransitionScene")
|
||||
{
|
||||
EditorSceneInfo sceneInfo = new EditorSceneInfo(scene.path, Path.GetFileNameWithoutExtension(scene.path));
|
||||
buildableScenes.Add(sceneInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
buildableScenes = null;
|
||||
invalidBuildableScene = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckForTransitionAPK()
|
||||
{
|
||||
OVRADBTool adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath());
|
||||
if (adbTool.isReady)
|
||||
{
|
||||
string matchedPackageList, error;
|
||||
var transitionPackageName = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.Android);
|
||||
if (useOptionalTransitionApkPackage)
|
||||
{
|
||||
transitionPackageName += ".transition";
|
||||
}
|
||||
string[] packageCheckCommand = new string[] { "-d shell pm list package", transitionPackageName };
|
||||
if (adbTool.RunCommand(packageCheckCommand, null, out matchedPackageList, out error) == 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(matchedPackageList))
|
||||
{
|
||||
currentApkStatus = ApkStatus.NOT_INSTALLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// adb "list package" command returns all package names that contains the given query package name
|
||||
// Need to check if the transition package name is matched exactly
|
||||
if (matchedPackageList.Contains("package:" + transitionPackageName + "\r\n"))
|
||||
{
|
||||
if (useOptionalTransitionApkPackage)
|
||||
{
|
||||
// If optional package name is used, it is deterministic that the transition apk is installed
|
||||
currentApkStatus = ApkStatus.OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
// get package info to check for TRANSITION_APK_VERSION_NAME
|
||||
string[] dumpPackageInfoCommand = new string[] { "-d shell dumpsys package", transitionPackageName };
|
||||
string packageInfo;
|
||||
if (adbTool.RunCommand(dumpPackageInfoCommand, null, out packageInfo, out error) == 0 &&
|
||||
!string.IsNullOrEmpty(packageInfo) &&
|
||||
packageInfo.Contains(OVRBundleManager.TRANSITION_APK_VERSION_NAME))
|
||||
{
|
||||
// Matched package name found, and the package info contains TRANSITION_APK_VERSION_NAME
|
||||
currentApkStatus = ApkStatus.OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentApkStatus = ApkStatus.NOT_INSTALLED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No matached package name returned
|
||||
currentApkStatus = ApkStatus.NOT_INSTALLED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (error.Contains("no devices found"))
|
||||
{
|
||||
currentApkStatus = ApkStatus.DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentApkStatus = ApkStatus.UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void PrintLog(string message, bool clear = false)
|
||||
{
|
||||
if (clear)
|
||||
{
|
||||
toolLog = message;
|
||||
}
|
||||
else
|
||||
{
|
||||
toolLog += message + "\n";
|
||||
}
|
||||
|
||||
GUIContent logContent = new GUIContent(toolLog);
|
||||
logBoxSize = logBoxStyle.CalcSize(logContent);
|
||||
|
||||
debugLogScroll.y = logBoxSize.y + logBoxSpacing;
|
||||
}
|
||||
|
||||
public static void PrintError(string error = "")
|
||||
{
|
||||
if(!string.IsNullOrEmpty(error))
|
||||
{
|
||||
toolLog += "<color=red>Failed!\n</color>" + error + "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
toolLog += "<color=red>Failed! Check Unity log for more details.\n</color>";
|
||||
}
|
||||
}
|
||||
|
||||
public static void PrintWarning(string warning)
|
||||
{
|
||||
toolLog += "<color=yellow>Warning!\n" + warning + "</color>\n";
|
||||
}
|
||||
|
||||
public static void PrintSuccess()
|
||||
{
|
||||
toolLog += "<color=green>Success!</color>\n";
|
||||
}
|
||||
|
||||
public static string GetEnumDescription(Enum eEnum)
|
||||
{
|
||||
Type enumType = eEnum.GetType();
|
||||
MemberInfo[] memberInfo = enumType.GetMember(eEnum.ToString());
|
||||
if (memberInfo != null && memberInfo.Length > 0)
|
||||
{
|
||||
var attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||
if (attrs != null && attrs.Length > 0)
|
||||
{
|
||||
return ((DescriptionAttribute)attrs[0]).Description;
|
||||
}
|
||||
}
|
||||
return eEnum.ToString();
|
||||
}
|
||||
|
||||
public static bool GetUseOptionalTransitionApkPackage()
|
||||
{
|
||||
return useOptionalTransitionApkPackage;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
Assets/Oculus/VR/Editor/OVRBundleTool.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRBundleTool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c27664370189a44bae1f4a8aba8b7ff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
188
Assets/Oculus/VR/Editor/OVRConfig.cs
Normal file
188
Assets/Oculus/VR/Editor/OVRConfig.cs
Normal file
@@ -0,0 +1,188 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
using System;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.InitializeOnLoad]
|
||||
#endif
|
||||
public class OVRConfig : ScriptableObject
|
||||
{
|
||||
[SerializeField]
|
||||
private string androidSDKPath = "";
|
||||
|
||||
[SerializeField]
|
||||
private string gradlePath = "";
|
||||
|
||||
[SerializeField]
|
||||
private string jdkPath = "";
|
||||
|
||||
private static OVRConfig instance;
|
||||
|
||||
public static OVRConfig Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = Resources.Load<OVRConfig>("OVRConfig");
|
||||
if (instance == null)
|
||||
{
|
||||
instance = ScriptableObject.CreateInstance<OVRConfig>();
|
||||
string resourcePath = Path.Combine(UnityEngine.Application.dataPath, "Resources");
|
||||
if (!Directory.Exists(resourcePath))
|
||||
{
|
||||
UnityEditor.AssetDatabase.CreateFolder("Assets", "Resources");
|
||||
}
|
||||
|
||||
string fullPath = Path.Combine(Path.Combine("Assets", "Resources"), "OVRBuildConfig.asset");
|
||||
UnityEditor.AssetDatabase.CreateAsset(instance, fullPath);
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
set
|
||||
{
|
||||
instance = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the path to the base directory of the Android SDK
|
||||
public string GetAndroidSDKPath(bool throwError = true)
|
||||
{
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
// Check for use of embedded path or user defined
|
||||
bool useEmbedded = EditorPrefs.GetBool("SdkUseEmbedded") || string.IsNullOrEmpty(EditorPrefs.GetString("AndroidSdkRoot"));
|
||||
if (useEmbedded)
|
||||
{
|
||||
androidSDKPath = Path.Combine(BuildPipeline.GetPlaybackEngineDirectory(BuildTarget.Android, BuildOptions.None), "SDK");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
androidSDKPath = EditorPrefs.GetString("AndroidSdkRoot");
|
||||
}
|
||||
|
||||
androidSDKPath = androidSDKPath.Replace("/", "\\");
|
||||
// Validate sdk path and notify user if path does not exist.
|
||||
if (!Directory.Exists(androidSDKPath))
|
||||
{
|
||||
androidSDKPath = Environment.GetEnvironmentVariable("ANDROID_SDK_ROOT");
|
||||
if (!string.IsNullOrEmpty(androidSDKPath))
|
||||
{
|
||||
return androidSDKPath;
|
||||
}
|
||||
|
||||
if (throwError)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Android SDK not Found",
|
||||
"Android SDK not found. Please ensure that the path is set correctly in (Edit -> Preferences -> External Tools) or that the Untiy Android module is installed correctly.",
|
||||
"Ok");
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(Instance);
|
||||
return androidSDKPath;
|
||||
}
|
||||
|
||||
// Returns the path to the gradle-launcher-*.jar
|
||||
public string GetGradlePath(bool throwError = true)
|
||||
{
|
||||
string libPath = "";
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
// Check for use of embedded path or user defined
|
||||
bool useEmbedded = EditorPrefs.GetBool("GradleUseEmbedded") || string.IsNullOrEmpty(EditorPrefs.GetString("GradlePath"));
|
||||
|
||||
if (useEmbedded)
|
||||
{
|
||||
libPath = Path.Combine(BuildPipeline.GetPlaybackEngineDirectory(BuildTarget.Android, BuildOptions.None), "Tools\\gradle\\lib");
|
||||
}
|
||||
else
|
||||
{
|
||||
libPath = Path.Combine(EditorPrefs.GetString("GradlePath"), "lib");
|
||||
}
|
||||
#else
|
||||
libPath = Path.Combine(EditorApplication.applicationContentsPath, "PlaybackEngines\\AndroidPlayer\\Tools\\gradle\\lib");
|
||||
#endif
|
||||
|
||||
libPath = libPath.Replace("/", "\\");
|
||||
if (!string.IsNullOrEmpty(libPath) && Directory.Exists(libPath))
|
||||
{
|
||||
string[] gradleJar = Directory.GetFiles(libPath, "gradle-launcher-*.jar");
|
||||
if (gradleJar.Length == 1)
|
||||
{
|
||||
gradlePath = gradleJar[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Validate gradle path and notify user if path does not exist.
|
||||
if (!File.Exists(gradlePath))
|
||||
{
|
||||
if (throwError)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Gradle not Found",
|
||||
"Gradle not found. Please ensure that the path is set correctly in (Edit -> Preferences -> External Tools) or that the Untiy Android module is installed correctly.",
|
||||
"Ok");
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(Instance);
|
||||
return gradlePath;
|
||||
}
|
||||
|
||||
// Returns path to the Java executable in the JDK
|
||||
public string GetJDKPath(bool throwError = true)
|
||||
{
|
||||
#if UNITY_EDITOR_WIN
|
||||
// Check for use of embedded path or user defined
|
||||
bool useEmbedded = EditorPrefs.GetBool("JdkUseEmbedded") || string.IsNullOrEmpty(EditorPrefs.GetString("JdkPath"));
|
||||
|
||||
string exePath = "";
|
||||
if (useEmbedded)
|
||||
{
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
exePath = Path.Combine(BuildPipeline.GetPlaybackEngineDirectory(BuildTarget.Android, BuildOptions.None), "Tools\\OpenJDK\\Windows\\bin");
|
||||
#else
|
||||
exePath = Path.Combine(EditorApplication.applicationContentsPath, "PlaybackEngines\\AndroidPlayer\\Tools\\OpenJDK\\Windows\\bin");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
exePath = Path.Combine(EditorPrefs.GetString("JdkPath"), "bin");
|
||||
}
|
||||
|
||||
jdkPath = Path.Combine(exePath, "java.exe");
|
||||
jdkPath = jdkPath.Replace("/", "\\");
|
||||
|
||||
// Validate gradle path and notify user if path does not exist.
|
||||
if (!File.Exists(jdkPath))
|
||||
{
|
||||
// Check the enviornment variable as a backup to see if the JDK is there.
|
||||
string javaHome = Environment.GetEnvironmentVariable("JAVA_HOME");
|
||||
if(!string.IsNullOrEmpty(javaHome))
|
||||
{
|
||||
jdkPath = Path.Combine(javaHome, "bin\\java.exe");
|
||||
if(File.Exists(jdkPath))
|
||||
{
|
||||
EditorUtility.SetDirty(Instance);
|
||||
return jdkPath;
|
||||
}
|
||||
}
|
||||
|
||||
if (throwError)
|
||||
{
|
||||
EditorUtility.DisplayDialog("JDK not Found",
|
||||
"JDK not found. Please ensure that the path is set correctly in (Edit -> Preferences -> External Tools) or that the Untiy Android module is installed correctly.",
|
||||
"Ok");
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
#endif
|
||||
EditorUtility.SetDirty(Instance);
|
||||
return jdkPath;
|
||||
}
|
||||
}
|
||||
11
Assets/Oculus/VR/Editor/OVRConfig.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRConfig.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20553fac56ec59645857c0732b787431
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
53
Assets/Oculus/VR/Editor/OVRDeviceSelector.cs
Normal file
53
Assets/Oculus/VR/Editor/OVRDeviceSelector.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
public class OVRDeviceSelector
|
||||
{
|
||||
public static bool isTargetDeviceQuestFamily
|
||||
{
|
||||
get
|
||||
{
|
||||
return isTargetDeviceQuest || isTargetDeviceQuest2;
|
||||
}
|
||||
}
|
||||
public static bool isTargetDeviceQuest
|
||||
{
|
||||
get
|
||||
{
|
||||
OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig();
|
||||
return projectConfig.targetDeviceTypes.Contains(OVRProjectConfig.DeviceType.Quest);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool isTargetDeviceQuest2
|
||||
{
|
||||
get
|
||||
{
|
||||
OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig();
|
||||
return projectConfig.targetDeviceTypes.Contains(OVRProjectConfig.DeviceType.Quest2);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Oculus/VR/Editor/OVRDeviceSelector.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRDeviceSelector.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 157dce969e882084080e0a2c39efe398
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
242
Assets/Oculus/VR/Editor/OVRDirectorySyncer.cs
Normal file
242
Assets/Oculus/VR/Editor/OVRDirectorySyncer.cs
Normal file
@@ -0,0 +1,242 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System;
|
||||
|
||||
public class DirectorySyncer
|
||||
{
|
||||
public delegate void SyncResultDelegate(SyncResult syncResult);
|
||||
|
||||
public readonly string Source;
|
||||
public readonly string Target;
|
||||
public SyncResultDelegate WillPerformOperations;
|
||||
private readonly Regex _ignoreExpression;
|
||||
|
||||
// helper classes to simplify transition beyond .NET runtime 3.5
|
||||
public abstract class CancellationToken
|
||||
{
|
||||
protected abstract bool _IsCancellationRequested();
|
||||
|
||||
public virtual bool IsCancellationRequested
|
||||
{
|
||||
get { return _IsCancellationRequested(); }
|
||||
}
|
||||
|
||||
public void ThrowIfCancellationRequested()
|
||||
{
|
||||
if (IsCancellationRequested)
|
||||
{
|
||||
throw new Exception("Operation Cancelled");
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly CancellationToken None = new CancellationTokenNone();
|
||||
|
||||
private class CancellationTokenNone : CancellationToken
|
||||
{
|
||||
protected override bool _IsCancellationRequested()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CancellationTokenSource : CancellationToken
|
||||
{
|
||||
private bool _isCancelled;
|
||||
|
||||
protected override bool _IsCancellationRequested()
|
||||
{
|
||||
return _isCancelled;
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
_isCancelled = true;
|
||||
}
|
||||
|
||||
public CancellationToken Token
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
}
|
||||
|
||||
private static string EnsureTrailingDirectorySeparator(string path)
|
||||
{
|
||||
return path.EndsWith("" + Path.DirectorySeparatorChar)
|
||||
? path
|
||||
: path + Path.DirectorySeparatorChar;
|
||||
}
|
||||
|
||||
private static string CheckedDirectory(string nameInExceptionText, string directory)
|
||||
{
|
||||
directory = Path.GetFullPath(directory);
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
throw new ArgumentException(string.Format("{0} is not a valid directory for argument ${1}", directory,
|
||||
nameInExceptionText));
|
||||
}
|
||||
|
||||
return EnsureTrailingDirectorySeparator(directory);
|
||||
}
|
||||
|
||||
public DirectorySyncer(string source, string target, string ignoreRegExPattern = null)
|
||||
{
|
||||
Source = CheckedDirectory("source", source);
|
||||
Target = CheckedDirectory("target", target);
|
||||
if (Source.StartsWith(Target, StringComparison.OrdinalIgnoreCase) ||
|
||||
Target.StartsWith(Source, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new ArgumentException(string.Format("Paths must not contain each other (source: {0}, target: {1}",
|
||||
Source, Target));
|
||||
}
|
||||
|
||||
ignoreRegExPattern = ignoreRegExPattern ?? "^$";
|
||||
_ignoreExpression = new Regex(ignoreRegExPattern, RegexOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
public class SyncResult
|
||||
{
|
||||
public readonly IEnumerable<string> Created;
|
||||
public readonly IEnumerable<string> Updated;
|
||||
public readonly IEnumerable<string> Deleted;
|
||||
|
||||
public SyncResult(IEnumerable<string> created, IEnumerable<string> updated, IEnumerable<string> deleted)
|
||||
{
|
||||
Created = created;
|
||||
Updated = updated;
|
||||
Deleted = deleted;
|
||||
}
|
||||
}
|
||||
|
||||
public bool RelativeFilePathIsRelevant(string relativeFilename)
|
||||
{
|
||||
return !_ignoreExpression.IsMatch(relativeFilename);
|
||||
}
|
||||
|
||||
public bool RelativeDirectoryPathIsRelevant(string relativeDirName)
|
||||
{
|
||||
// Since our ignore patterns look at file names, they may contain trailing path separators
|
||||
// In order for paths to match those rules, we add a path separator here
|
||||
return !_ignoreExpression.IsMatch(EnsureTrailingDirectorySeparator(relativeDirName));
|
||||
}
|
||||
|
||||
private HashSet<string> RelevantRelativeFilesBeneathDirectory(string path, CancellationToken cancellationToken)
|
||||
{
|
||||
return new HashSet<string>(Directory.GetFiles(path, "*", SearchOption.AllDirectories)
|
||||
.TakeWhile((s) => !cancellationToken.IsCancellationRequested)
|
||||
.Select(p => PathHelper.MakeRelativePath(path, p)).Where(RelativeFilePathIsRelevant));
|
||||
}
|
||||
|
||||
private HashSet<string> RelevantRelativeDirectoriesBeneathDirectory(string path,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return new HashSet<string>(Directory.GetDirectories(path, "*", SearchOption.AllDirectories)
|
||||
.TakeWhile((s) => !cancellationToken.IsCancellationRequested)
|
||||
.Select(p => PathHelper.MakeRelativePath(path, p)).Where(RelativeDirectoryPathIsRelevant));
|
||||
}
|
||||
|
||||
public SyncResult Synchronize()
|
||||
{
|
||||
return Synchronize(CancellationToken.None);
|
||||
}
|
||||
|
||||
private void DeleteOutdatedFilesFromTarget(SyncResult syncResult, CancellationToken cancellationToken)
|
||||
{
|
||||
var outdatedFiles = syncResult.Updated.Union(syncResult.Deleted);
|
||||
foreach (var fileName in outdatedFiles)
|
||||
{
|
||||
File.Delete(Path.Combine(Target, fileName));
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "ParameterTypeCanBeEnumerable.Local")]
|
||||
private void DeleteOutdatedEmptyDirectoriesFromTarget(HashSet<string> sourceDirs, HashSet<string> targetDirs,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var deleted = targetDirs.Except(sourceDirs).OrderByDescending(s => s);
|
||||
|
||||
// By sorting in descending order above, we delete leaf-first,
|
||||
// this is simpler than collapsing the list above (which would also allow us to run these ops in parallel).
|
||||
// Assumption is that there are few empty folders to delete
|
||||
foreach (var dir in deleted)
|
||||
{
|
||||
Directory.Delete(Path.Combine(Target, dir));
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "ParameterTypeCanBeEnumerable.Local")]
|
||||
private void CreateRelevantDirectoriesAtTarget(HashSet<string> sourceDirs, HashSet<string> targetDirs,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var created = sourceDirs.Except(targetDirs);
|
||||
foreach (var dir in created)
|
||||
{
|
||||
Directory.CreateDirectory(Path.Combine(Target, dir));
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveRelevantFilesToTarget(SyncResult syncResult, CancellationToken cancellationToken)
|
||||
{
|
||||
// step 3: we move all new files to target
|
||||
var newFiles = syncResult.Created.Union(syncResult.Updated);
|
||||
foreach (var fileName in newFiles)
|
||||
{
|
||||
var sourceFileName = Path.Combine(Source, fileName);
|
||||
var destFileName = Path.Combine(Target, fileName);
|
||||
// target directory exists due to step CreateRelevantDirectoriesAtTarget()
|
||||
File.Move(sourceFileName, destFileName);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
}
|
||||
|
||||
public SyncResult Synchronize(CancellationToken cancellationToken)
|
||||
{
|
||||
var sourceDirs = RelevantRelativeDirectoriesBeneathDirectory(Source, cancellationToken);
|
||||
var targetDirs = RelevantRelativeDirectoriesBeneathDirectory(Target, cancellationToken);
|
||||
var sourceFiles = RelevantRelativeFilesBeneathDirectory(Source, cancellationToken);
|
||||
var targetFiles = RelevantRelativeFilesBeneathDirectory(Target, cancellationToken);
|
||||
|
||||
var created = sourceFiles.Except(targetFiles).OrderBy(s => s).ToList();
|
||||
var updated = sourceFiles.Intersect(targetFiles).OrderBy(s => s).ToList();
|
||||
var deleted = targetFiles.Except(sourceFiles).OrderBy(s => s).ToList();
|
||||
var syncResult = new SyncResult(created, updated, deleted);
|
||||
|
||||
if (WillPerformOperations != null)
|
||||
{
|
||||
WillPerformOperations.Invoke(syncResult);
|
||||
}
|
||||
|
||||
DeleteOutdatedFilesFromTarget(syncResult, cancellationToken);
|
||||
DeleteOutdatedEmptyDirectoriesFromTarget(sourceDirs, targetDirs, cancellationToken);
|
||||
CreateRelevantDirectoriesAtTarget(sourceDirs, targetDirs, cancellationToken);
|
||||
MoveRelevantFilesToTarget(syncResult, cancellationToken);
|
||||
|
||||
return syncResult;
|
||||
}
|
||||
}
|
||||
11
Assets/Oculus/VR/Editor/OVRDirectorySyncer.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRDirectorySyncer.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 666774827ce57754f9fbd8e008ed0a2a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
276
Assets/Oculus/VR/Editor/OVREngineConfigurationUpdater.cs
Normal file
276
Assets/Oculus/VR/Editor/OVREngineConfigurationUpdater.cs
Normal file
@@ -0,0 +1,276 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
#if USING_XR_MANAGEMENT && USING_XR_SDK_OCULUS
|
||||
#define USING_XR_SDK
|
||||
#endif
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
#define REQUIRES_XR_SDK
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
[InitializeOnLoad]
|
||||
class OVREngineConfigurationUpdater
|
||||
{
|
||||
private const string prefName = "OVREngineConfigurationUpdater_Enabled";
|
||||
private const string menuItemName = "Oculus/Tools/Use Required Project Settings";
|
||||
private const string androidAssetsPath = "Assets/Plugins/Android/assets";
|
||||
private const string androidManifestPath = "Assets/Plugins/Android/AndroidManifest.xml";
|
||||
static bool setPrefsForUtilities;
|
||||
|
||||
[MenuItem(menuItemName)]
|
||||
static void ToggleUtilities()
|
||||
{
|
||||
setPrefsForUtilities = !setPrefsForUtilities;
|
||||
Menu.SetChecked(menuItemName, setPrefsForUtilities);
|
||||
|
||||
int newValue = (setPrefsForUtilities) ? 1 : 0;
|
||||
PlayerPrefs.SetInt(prefName, newValue);
|
||||
PlayerPrefs.Save();
|
||||
|
||||
Debug.Log("Using required project settings: " + setPrefsForUtilities);
|
||||
}
|
||||
|
||||
private static readonly string dashSupportEnableConfirmedKey = "Oculus_Utilities_OVREngineConfiguration_DashSupportEnableConfirmed_" + Application.unityVersion + OVRManager.utilitiesVersion;
|
||||
private static bool dashSupportEnableConfirmed
|
||||
{
|
||||
get
|
||||
{
|
||||
return PlayerPrefs.GetInt(dashSupportEnableConfirmedKey, 0) == 1;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
PlayerPrefs.SetInt(dashSupportEnableConfirmedKey, value ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static OVREngineConfigurationUpdater()
|
||||
{
|
||||
EditorApplication.delayCall += OnDelayCall;
|
||||
EditorApplication.update += OnUpdate;
|
||||
}
|
||||
|
||||
static void OnDelayCall()
|
||||
{
|
||||
setPrefsForUtilities = PlayerPrefs.GetInt(prefName, 1) != 0;
|
||||
Menu.SetChecked(menuItemName, setPrefsForUtilities);
|
||||
|
||||
if (!setPrefsForUtilities)
|
||||
return;
|
||||
|
||||
OVRPlugin.AddCustomMetadata("build_target", EditorUserBuildSettings.activeBuildTarget.ToString());
|
||||
EnforceAndroidSettings();
|
||||
EnforceInputManagerBindings();
|
||||
}
|
||||
|
||||
static void OnUpdate()
|
||||
{
|
||||
if (!setPrefsForUtilities)
|
||||
return;
|
||||
|
||||
EnforceBundleId();
|
||||
EnforceVRSupport();
|
||||
EnforceInstallLocation();
|
||||
}
|
||||
|
||||
static void EnforceAndroidSettings()
|
||||
{
|
||||
if (EditorUserBuildSettings.activeBuildTarget != BuildTarget.Android)
|
||||
return;
|
||||
|
||||
if (PlayerSettings.defaultInterfaceOrientation != UIOrientation.LandscapeLeft)
|
||||
{
|
||||
Debug.Log("OVREngineConfigurationUpdater: Setting orientation to Landscape Left");
|
||||
// Default screen orientation must be set to landscape left.
|
||||
PlayerSettings.defaultInterfaceOrientation = UIOrientation.LandscapeLeft;
|
||||
}
|
||||
|
||||
#if !USING_XR_SDK && !REQUIRES_XR_SDK
|
||||
if (!PlayerSettings.virtualRealitySupported)
|
||||
{
|
||||
// NOTE: This value should not affect the main window surface
|
||||
// when Built-in VR support is enabled.
|
||||
|
||||
// NOTE: On Adreno Lollipop, it is an error to have antiAliasing set on the
|
||||
// main window surface with front buffer rendering enabled. The view will
|
||||
// render black.
|
||||
// On Adreno KitKat, some tiling control modes will cause the view to render
|
||||
// black.
|
||||
if (QualitySettings.antiAliasing != 0 && QualitySettings.antiAliasing != 1)
|
||||
{
|
||||
Debug.Log("OVREngineConfigurationUpdater: Disabling antiAliasing");
|
||||
QualitySettings.antiAliasing = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (QualitySettings.vSyncCount != 0)
|
||||
{
|
||||
Debug.Log("OVREngineConfigurationUpdater: Setting vsyncCount to 0");
|
||||
// We sync in the TimeWarp, so we don't want unity syncing elsewhere.
|
||||
QualitySettings.vSyncCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void EnforceVRSupport()
|
||||
{
|
||||
#if !USING_XR_SDK && !REQUIRES_XR_SDK
|
||||
if (PlayerSettings.virtualRealitySupported)
|
||||
return;
|
||||
|
||||
var mgrs = GameObject.FindObjectsOfType<OVRManager>();
|
||||
for (int i = 0; i < mgrs.Length; ++i)
|
||||
{
|
||||
if (mgrs [i].isActiveAndEnabled)
|
||||
{
|
||||
Debug.Log ("Enabling Unity VR support");
|
||||
PlayerSettings.virtualRealitySupported = true;
|
||||
|
||||
bool oculusFound = false;
|
||||
foreach (var device in UnityEngine.XR.XRSettings.supportedDevices)
|
||||
oculusFound |= (device == "Oculus");
|
||||
|
||||
if (!oculusFound)
|
||||
Debug.LogError("Please add Oculus to the list of supported devices to use the Utilities.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void EnforceBundleId()
|
||||
{
|
||||
bool shouldEnforceBundleId = false;
|
||||
#if USING_XR_SDK
|
||||
shouldEnforceBundleId = true;
|
||||
#elif !REQUIRES_XR_SDK
|
||||
if (PlayerSettings.virtualRealitySupported)
|
||||
shouldEnforceBundleId = true;
|
||||
#endif
|
||||
|
||||
if (shouldEnforceBundleId)
|
||||
{
|
||||
if (PlayerSettings.applicationIdentifier == "" || PlayerSettings.applicationIdentifier == "com.Company.ProductName")
|
||||
{
|
||||
string defaultBundleId = "com.oculus.UnitySample";
|
||||
Debug.LogWarning("\"" + PlayerSettings.applicationIdentifier + "\" is not a valid bundle identifier. Defaulting to \"" + defaultBundleId + "\".");
|
||||
PlayerSettings.applicationIdentifier = defaultBundleId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnforceInstallLocation()
|
||||
{
|
||||
if (PlayerSettings.Android.preferredInstallLocation != AndroidPreferredInstallLocation.Auto)
|
||||
PlayerSettings.Android.preferredInstallLocation = AndroidPreferredInstallLocation.Auto;
|
||||
}
|
||||
|
||||
private static void EnforceInputManagerBindings()
|
||||
{
|
||||
try
|
||||
{
|
||||
BindAxis(new Axis() { name = "Oculus_CrossPlatform_Button2", positiveButton = "joystick button 0", gravity = 1000f, sensitivity = 1000f, type = 0 });
|
||||
BindAxis(new Axis() { name = "Oculus_CrossPlatform_Button4", positiveButton = "joystick button 2", gravity = 1000f, sensitivity = 1000f, type = 0 });
|
||||
BindAxis(new Axis() { name = "Oculus_CrossPlatform_PrimaryThumbstick", positiveButton = "joystick button 8", gravity = 0f, dead = 0f, sensitivity = 0.1f, type = 0 });
|
||||
BindAxis(new Axis() { name = "Oculus_CrossPlatform_SecondaryThumbstick", positiveButton = "joystick button 9", gravity = 0f, dead = 0f, sensitivity = 0.1f, type = 0 });
|
||||
BindAxis(new Axis() { name = "Oculus_CrossPlatform_PrimaryIndexTrigger", dead = 0.19f, type = 2, axis = 8, joyNum = 0 });
|
||||
BindAxis(new Axis() { name = "Oculus_CrossPlatform_SecondaryIndexTrigger", dead = 0.19f, type = 2, axis = 9, joyNum = 0 });
|
||||
BindAxis(new Axis() { name = "Oculus_CrossPlatform_PrimaryHandTrigger", dead = 0.19f, type = 2, axis = 10, joyNum = 0 });
|
||||
BindAxis(new Axis() { name = "Oculus_CrossPlatform_SecondaryHandTrigger", dead = 0.19f, type = 2, axis = 11, joyNum = 0 });
|
||||
BindAxis(new Axis() { name = "Oculus_CrossPlatform_PrimaryThumbstickHorizontal", dead = 0.19f, type = 2, axis = 0, joyNum = 0 });
|
||||
BindAxis(new Axis() { name = "Oculus_CrossPlatform_PrimaryThumbstickVertical", dead = 0.19f, type = 2, axis = 1, joyNum = 0, invert = true });
|
||||
BindAxis(new Axis() { name = "Oculus_CrossPlatform_SecondaryThumbstickHorizontal", dead = 0.19f, type = 2, axis = 3, joyNum = 0 });
|
||||
BindAxis(new Axis() { name = "Oculus_CrossPlatform_SecondaryThumbstickVertical", dead = 0.19f, type = 2, axis = 4, joyNum = 0, invert = true });
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.LogError("Failed to apply Oculus input manager bindings.");
|
||||
}
|
||||
}
|
||||
|
||||
private class Axis
|
||||
{
|
||||
public string name = String.Empty;
|
||||
public string descriptiveName = String.Empty;
|
||||
public string descriptiveNegativeName = String.Empty;
|
||||
public string negativeButton = String.Empty;
|
||||
public string positiveButton = String.Empty;
|
||||
public string altNegativeButton = String.Empty;
|
||||
public string altPositiveButton = String.Empty;
|
||||
public float gravity = 0.0f;
|
||||
public float dead = 0.001f;
|
||||
public float sensitivity = 1.0f;
|
||||
public bool snap = false;
|
||||
public bool invert = false;
|
||||
public int type = 2;
|
||||
public int axis = 0;
|
||||
public int joyNum = 0;
|
||||
}
|
||||
|
||||
private static void BindAxis(Axis axis)
|
||||
{
|
||||
SerializedObject serializedObject = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/InputManager.asset")[0]);
|
||||
SerializedProperty axesProperty = serializedObject.FindProperty("m_Axes");
|
||||
|
||||
SerializedProperty axisIter = axesProperty.Copy();
|
||||
axisIter.Next(true);
|
||||
axisIter.Next(true);
|
||||
while (axisIter.Next(false))
|
||||
{
|
||||
if (axisIter.FindPropertyRelative("m_Name").stringValue == axis.name)
|
||||
{
|
||||
// Axis already exists. Don't create binding.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
axesProperty.arraySize++;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
SerializedProperty axisProperty = axesProperty.GetArrayElementAtIndex(axesProperty.arraySize - 1);
|
||||
axisProperty.FindPropertyRelative("m_Name").stringValue = axis.name;
|
||||
axisProperty.FindPropertyRelative("descriptiveName").stringValue = axis.descriptiveName;
|
||||
axisProperty.FindPropertyRelative("descriptiveNegativeName").stringValue = axis.descriptiveNegativeName;
|
||||
axisProperty.FindPropertyRelative("negativeButton").stringValue = axis.negativeButton;
|
||||
axisProperty.FindPropertyRelative("positiveButton").stringValue = axis.positiveButton;
|
||||
axisProperty.FindPropertyRelative("altNegativeButton").stringValue = axis.altNegativeButton;
|
||||
axisProperty.FindPropertyRelative("altPositiveButton").stringValue = axis.altPositiveButton;
|
||||
axisProperty.FindPropertyRelative("gravity").floatValue = axis.gravity;
|
||||
axisProperty.FindPropertyRelative("dead").floatValue = axis.dead;
|
||||
axisProperty.FindPropertyRelative("sensitivity").floatValue = axis.sensitivity;
|
||||
axisProperty.FindPropertyRelative("snap").boolValue = axis.snap;
|
||||
axisProperty.FindPropertyRelative("invert").boolValue = axis.invert;
|
||||
axisProperty.FindPropertyRelative("type").intValue = axis.type;
|
||||
axisProperty.FindPropertyRelative("axis").intValue = axis.axis;
|
||||
axisProperty.FindPropertyRelative("joyNum").intValue = axis.joyNum;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c86538ded11bfe24c8c79818bb9ea66a
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
96
Assets/Oculus/VR/Editor/OVRExpansionFileGenerator.cs
Normal file
96
Assets/Oculus/VR/Editor/OVRExpansionFileGenerator.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
public class BuildAssetBundles : MonoBehaviour
|
||||
{
|
||||
[MenuItem("Oculus/Tools/Build Mobile-Quest Expansion File", false, 100000)]
|
||||
public static void BuildBundles()
|
||||
{
|
||||
// Create expansion file directory and call build asset bundles
|
||||
string path = Application.dataPath + "/../Asset Bundles/";
|
||||
if (!System.IO.Directory.Exists(path))
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(path);
|
||||
}
|
||||
BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.Android);
|
||||
|
||||
// Rename asset bundle file to the proper obb string
|
||||
if (File.Exists(path + "Asset Bundles"))
|
||||
{
|
||||
string expansionName = "main." + PlayerSettings.Android.bundleVersionCode + "." + PlayerSettings.applicationIdentifier + ".obb";
|
||||
try
|
||||
{
|
||||
if (File.Exists(path + expansionName))
|
||||
{
|
||||
File.Delete(path + expansionName);
|
||||
}
|
||||
File.Move(path + "Asset Bundles", path + expansionName);
|
||||
UnityEngine.Debug.Log("OBB expansion file " + expansionName + " has been successfully created at " + path);
|
||||
|
||||
UpdateAndroidManifest();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogError(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateAndroidManifest()
|
||||
{
|
||||
string manifestFolder = Application.dataPath + "/Plugins/Android";
|
||||
try
|
||||
{
|
||||
// Load android manfiest file
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(manifestFolder + "/AndroidManifest.xml");
|
||||
|
||||
string androidNamepsaceURI;
|
||||
XmlElement element = (XmlElement)doc.SelectSingleNode("/manifest");
|
||||
if(element == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Could not find manifest tag in android manifest.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get android namespace URI from the manifest
|
||||
androidNamepsaceURI = element.GetAttribute("xmlns:android");
|
||||
if (!string.IsNullOrEmpty(androidNamepsaceURI))
|
||||
{
|
||||
// Check if the android manifest already has the read external storage permission
|
||||
XmlNodeList nodeList = doc.SelectNodes("/manifest/application/uses-permission");
|
||||
foreach (XmlElement e in nodeList)
|
||||
{
|
||||
string attr = e.GetAttribute("name", androidNamepsaceURI);
|
||||
if (attr == "android.permission.READ_EXTERNAL_STORAGE")
|
||||
{
|
||||
UnityEngine.Debug.Log("Android manifest already has the proper permissions.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
element = (XmlElement)doc.SelectSingleNode("/manifest/application");
|
||||
if (element != null)
|
||||
{
|
||||
// Insert read external storage permission
|
||||
XmlElement newElement = doc.CreateElement("uses-permission");
|
||||
newElement.SetAttribute("name", androidNamepsaceURI, "android.permission.READ_EXTERNAL_STORAGE");
|
||||
element.AppendChild(newElement);
|
||||
|
||||
doc.Save(manifestFolder + "/AndroidManifest.xml");
|
||||
UnityEngine.Debug.Log("Successfully modified android manifest with external storage permission.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UnityEngine.Debug.LogError("Could not find android naemspace URI in android manifest.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogError(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Oculus/VR/Editor/OVRExpansionFileGenerator.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRExpansionFileGenerator.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2a0ba46d78379541a5f56225e034afa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
434
Assets/Oculus/VR/Editor/OVRGradleGeneration.cs
Normal file
434
Assets/Oculus/VR/Editor/OVRGradleGeneration.cs
Normal file
@@ -0,0 +1,434 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
//#define BUILDSESSION
|
||||
|
||||
#if USING_XR_MANAGEMENT && USING_XR_SDK_OCULUS
|
||||
#define USING_XR_SDK
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
#if UNITY_ANDROID
|
||||
using UnityEditor.Android;
|
||||
#endif
|
||||
|
||||
[InitializeOnLoad]
|
||||
public class OVRGradleGeneration
|
||||
: IPreprocessBuildWithReport, IPostprocessBuildWithReport
|
||||
#if UNITY_ANDROID
|
||||
, IPostGenerateGradleAndroidProject
|
||||
#endif
|
||||
{
|
||||
public OVRADBTool adbTool;
|
||||
public Process adbProcess;
|
||||
|
||||
public int callbackOrder { get { return 99999; } }
|
||||
static private System.DateTime buildStartTime;
|
||||
static private System.Guid buildGuid;
|
||||
|
||||
#if UNITY_ANDROID
|
||||
private const string prefName = "OVRAutoIncrementVersionCode_Enabled";
|
||||
private const string menuItemAutoIncVersion = "Oculus/Tools/Auto Increment Version Code";
|
||||
static bool autoIncrementVersion = false;
|
||||
#endif
|
||||
|
||||
static OVRGradleGeneration()
|
||||
{
|
||||
EditorApplication.delayCall += OnDelayCall;
|
||||
}
|
||||
|
||||
static void OnDelayCall()
|
||||
{
|
||||
#if UNITY_ANDROID
|
||||
autoIncrementVersion = PlayerPrefs.GetInt(prefName, 0) != 0;
|
||||
Menu.SetChecked(menuItemAutoIncVersion, autoIncrementVersion);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_ANDROID
|
||||
[MenuItem(menuItemAutoIncVersion)]
|
||||
static void ToggleUtilities()
|
||||
{
|
||||
autoIncrementVersion = !autoIncrementVersion;
|
||||
Menu.SetChecked(menuItemAutoIncVersion, autoIncrementVersion);
|
||||
|
||||
int newValue = (autoIncrementVersion) ? 1 : 0;
|
||||
PlayerPrefs.SetInt(prefName, newValue);
|
||||
PlayerPrefs.Save();
|
||||
|
||||
UnityEngine.Debug.Log("Auto Increment Version Code: " + autoIncrementVersion);
|
||||
}
|
||||
#endif
|
||||
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
#if UNITY_ANDROID && !(USING_XR_SDK && UNITY_2019_3_OR_NEWER)
|
||||
// Generate error when Vulkan is selected as the perferred graphics API, which is not currently supported in Unity XR
|
||||
if (!PlayerSettings.GetUseDefaultGraphicsAPIs(BuildTarget.Android))
|
||||
{
|
||||
GraphicsDeviceType[] apis = PlayerSettings.GetGraphicsAPIs(BuildTarget.Android);
|
||||
if (apis.Length >= 1 && apis[0] == GraphicsDeviceType.Vulkan)
|
||||
{
|
||||
throw new BuildFailedException("The Vulkan Graphics API does not support XR in your configuration. To use Vulkan, you must use Unity 2019.3 or newer, and the XR Plugin Management.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
buildStartTime = System.DateTime.Now;
|
||||
buildGuid = System.Guid.NewGuid();
|
||||
|
||||
if (!report.summary.outputPath.Contains("OVRGradleTempExport"))
|
||||
{
|
||||
OVRPlugin.SetDeveloperMode(OVRPlugin.Bool.True);
|
||||
OVRPlugin.AddCustomMetadata("build_type", "standard");
|
||||
}
|
||||
|
||||
OVRPlugin.AddCustomMetadata("build_guid", buildGuid.ToString());
|
||||
OVRPlugin.AddCustomMetadata("target_platform", report.summary.platform.ToString());
|
||||
#if !UNITY_2019_3_OR_NEWER
|
||||
OVRPlugin.AddCustomMetadata("scripting_runtime_version", UnityEditor.PlayerSettings.scriptingRuntimeVersion.ToString());
|
||||
#endif
|
||||
if (report.summary.platform == UnityEditor.BuildTarget.StandaloneWindows
|
||||
|| report.summary.platform == UnityEditor.BuildTarget.StandaloneWindows64)
|
||||
{
|
||||
OVRPlugin.AddCustomMetadata("target_oculus_platform", "rift");
|
||||
}
|
||||
#if BUILDSESSION
|
||||
StreamWriter writer = new StreamWriter("build_session", false);
|
||||
UnityEngine.Debug.LogFormat("Build Session: {0}", buildGuid.ToString());
|
||||
writer.WriteLine(buildGuid.ToString());
|
||||
writer.Close();
|
||||
#endif
|
||||
}
|
||||
|
||||
public void OnPostGenerateGradleAndroidProject(string path)
|
||||
{
|
||||
UnityEngine.Debug.Log("OVRGradleGeneration triggered.");
|
||||
|
||||
var targetOculusPlatform = new List<string>();
|
||||
if (OVRDeviceSelector.isTargetDeviceQuestFamily)
|
||||
{
|
||||
targetOculusPlatform.Add("quest");
|
||||
}
|
||||
OVRPlugin.AddCustomMetadata("target_oculus_platform", String.Join("_", targetOculusPlatform.ToArray()));
|
||||
UnityEngine.Debug.LogFormat("QuestFamily = {0}: Quest = {1}, Quest2 = {2}",
|
||||
OVRDeviceSelector.isTargetDeviceQuestFamily,
|
||||
OVRDeviceSelector.isTargetDeviceQuest,
|
||||
OVRDeviceSelector.isTargetDeviceQuest2);
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
string gradleBuildPath = Path.Combine(path, "../launcher/build.gradle");
|
||||
#else
|
||||
string gradleBuildPath = Path.Combine(path, "build.gradle");
|
||||
#endif
|
||||
bool v2SigningEnabled = true;
|
||||
|
||||
if (File.Exists(gradleBuildPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
string gradle = File.ReadAllText(gradleBuildPath);
|
||||
int v2Signingindex = gradle.IndexOf("v2SigningEnabled false");
|
||||
|
||||
if (v2Signingindex != -1)
|
||||
{
|
||||
//v2 Signing flag found, ensure the correct value is set based on platform.
|
||||
if (v2SigningEnabled)
|
||||
{
|
||||
gradle = gradle.Replace("v2SigningEnabled false", "v2SigningEnabled true");
|
||||
System.IO.File.WriteAllText(gradleBuildPath, gradle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//v2 Signing flag missing, add it right after the key store password and set the value based on platform.
|
||||
int keyPassIndex = gradle.IndexOf("keyPassword");
|
||||
if (keyPassIndex != -1)
|
||||
{
|
||||
int v2Index = gradle.IndexOf("\n", keyPassIndex) + 1;
|
||||
if(v2Index != -1)
|
||||
{
|
||||
gradle = gradle.Insert(v2Index, "v2SigningEnabled " + (v2SigningEnabled ? "true" : "false") + "\n");
|
||||
System.IO.File.WriteAllText(gradleBuildPath, gradle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogWarningFormat("Unable to overwrite build.gradle, error {0}", e.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.LogWarning("Unable to locate build.gradle");
|
||||
}
|
||||
|
||||
PatchAndroidManifest(path);
|
||||
}
|
||||
|
||||
public void PatchAndroidManifest(string path)
|
||||
{
|
||||
string manifestFolder = Path.Combine(path, "src/main");
|
||||
string file = manifestFolder + "/AndroidManifest.xml";
|
||||
|
||||
bool patchedSecurityConfig = false;
|
||||
// If Enable NSC Config, copy XML file into gradle project
|
||||
OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig();
|
||||
if (projectConfig != null)
|
||||
{
|
||||
if (projectConfig.enableNSCConfig)
|
||||
{
|
||||
// If no custom xml security path is specified, look for the default location in the integrations package.
|
||||
string securityConfigFile = projectConfig.securityXmlPath;
|
||||
if (string.IsNullOrEmpty(securityConfigFile))
|
||||
{
|
||||
securityConfigFile = GetOculusProjectNetworkSecConfigPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
Uri configUri = new Uri(Path.GetFullPath(securityConfigFile));
|
||||
Uri projectUri = new Uri(Application.dataPath);
|
||||
Uri relativeUri = projectUri.MakeRelativeUri(configUri);
|
||||
securityConfigFile = relativeUri.ToString();
|
||||
}
|
||||
|
||||
string xmlDirectory = Path.Combine(path, "src/main/res/xml");
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(xmlDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(xmlDirectory);
|
||||
}
|
||||
File.Copy(securityConfigFile, Path.Combine(xmlDirectory, "network_sec_config.xml"), true);
|
||||
patchedSecurityConfig = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogError(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OVRManifestPreprocessor.PatchAndroidManifest(file, enableSecurity: patchedSecurityConfig);
|
||||
}
|
||||
|
||||
private static string GetOculusProjectNetworkSecConfigPath()
|
||||
{
|
||||
var so = ScriptableObject.CreateInstance(typeof(OVRPluginUpdaterStub));
|
||||
var script = MonoScript.FromScriptableObject(so);
|
||||
string assetPath = AssetDatabase.GetAssetPath(script);
|
||||
string editorDir = Directory.GetParent(assetPath).FullName;
|
||||
string configAssetPath = Path.GetFullPath(Path.Combine(editorDir, "network_sec_config.xml"));
|
||||
Uri configUri = new Uri(configAssetPath);
|
||||
Uri projectUri = new Uri(Application.dataPath);
|
||||
Uri relativeUri = projectUri.MakeRelativeUri(configUri);
|
||||
|
||||
return relativeUri.ToString();
|
||||
}
|
||||
|
||||
public void OnPostprocessBuild(BuildReport report)
|
||||
{
|
||||
#if UNITY_ANDROID
|
||||
if(autoIncrementVersion)
|
||||
{
|
||||
if((report.summary.options & BuildOptions.Development) == 0)
|
||||
{
|
||||
PlayerSettings.Android.bundleVersionCode++;
|
||||
UnityEngine.Debug.Log("Incrementing version code to " + PlayerSettings.Android.bundleVersionCode);
|
||||
}
|
||||
}
|
||||
|
||||
bool isExporting = true;
|
||||
foreach (var step in report.steps)
|
||||
{
|
||||
if (step.name.Contains("Compile scripts")
|
||||
|| step.name.Contains("Building scenes")
|
||||
|| step.name.Contains("Writing asset files")
|
||||
|| step.name.Contains("Preparing APK resources")
|
||||
|| step.name.Contains("Creating Android manifest")
|
||||
|| step.name.Contains("Processing plugins")
|
||||
|| step.name.Contains("Exporting project")
|
||||
|| step.name.Contains("Building Gradle project"))
|
||||
{
|
||||
OVRPlugin.SendEvent("build_step_" + step.name.ToLower().Replace(' ', '_'),
|
||||
step.duration.TotalSeconds.ToString(), "ovrbuild");
|
||||
#if BUILDSESSION
|
||||
UnityEngine.Debug.LogFormat("build_step_" + step.name.ToLower().Replace(' ', '_') + ": {0}", step.duration.TotalSeconds.ToString());
|
||||
#endif
|
||||
if(step.name.Contains("Building Gradle project"))
|
||||
{
|
||||
isExporting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
OVRPlugin.AddCustomMetadata("build_step_count", report.steps.Length.ToString());
|
||||
if (report.summary.outputPath.Contains("apk")) // Exclude Gradle Project Output
|
||||
{
|
||||
var fileInfo = new System.IO.FileInfo(report.summary.outputPath);
|
||||
OVRPlugin.AddCustomMetadata("build_output_size", fileInfo.Length.ToString());
|
||||
}
|
||||
#endif
|
||||
if (!report.summary.outputPath.Contains("OVRGradleTempExport"))
|
||||
{
|
||||
OVRPlugin.SendEvent("build_complete", (System.DateTime.Now - buildStartTime).TotalSeconds.ToString(), "ovrbuild");
|
||||
#if BUILDSESSION
|
||||
UnityEngine.Debug.LogFormat("build_complete: {0}", (System.DateTime.Now - buildStartTime).TotalSeconds.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_ANDROID
|
||||
if (!isExporting)
|
||||
{
|
||||
// Get the hosts path to Android SDK
|
||||
if (adbTool == null)
|
||||
{
|
||||
adbTool = new OVRADBTool(OVRConfig.Instance.GetAndroidSDKPath(false));
|
||||
}
|
||||
|
||||
if (adbTool.isReady)
|
||||
{
|
||||
// Check to see if there are any ADB devices connected before continuing.
|
||||
List<string> devices = adbTool.GetDevices();
|
||||
if(devices.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear current logs on device
|
||||
Process adbClearProcess;
|
||||
adbClearProcess = adbTool.RunCommandAsync(new string[] { "logcat --clear" }, null);
|
||||
|
||||
// Add a timeout if we cannot get a response from adb logcat --clear in time.
|
||||
Stopwatch timeout = new Stopwatch();
|
||||
timeout.Start();
|
||||
while (!adbClearProcess.WaitForExit(100))
|
||||
{
|
||||
if (timeout.ElapsedMilliseconds > 2000)
|
||||
{
|
||||
adbClearProcess.Kill();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if existing ADB process is still running, kill if needed
|
||||
if (adbProcess != null && !adbProcess.HasExited)
|
||||
{
|
||||
adbProcess.Kill();
|
||||
}
|
||||
|
||||
// Begin thread to time upload and install
|
||||
var thread = new Thread(delegate ()
|
||||
{
|
||||
TimeDeploy();
|
||||
});
|
||||
thread.Start();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_ANDROID
|
||||
public bool WaitForProcess;
|
||||
public bool TransferStarted;
|
||||
public DateTime UploadStart;
|
||||
public DateTime UploadEnd;
|
||||
public DateTime InstallEnd;
|
||||
|
||||
public void TimeDeploy()
|
||||
{
|
||||
if (adbTool != null)
|
||||
{
|
||||
TransferStarted = false;
|
||||
DataReceivedEventHandler outputRecieved = new DataReceivedEventHandler(
|
||||
(s, e) =>
|
||||
{
|
||||
if (e.Data != null && e.Data.Length != 0 && !e.Data.Contains("\u001b"))
|
||||
{
|
||||
if (e.Data.Contains("free_cache"))
|
||||
{
|
||||
// Device recieved install command and is starting upload
|
||||
UploadStart = System.DateTime.Now;
|
||||
TransferStarted = true;
|
||||
}
|
||||
else if (e.Data.Contains("Running dexopt"))
|
||||
{
|
||||
// Upload has finished and Package Manager is starting install
|
||||
UploadEnd = System.DateTime.Now;
|
||||
}
|
||||
else if (e.Data.Contains("dex2oat took"))
|
||||
{
|
||||
// Package Manager finished install
|
||||
InstallEnd = System.DateTime.Now;
|
||||
WaitForProcess = false;
|
||||
}
|
||||
else if (e.Data.Contains("W PackageManager"))
|
||||
{
|
||||
// Warning from Package Manager is a failure in the install process
|
||||
WaitForProcess = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
WaitForProcess = true;
|
||||
adbProcess = adbTool.RunCommandAsync(new string[] { "logcat" }, outputRecieved);
|
||||
|
||||
Stopwatch transferTimeout = new Stopwatch();
|
||||
transferTimeout.Start();
|
||||
while (adbProcess != null && !adbProcess.WaitForExit(100))
|
||||
{
|
||||
if (!WaitForProcess)
|
||||
{
|
||||
adbProcess.Kill();
|
||||
float UploadTime = (float)(UploadEnd - UploadStart).TotalMilliseconds / 1000f;
|
||||
float InstallTime = (float)(InstallEnd - UploadEnd).TotalMilliseconds / 1000f;
|
||||
|
||||
if (UploadTime > 0f)
|
||||
{
|
||||
OVRPlugin.SendEvent("deploy_task", UploadTime.ToString(), "ovrbuild");
|
||||
}
|
||||
if (InstallTime > 0f)
|
||||
{
|
||||
OVRPlugin.SendEvent("install_task", InstallTime.ToString(), "ovrbuild");
|
||||
}
|
||||
}
|
||||
|
||||
if (!TransferStarted && transferTimeout.ElapsedMilliseconds > 5000)
|
||||
{
|
||||
adbProcess.Kill();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
11
Assets/Oculus/VR/Editor/OVRGradleGeneration.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRGradleGeneration.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee7053149e3a159409d4deeb2f2e687f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
32
Assets/Oculus/VR/Editor/OVRLayerAttributeEditor.cs
Normal file
32
Assets/Oculus/VR/Editor/OVRLayerAttributeEditor.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomPropertyDrawer(typeof(OVRLayerAttribute))]
|
||||
class LayerAttributeEditor : PropertyDrawer {
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
// One line of oxygen free code.
|
||||
property.intValue = EditorGUI.LayerField(position, label, property.intValue);
|
||||
}
|
||||
}
|
||||
12
Assets/Oculus/VR/Editor/OVRLayerAttributeEditor.cs.meta
Normal file
12
Assets/Oculus/VR/Editor/OVRLayerAttributeEditor.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c08392d306aac74a88ba571af63c985
|
||||
timeCreated: 1499749379
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
914
Assets/Oculus/VR/Editor/OVRLint.cs
Normal file
914
Assets/Oculus/VR/Editor/OVRLint.cs
Normal file
@@ -0,0 +1,914 @@
|
||||
/************************************************************************************
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus Master SDK License Version 1.0 (the "License"); you may not use
|
||||
the Utilities SDK except in compliance with the License, which is provided at the time of installation
|
||||
or download, or which otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
https://developer.oculus.com/licenses/oculusmastersdk-1.0/
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Utilities SDK distributed
|
||||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
ANY KIND, either express or implied. See the License for the specific language governing
|
||||
permissions and limitations under the License.
|
||||
************************************************************************************/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
#if USING_XR_MANAGEMENT && USING_XR_SDK_OCULUS
|
||||
#define USING_XR_SDK
|
||||
#endif
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
#define REQUIRES_XR_SDK
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using Assets.OVR.Scripts;
|
||||
using Assets.Oculus.VR;
|
||||
using Assets.Oculus.VR.Editor;
|
||||
|
||||
/// <summary>
|
||||
///Scans the project and warns about the following conditions:
|
||||
///Audio sources > 16
|
||||
///Using MSAA levels other than recommended level
|
||||
///Excessive pixel lights (>1 on Mobile; >3 on Rift)
|
||||
///Directional Lightmapping Modes (on Mobile; use Non-Directional)
|
||||
///Preload audio setting on individual audio clips
|
||||
///Decompressing audio clips on load
|
||||
///Disabling occlusion mesh
|
||||
///Android target API level set to 21 or higher
|
||||
///Unity skybox use (on by default, but if you can't see the skybox switching to Color is much faster on Mobile)
|
||||
///Lights marked as "baked" but that were not included in the last bake (and are therefore realtime).
|
||||
///Lack of static batching and dynamic batching settings activated.
|
||||
///Full screen image effects (Mobile)
|
||||
///Warn about large textures that are marked as uncompressed.
|
||||
///32-bit depth buffer (use 16)
|
||||
///Use of projectors (Mobile; can be used carefully but slow enough to warrant a warning)
|
||||
///Maybe in the future once quantified: Graphics jobs and IL2CPP on Mobile.
|
||||
///Real-time global illumination
|
||||
///No texture compression, or non-ASTC texture compression as a global setting (Mobile).
|
||||
///Using deferred rendering
|
||||
///Excessive texture resolution after LOD bias (>2k on Mobile; >4k on Rift)
|
||||
///Not using trilinear or aniso filtering and not generating mipmaps
|
||||
///Excessive render scale (>1.2)
|
||||
///Slow physics settings: Sleep Threshold < 0.005, Default Contact Offset < 0.01, Solver Iteration Count > 6
|
||||
///Shadows on when approaching the geometry or draw call limits
|
||||
///Non-static objects with colliders that are missing rigidbodies on themselves or in the parent chain.
|
||||
///No initialization of GPU/CPU throttling settings, or init to dangerous values (-1 or > 3) (Mobile)
|
||||
///Using inefficient effects: SSAO, motion blur, global fog, parallax mapping, etc.
|
||||
///Too many Overlay layers
|
||||
///Use of Standard shader or Standard Specular shader on Mobile. More generally, excessive use of multipass shaders (legacy specular, etc).
|
||||
///Multiple cameras with clears (on Mobile, potential for excessive fill cost)
|
||||
///Excessive shader passes (>2)
|
||||
///Material pointers that have been instanced in the editor (esp. if we could determine that the instance has no deltas from the original)
|
||||
///Excessive draw calls (>150 on Mobile; >2000 on Rift)
|
||||
///Excessive tris or verts (>100k on Mobile; >1M on Rift)
|
||||
///Large textures, lots of prefabs in startup scene (for bootstrap optimization)
|
||||
///GPU skinning: testing Android-only, as most Rift devs are GPU-bound.
|
||||
/// </summary>
|
||||
[InitializeOnLoadAttribute]
|
||||
public class OVRLint : EditorWindow
|
||||
{
|
||||
//TODO: The following require reflection or static analysis.
|
||||
///Use of ONSP reflections (Mobile)
|
||||
///Use of LoadLevelAsync / LoadLevelAdditiveAsync (on Mobile, this kills frame rate so dramatically it's probably better to just go to black and load synchronously)
|
||||
///Use of Linq in non-editor assemblies (common cause of GCs). Minor: use of foreach.
|
||||
///Use of Unity WWW (exceptionally high overhead for large file downloads, but acceptable for tiny gets).
|
||||
///Declared but empty Awake/Start/Update/OnCollisionEnter/OnCollisionExit/OnCollisionStay. Also OnCollision* star methods that declare the Collision argument but do not reference it (omitting it short-circuits the collision contact calculation).
|
||||
|
||||
private static List<FixRecord> mRecords = new List<FixRecord>();
|
||||
private static List<FixRecord> mRuntimeEditModeRequiredRecords = new List<FixRecord>();
|
||||
private Vector2 mScrollPosition;
|
||||
|
||||
[MenuItem("Oculus/Tools/OVR Performance Lint Tool")]
|
||||
static void Init()
|
||||
{
|
||||
// Get existing open window or if none, make a new one:
|
||||
EditorWindow.GetWindow(typeof(OVRLint));
|
||||
OVRPlugin.SendEvent("perf_lint", "activated");
|
||||
OVRLint.RunCheck();
|
||||
}
|
||||
|
||||
OVRLint()
|
||||
{
|
||||
EditorApplication.playModeStateChanged += HandlePlayModeState;
|
||||
}
|
||||
|
||||
private static void HandlePlayModeState(PlayModeStateChange state)
|
||||
{
|
||||
if (state == PlayModeStateChange.EnteredEditMode)
|
||||
{
|
||||
ApplyEditModeRequiredFix();
|
||||
}
|
||||
}
|
||||
|
||||
private static void ApplyEditModeRequiredFix()
|
||||
{
|
||||
// Apply runtime fixes that require edit mode when applying fix
|
||||
foreach (FixRecord record in mRuntimeEditModeRequiredRecords)
|
||||
{
|
||||
record.fixMethod(null, false, 0);
|
||||
OVRPlugin.SendEvent("perf_lint_apply_fix", record.category);
|
||||
record.complete = true;
|
||||
}
|
||||
mRuntimeEditModeRequiredRecords.Clear();
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
GUILayout.Label("OVR Performance Lint Tool", EditorStyles.boldLabel);
|
||||
if (GUILayout.Button("Refresh", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
RunCheck();
|
||||
}
|
||||
|
||||
string lastCategory = "";
|
||||
|
||||
mScrollPosition = EditorGUILayout.BeginScrollView(mScrollPosition);
|
||||
|
||||
for (int x = 0; x < mRecords.Count; x++)
|
||||
{
|
||||
FixRecord record = mRecords[x];
|
||||
|
||||
if (!record.category.Equals(lastCategory)) // new category
|
||||
{
|
||||
lastCategory = record.category;
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Label(lastCategory, EditorStyles.label, GUILayout.Width(200));
|
||||
bool moreThanOne = (x + 1 < mRecords.Count && mRecords[x + 1].category.Equals(lastCategory));
|
||||
if (record.buttonNames != null && record.buttonNames.Length > 0)
|
||||
{
|
||||
if (moreThanOne)
|
||||
{
|
||||
GUILayout.Label("Apply to all:", EditorStyles.label, GUILayout.Width(75));
|
||||
for (int y = 0; y < record.buttonNames.Length; y++)
|
||||
{
|
||||
if (GUILayout.Button(record.buttonNames[y], EditorStyles.toolbarButton, GUILayout.Width(200)))
|
||||
{
|
||||
List<FixRecord> recordsToProcess = new List<FixRecord>();
|
||||
|
||||
for (int z = x; z < mRecords.Count; z++)
|
||||
{
|
||||
FixRecord thisRecord = mRecords[z];
|
||||
bool isLast = false;
|
||||
if (z + 1 >= mRecords.Count || !mRecords[z + 1].category.Equals(lastCategory))
|
||||
{
|
||||
isLast = true;
|
||||
}
|
||||
|
||||
if (!thisRecord.complete)
|
||||
{
|
||||
recordsToProcess.Add(thisRecord);
|
||||
}
|
||||
|
||||
if (isLast)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UnityEngine.Object[] undoObjects = new UnityEngine.Object[recordsToProcess.Count];
|
||||
for (int z = 0; z < recordsToProcess.Count; z++)
|
||||
{
|
||||
undoObjects[z] = recordsToProcess[z].targetObject;
|
||||
}
|
||||
Undo.RecordObjects(undoObjects, record.category + " (Multiple)");
|
||||
for (int z = 0; z < recordsToProcess.Count; z++)
|
||||
{
|
||||
FixRecord thisRecord = recordsToProcess[z];
|
||||
thisRecord.fixMethod(thisRecord.targetObject, (z + 1 == recordsToProcess.Count), y);
|
||||
OVRPlugin.SendEvent("perf_lint_apply_fix", thisRecord.category);
|
||||
thisRecord.complete = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
if (moreThanOne || record.targetObject)
|
||||
{
|
||||
GUILayout.Label(record.message);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUI.enabled = !record.complete;
|
||||
if (record.targetObject)
|
||||
{
|
||||
EditorGUILayout.ObjectField(record.targetObject, record.targetObject.GetType(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label(record.message);
|
||||
}
|
||||
if (record.buttonNames != null)
|
||||
{
|
||||
for (int y = 0; y < record.buttonNames.Length; y++)
|
||||
{
|
||||
if (GUILayout.Button(record.buttonNames[y], EditorStyles.toolbarButton, GUILayout.Width(200)))
|
||||
{
|
||||
if (record.targetObject != null)
|
||||
{
|
||||
Undo.RecordObject(record.targetObject, record.category);
|
||||
}
|
||||
|
||||
if (record.editModeRequired)
|
||||
{
|
||||
// Add to the fix record list that requires edit mode
|
||||
mRuntimeEditModeRequiredRecords.Add(record);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply the fix directly
|
||||
record.fixMethod(record.targetObject, true, y);
|
||||
OVRPlugin.SendEvent("perf_lint_apply_fix", record.category);
|
||||
record.complete = true;
|
||||
}
|
||||
|
||||
if (mRuntimeEditModeRequiredRecords.Count != 0)
|
||||
{
|
||||
// Stop the scene to apply edit mode required records
|
||||
EditorApplication.ExecuteMenuItem("Edit/Play");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
GUI.enabled = true;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
|
||||
|
||||
public static int RunCheck()
|
||||
{
|
||||
mRecords.Clear();
|
||||
mRuntimeEditModeRequiredRecords.Clear();
|
||||
|
||||
CheckStaticCommonIssues();
|
||||
#if UNITY_ANDROID
|
||||
CheckStaticAndroidIssues();
|
||||
#endif
|
||||
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
CheckRuntimeCommonIssues();
|
||||
#if UNITY_ANDROID
|
||||
CheckRuntimeAndroidIssues();
|
||||
#endif
|
||||
}
|
||||
|
||||
mRecords.Sort(delegate (FixRecord record1, FixRecord record2)
|
||||
{
|
||||
return record1.category.CompareTo(record2.category);
|
||||
});
|
||||
return mRecords.Count;
|
||||
}
|
||||
|
||||
static void AddFix(string category, string message, FixMethodDelegate method, UnityEngine.Object target, bool editModeRequired, params string[] buttons)
|
||||
{
|
||||
OVRPlugin.SendEvent("perf_lint_add_fix", category);
|
||||
mRecords.Add(new FixRecord(category, message, method, target, editModeRequired, buttons));
|
||||
}
|
||||
|
||||
static void CheckStaticCommonIssues()
|
||||
{
|
||||
if (OVRManager.IsUnityAlphaOrBetaVersion())
|
||||
{
|
||||
AddFix("General", OVRManager.UnityAlphaOrBetaVersionWarningMessage, null, null, false);
|
||||
}
|
||||
|
||||
if (QualitySettings.anisotropicFiltering != AnisotropicFiltering.Enable && QualitySettings.anisotropicFiltering != AnisotropicFiltering.ForceEnable)
|
||||
{
|
||||
AddFix("Optimize Aniso", "Anisotropic filtering is recommended for optimal image sharpness and GPU performance.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
// Ideally this would be multi-option: offer Enable or ForceEnable.
|
||||
QualitySettings.anisotropicFiltering = AnisotropicFiltering.Enable;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
#if UNITY_ANDROID
|
||||
int recommendedPixelLightCount = 1;
|
||||
#else
|
||||
int recommendedPixelLightCount = 3;
|
||||
#endif
|
||||
|
||||
if (QualitySettings.pixelLightCount > recommendedPixelLightCount)
|
||||
{
|
||||
AddFix("Optimize Pixel Light Count", "For GPU performance set no more than " + recommendedPixelLightCount + " pixel lights in Quality Settings (currently " + QualitySettings.pixelLightCount + ").", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
QualitySettings.pixelLightCount = recommendedPixelLightCount;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
#if false
|
||||
// Should we recommend this? Seems to be mutually exclusive w/ dynamic batching.
|
||||
if (!PlayerSettings.graphicsJobs)
|
||||
{
|
||||
AddFix ("Optimize Graphics Jobs", "For CPU performance, please use graphics jobs.", delegate(UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
PlayerSettings.graphicsJobs = true;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((!PlayerSettings.MTRendering || !PlayerSettings.GetMobileMTRendering(BuildTargetGroup.Android)))
|
||||
{
|
||||
AddFix("Optimize MT Rendering", "For CPU performance, please enable multithreaded rendering.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
PlayerSettings.SetMobileMTRendering(BuildTargetGroup.Standalone, true);
|
||||
PlayerSettings.SetMobileMTRendering(BuildTargetGroup.Android, true);
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
#if UNITY_ANDROID
|
||||
if (!PlayerSettings.use32BitDisplayBuffer)
|
||||
{
|
||||
AddFix("Optimize Display Buffer Format", "We recommend to enable use32BitDisplayBuffer.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
PlayerSettings.use32BitDisplayBuffer = true;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !UNITY_ANDROID && !USING_XR_SDK && !REQUIRES_XR_SDK
|
||||
if (!PlayerSettings.VROculus.dashSupport)
|
||||
{
|
||||
AddFix("Enable Dash Integration", "We recommend to enable Dash Integration for better user experience.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
PlayerSettings.VROculus.dashSupport = true;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
if (!PlayerSettings.VROculus.sharedDepthBuffer)
|
||||
{
|
||||
AddFix("Enable Depth Buffer Sharing", "We recommend to enable Depth Buffer Sharing for better user experience on Oculus Dash.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
PlayerSettings.VROculus.sharedDepthBuffer = true;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
#endif
|
||||
|
||||
BuildTargetGroup target = EditorUserBuildSettings.selectedBuildTargetGroup;
|
||||
var tier = UnityEngine.Rendering.GraphicsTier.Tier1;
|
||||
var tierSettings = UnityEditor.Rendering.EditorGraphicsSettings.GetTierSettings(target, tier);
|
||||
|
||||
if ((tierSettings.renderingPath == RenderingPath.DeferredShading ||
|
||||
tierSettings.renderingPath == RenderingPath.DeferredLighting))
|
||||
{
|
||||
AddFix("Optimize Rendering Path", "For CPU performance, please do not use deferred shading.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
tierSettings.renderingPath = RenderingPath.Forward;
|
||||
UnityEditor.Rendering.EditorGraphicsSettings.SetTierSettings(target, tier, tierSettings);
|
||||
}, null, false, "Use Forward");
|
||||
}
|
||||
|
||||
if (PlayerSettings.stereoRenderingPath == StereoRenderingPath.MultiPass)
|
||||
{
|
||||
AddFix("Optimize Stereo Rendering", "For CPU performance, please enable single-pass or instanced stereo rendering.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
PlayerSettings.stereoRenderingPath = StereoRenderingPath.Instancing;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
if (LightmapSettings.lightmaps.Length > 0 && LightmapSettings.lightmapsMode != LightmapsMode.NonDirectional)
|
||||
{
|
||||
AddFix("Optimize Lightmap Directionality", "Switching from directional lightmaps to non-directional lightmaps can save a small amount of GPU time.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
LightmapSettings.lightmapsMode = LightmapsMode.NonDirectional;
|
||||
}, null, false, "Switch to non-directional lightmaps");
|
||||
}
|
||||
|
||||
if (Lightmapping.realtimeGI)
|
||||
{
|
||||
AddFix("Disable Realtime GI", "Disabling real-time global illumination can improve GPU performance.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
Lightmapping.realtimeGI = false;
|
||||
}, null, false, "Set Lightmapping.realtimeGI = false.");
|
||||
}
|
||||
|
||||
var lights = GameObject.FindObjectsOfType<Light>();
|
||||
for (int i = 0; i < lights.Length; ++i)
|
||||
{
|
||||
if (lights [i].type != LightType.Directional && !lights [i].bakingOutput.isBaked && IsLightBaked(lights[i]))
|
||||
{
|
||||
AddFix("Unbaked Lights", "The following lights in the scene are marked as Baked, but they don't have up to date lightmap data. Generate the lightmap data, or set it to auto-generate, in Window->Lighting->Settings.", null, lights[i], false, null);
|
||||
}
|
||||
|
||||
if (lights[i].shadows != LightShadows.None && !IsLightBaked(lights[i]))
|
||||
{
|
||||
AddFix("Optimize Shadows", "For CPU performance, consider disabling shadows on realtime lights.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
Light thisLight = (Light)obj;
|
||||
thisLight.shadows = LightShadows.None;
|
||||
}, lights[i], false, "Set \"Shadow Type\" to \"No Shadows\"");
|
||||
}
|
||||
}
|
||||
|
||||
var sources = GameObject.FindObjectsOfType<AudioSource>();
|
||||
if (sources.Length > 16)
|
||||
{
|
||||
List<AudioSource> playingAudioSources = new List<AudioSource>();
|
||||
foreach (var audioSource in sources)
|
||||
{
|
||||
if (audioSource.isPlaying)
|
||||
{
|
||||
playingAudioSources.Add(audioSource);
|
||||
}
|
||||
}
|
||||
|
||||
if (playingAudioSources.Count > 16)
|
||||
{
|
||||
// Sort playing audio sources by priority
|
||||
playingAudioSources.Sort(delegate (AudioSource x, AudioSource y)
|
||||
{
|
||||
return x.priority.CompareTo(y.priority);
|
||||
});
|
||||
for (int i = 16; i < playingAudioSources.Count; ++i)
|
||||
{
|
||||
AddFix("Optimize Audio Source Count", "For CPU performance, please disable all but the top 16 AudioSources.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
AudioSource audioSource = (AudioSource)obj;
|
||||
audioSource.enabled = false;
|
||||
}, playingAudioSources[i], false, "Disable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var clips = GameObject.FindObjectsOfType<AudioClip>();
|
||||
for (int i = 0; i < clips.Length; ++i)
|
||||
{
|
||||
if (clips[i].loadType == AudioClipLoadType.DecompressOnLoad)
|
||||
{
|
||||
AddFix("Audio Loading", "For fast loading, please don't use decompress on load for audio clips", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
AudioClip thisClip = (AudioClip)obj;
|
||||
if (selected == 0)
|
||||
{
|
||||
SetAudioLoadType(thisClip, AudioClipLoadType.CompressedInMemory, last);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetAudioLoadType(thisClip, AudioClipLoadType.Streaming, last);
|
||||
}
|
||||
|
||||
}, clips[i], false, "Change to Compressed in Memory", "Change to Streaming");
|
||||
}
|
||||
|
||||
if (clips[i].preloadAudioData)
|
||||
{
|
||||
AddFix("Audio Preload", "For fast loading, please don't preload data for audio clips.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
SetAudioPreload(clips[i], false, last);
|
||||
}, clips[i], false, "Fix");
|
||||
}
|
||||
}
|
||||
|
||||
if (Physics.defaultContactOffset < 0.01f)
|
||||
{
|
||||
AddFix("Optimize Contact Offset", "For CPU performance, please don't use default contact offset below 0.01.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
Physics.defaultContactOffset = 0.01f;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
if (Physics.sleepThreshold < 0.005f)
|
||||
{
|
||||
AddFix("Optimize Sleep Threshold", "For CPU performance, please don't use sleep threshold below 0.005.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
Physics.sleepThreshold = 0.005f;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
if (Physics.defaultSolverIterations > 8)
|
||||
{
|
||||
AddFix("Optimize Solver Iterations", "For CPU performance, please don't use excessive solver iteration counts.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
Physics.defaultSolverIterations = 8;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
var materials = Resources.FindObjectsOfTypeAll<Material>();
|
||||
for (int i = 0; i < materials.Length; ++i)
|
||||
{
|
||||
if (materials[i].shader.name.Contains("Parallax") || materials[i].IsKeywordEnabled("_PARALLAXMAP"))
|
||||
{
|
||||
AddFix("Optimize Shading", "For GPU performance, please don't use parallax-mapped materials.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
Material thisMaterial = (Material)obj;
|
||||
if (thisMaterial.IsKeywordEnabled("_PARALLAXMAP"))
|
||||
{
|
||||
thisMaterial.DisableKeyword("_PARALLAXMAP");
|
||||
}
|
||||
|
||||
if (thisMaterial.shader.name.Contains("Parallax"))
|
||||
{
|
||||
var newName = thisMaterial.shader.name.Replace("-ParallaxSpec", "-BumpSpec");
|
||||
newName = newName.Replace("-Parallax", "-Bump");
|
||||
var newShader = Shader.Find(newName);
|
||||
if (newShader)
|
||||
{
|
||||
thisMaterial.shader = newShader;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Unable to find a replacement for shader " + materials[i].shader.name);
|
||||
}
|
||||
}
|
||||
}, materials[i], false, "Fix");
|
||||
}
|
||||
}
|
||||
|
||||
var renderers = GameObject.FindObjectsOfType<Renderer>();
|
||||
for (int i = 0; i < renderers.Length; ++i)
|
||||
{
|
||||
if (renderers[i].sharedMaterial == null)
|
||||
{
|
||||
AddFix("Instanced Materials", "Please avoid instanced materials on renderers.", null, renderers[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
var overlays = GameObject.FindObjectsOfType<OVROverlay>();
|
||||
if (overlays.Length > 4)
|
||||
{
|
||||
AddFix("Optimize VR Layer Count", "For GPU performance, please use 4 or fewer VR layers.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
for (int i = 4; i < OVROverlay.instances.Length; ++i)
|
||||
{
|
||||
OVROverlay.instances[i].enabled = false;
|
||||
}
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
var splashScreen = PlayerSettings.virtualRealitySplashScreen;
|
||||
if (splashScreen != null)
|
||||
{
|
||||
if (splashScreen.filterMode != FilterMode.Trilinear)
|
||||
{
|
||||
AddFix("Optimize VR Splash Filtering", "For visual quality, please use trilinear filtering on your VR splash screen.", delegate (UnityEngine.Object obj, bool last, int EditorSelectedRenderState)
|
||||
{
|
||||
var assetPath = AssetDatabase.GetAssetPath(splashScreen);
|
||||
var importer = (TextureImporter)TextureImporter.GetAtPath(assetPath);
|
||||
importer.filterMode = FilterMode.Trilinear;
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
if (splashScreen.mipmapCount <= 1)
|
||||
{
|
||||
AddFix("Generate VR Splash Mipmaps", "For visual quality, please use mipmaps with your VR splash screen.", delegate (UnityEngine.Object obj, bool last, int EditorSelectedRenderState)
|
||||
{
|
||||
var assetPath = AssetDatabase.GetAssetPath(splashScreen);
|
||||
var importer = (TextureImporter)TextureImporter.GetAtPath(assetPath);
|
||||
importer.mipmapEnabled = true;
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CheckRuntimeCommonIssues()
|
||||
{
|
||||
if (!OVRPlugin.occlusionMesh)
|
||||
{
|
||||
AddFix("Occlusion Mesh", "Enabling the occlusion mesh saves substantial GPU resources, generally with no visual impact. Enable unless you have an exceptional use case.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
OVRPlugin.occlusionMesh = true;
|
||||
}, null, false, "Set OVRPlugin.occlusionMesh = true");
|
||||
}
|
||||
|
||||
if (OVRManager.instance != null && !OVRManager.instance.useRecommendedMSAALevel)
|
||||
{
|
||||
AddFix("Optimize MSAA", "OVRManager can select the optimal antialiasing for the installed hardware at runtime. Recommend enabling this.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
var ovrManagers = GameObject.FindObjectsOfType<OVRManager>();
|
||||
foreach (var ovrManager in ovrManagers)
|
||||
{
|
||||
ovrManager.useRecommendedMSAALevel = true;
|
||||
}
|
||||
}, null, true, "Stop Play and Fix");
|
||||
}
|
||||
|
||||
if (UnityEngine.XR.XRSettings.eyeTextureResolutionScale > 1.5)
|
||||
{
|
||||
AddFix("Optimize Render Scale", "Render scale above 1.5 is extremely expensive on the GPU, with little if any positive visual benefit.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
UnityEngine.XR.XRSettings.eyeTextureResolutionScale = 1.5f;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_ANDROID
|
||||
static void CheckStaticAndroidIssues()
|
||||
{
|
||||
if (OVRDeviceSelector.isTargetDeviceQuestFamily && PlayerSettings.Android.targetArchitectures != AndroidArchitecture.ARM64)
|
||||
{
|
||||
// Quest store is only accepting 64-bit apps as of November 25th 2019
|
||||
AddFix("Set Target Architecture to ARM64", "32-bit Quest apps are no longer being accepted on the Oculus Store.",
|
||||
delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARM64;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
// Check that the minSDKVersion meets requirement, 23 for Quest
|
||||
AndroidSdkVersions recommendedAndroidMinSdkVersion = AndroidSdkVersions.AndroidApiLevel23;
|
||||
if ((int)PlayerSettings.Android.minSdkVersion < (int)recommendedAndroidMinSdkVersion)
|
||||
{
|
||||
AddFix("Set Min Android API Level", "Please require at least API level " + (int)recommendedAndroidMinSdkVersion, delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
PlayerSettings.Android.minSdkVersion = recommendedAndroidMinSdkVersion;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
// Check that compileSDKVersion meets minimal version 26 as required for Quest's headtracking feature
|
||||
// Unity Sets compileSDKVersion in Gradle as the value used in targetSdkVersion
|
||||
AndroidSdkVersions requiredAndroidTargetSdkVersion = AndroidSdkVersions.AndroidApiLevel26;
|
||||
if (OVRDeviceSelector.isTargetDeviceQuestFamily &&
|
||||
(int)PlayerSettings.Android.targetSdkVersion < (int)requiredAndroidTargetSdkVersion)
|
||||
{
|
||||
AddFix("Set Android Target SDK Level", "Oculus Quest apps require at least target API level " +
|
||||
(int)requiredAndroidTargetSdkVersion, delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
PlayerSettings.Android.targetSdkVersion = requiredAndroidTargetSdkVersion;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
// Check that Android TV Compatibility is disabled
|
||||
if (PlayerSettings.Android.androidTVCompatibility)
|
||||
{
|
||||
AddFix("Disable Android TV Compatibility", "Apps with Android TV Compatibility enabled are not accepted by the Oculus Store.",
|
||||
delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
PlayerSettings.Android.androidTVCompatibility = false;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
if (!PlayerSettings.gpuSkinning)
|
||||
{
|
||||
AddFix("Optimize GPU Skinning", "If you are CPU-bound, consider using GPU skinning.",
|
||||
delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
PlayerSettings.gpuSkinning = true;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
|
||||
if (RenderSettings.skybox)
|
||||
{
|
||||
AddFix("Optimize Clearing", "For GPU performance, please don't use Unity's built-in Skybox.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
RenderSettings.skybox = null;
|
||||
}, null, false, "Clear Skybox");
|
||||
}
|
||||
|
||||
var materials = Resources.FindObjectsOfTypeAll<Material>();
|
||||
for (int i = 0; i < materials.Length; ++i)
|
||||
{
|
||||
if (materials[i].IsKeywordEnabled("_SPECGLOSSMAP") || materials[i].IsKeywordEnabled("_METALLICGLOSSMAP"))
|
||||
{
|
||||
AddFix("Optimize Specular Material", "For GPU performance, please don't use specular shader on materials.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
Material thisMaterial = (Material)obj;
|
||||
thisMaterial.DisableKeyword("_SPECGLOSSMAP");
|
||||
thisMaterial.DisableKeyword("_METALLICGLOSSMAP");
|
||||
}, materials[i], false, "Fix");
|
||||
}
|
||||
|
||||
if (materials[i].passCount > 2)
|
||||
{
|
||||
AddFix("Material Passes", "Please use 2 or fewer passes in materials.", null, materials[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
ScriptingImplementation backend = PlayerSettings.GetScriptingBackend(UnityEditor.BuildTargetGroup.Android);
|
||||
if (backend != UnityEditor.ScriptingImplementation.IL2CPP)
|
||||
{
|
||||
AddFix("Optimize Scripting Backend", "For CPU performance, please use IL2CPP.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
PlayerSettings.SetScriptingBackend(UnityEditor.BuildTargetGroup.Android, UnityEditor.ScriptingImplementation.IL2CPP);
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
var monoBehaviours = GameObject.FindObjectsOfType<MonoBehaviour>();
|
||||
System.Type effectBaseType = System.Type.GetType("UnityStandardAssets.ImageEffects.PostEffectsBase");
|
||||
if (effectBaseType != null)
|
||||
{
|
||||
for (int i = 0; i < monoBehaviours.Length; ++i)
|
||||
{
|
||||
if (monoBehaviours[i].GetType().IsSubclassOf(effectBaseType))
|
||||
{
|
||||
AddFix("Image Effects", "Please don't use image effects.", null, monoBehaviours[i], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var textures = Resources.FindObjectsOfTypeAll<Texture2D>();
|
||||
|
||||
int maxTextureSize = 1024 * (1 << QualitySettings.masterTextureLimit);
|
||||
maxTextureSize = maxTextureSize * maxTextureSize;
|
||||
|
||||
for (int i = 0; i < textures.Length; ++i)
|
||||
{
|
||||
if (textures[i].filterMode == FilterMode.Trilinear && textures[i].mipmapCount == 1)
|
||||
{
|
||||
AddFix("Optimize Texture Filtering", "For GPU performance, please generate mipmaps or disable trilinear filtering for textures.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
Texture2D thisTexture = (Texture2D)obj;
|
||||
if (selected == 0)
|
||||
{
|
||||
thisTexture.filterMode = FilterMode.Bilinear;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTextureUseMips(thisTexture, true, last);
|
||||
}
|
||||
}, textures[i], false, "Switch to Bilinear", "Generate Mipmaps");
|
||||
}
|
||||
}
|
||||
|
||||
var projectors = GameObject.FindObjectsOfType<Projector>();
|
||||
if (projectors.Length > 0)
|
||||
{
|
||||
AddFix("Optimize Projectors", "For GPU performance, please don't use projectors.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
Projector[] thisProjectors = GameObject.FindObjectsOfType<Projector>();
|
||||
for (int i = 0; i < thisProjectors.Length; ++i)
|
||||
{
|
||||
thisProjectors[i].enabled = false;
|
||||
}
|
||||
}, null, false, "Disable Projectors");
|
||||
}
|
||||
|
||||
if (EditorUserBuildSettings.androidBuildSubtarget != MobileTextureSubtarget.ASTC)
|
||||
{
|
||||
AddFix("Optimize Texture Compression", "For GPU performance, please use ASTC.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
EditorUserBuildSettings.androidBuildSubtarget = MobileTextureSubtarget.ASTC;
|
||||
}, null, false, "Fix");
|
||||
}
|
||||
|
||||
var cameras = GameObject.FindObjectsOfType<Camera>();
|
||||
int clearCount = 0;
|
||||
for (int i = 0; i < cameras.Length; ++i)
|
||||
{
|
||||
if (cameras[i].clearFlags != CameraClearFlags.Nothing && cameras[i].clearFlags != CameraClearFlags.Depth)
|
||||
++clearCount;
|
||||
}
|
||||
|
||||
if (clearCount > 2)
|
||||
{
|
||||
AddFix("Camera Clears", "Please use 2 or fewer clears.", null, null, false);
|
||||
}
|
||||
|
||||
for (int i = 0; i < cameras.Length; ++i)
|
||||
{
|
||||
if (cameras[i].forceIntoRenderTexture)
|
||||
{
|
||||
AddFix("Optimize Mobile Rendering", "For GPU performance, please don't enable forceIntoRenderTexture on your camera, this might be a flag pollution created by post process stack you used before, \nif your post process had already been turned off, we strongly encourage you to disable forceIntoRenderTexture. If you still want to use post process for some reasons, \nyou can leave this one on, but be warned, enabling this flag will introduce huge GPU performance cost. To view your flag status, please turn on you inspector's debug mode",
|
||||
delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
Camera thisCamera = (Camera)obj;
|
||||
thisCamera.forceIntoRenderTexture = false;
|
||||
}, cameras[i], false, "Disable forceIntoRenderTexture");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CheckRuntimeAndroidIssues()
|
||||
{
|
||||
if (UnityStats.usedTextureMemorySize + UnityStats.vboTotalBytes > 1000000)
|
||||
{
|
||||
AddFix("Graphics Memory", "Please use less than 1GB of vertex and texture memory.", null, null, false);
|
||||
}
|
||||
|
||||
if (OVRManager.cpuLevel < 0 || OVRManager.cpuLevel > 3)
|
||||
{
|
||||
AddFix("Optimize CPU level", "For battery life, please use a safe CPU level.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
OVRManager.cpuLevel = 2;
|
||||
}, null, false, "Set to CPU2");
|
||||
}
|
||||
|
||||
if (OVRManager.gpuLevel < 0 || OVRManager.gpuLevel > 3)
|
||||
{
|
||||
AddFix("Optimize GPU level", "For battery life, please use a safe GPU level.", delegate (UnityEngine.Object obj, bool last, int selected)
|
||||
{
|
||||
OVRManager.gpuLevel = 2;
|
||||
}, null, false, "Set to GPU2");
|
||||
}
|
||||
|
||||
if (UnityStats.triangles > 100000 || UnityStats.vertices > 100000)
|
||||
{
|
||||
AddFix("Triangles and Verts", "Please use less than 100000 triangles or vertices.", null, null, false);
|
||||
}
|
||||
|
||||
// Warn for 50 if in non-VR mode?
|
||||
if (UnityStats.drawCalls > 100)
|
||||
{
|
||||
AddFix("Draw Calls", "Please use less than 100 draw calls.", null, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // UNITY_ANDROID
|
||||
|
||||
|
||||
enum LightmapType { Realtime = 4, Baked = 2, Mixed = 1 };
|
||||
|
||||
static bool IsLightBaked(Light light)
|
||||
{
|
||||
return light.lightmapBakeType == LightmapBakeType.Baked;
|
||||
}
|
||||
|
||||
static void SetAudioPreload(AudioClip clip, bool preload, bool refreshImmediately)
|
||||
{
|
||||
if (clip != null)
|
||||
{
|
||||
string assetPath = AssetDatabase.GetAssetPath(clip);
|
||||
AudioImporter importer = AssetImporter.GetAtPath(assetPath) as AudioImporter;
|
||||
if (importer != null)
|
||||
{
|
||||
if (preload != importer.preloadAudioData)
|
||||
{
|
||||
importer.preloadAudioData = preload;
|
||||
|
||||
AssetDatabase.ImportAsset(assetPath);
|
||||
if (refreshImmediately)
|
||||
{
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SetAudioLoadType(AudioClip clip, AudioClipLoadType loadType, bool refreshImmediately)
|
||||
{
|
||||
if (clip != null)
|
||||
{
|
||||
string assetPath = AssetDatabase.GetAssetPath(clip);
|
||||
AudioImporter importer = AssetImporter.GetAtPath(assetPath) as AudioImporter;
|
||||
if (importer != null)
|
||||
{
|
||||
if (loadType != importer.defaultSampleSettings.loadType)
|
||||
{
|
||||
AudioImporterSampleSettings settings = importer.defaultSampleSettings;
|
||||
settings.loadType = loadType;
|
||||
importer.defaultSampleSettings = settings;
|
||||
|
||||
AssetDatabase.ImportAsset(assetPath);
|
||||
if (refreshImmediately)
|
||||
{
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetTextureUseMips(Texture texture, bool useMips, bool refreshImmediately)
|
||||
{
|
||||
if (texture != null)
|
||||
{
|
||||
string assetPath = AssetDatabase.GetAssetPath(texture);
|
||||
TextureImporter tImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;
|
||||
if (tImporter != null && tImporter.mipmapEnabled != useMips)
|
||||
{
|
||||
tImporter.mipmapEnabled = useMips;
|
||||
|
||||
AssetDatabase.ImportAsset(assetPath);
|
||||
if (refreshImmediately)
|
||||
{
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static T FindComponentInParents<T>(GameObject obj) where T : Component
|
||||
{
|
||||
T component = null;
|
||||
if (obj != null)
|
||||
{
|
||||
Transform parent = obj.transform.parent;
|
||||
if (parent != null)
|
||||
{
|
||||
do
|
||||
{
|
||||
component = parent.GetComponent(typeof(T)) as T;
|
||||
parent = parent.parent;
|
||||
} while (parent != null && component == null);
|
||||
}
|
||||
}
|
||||
return component;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
11
Assets/Oculus/VR/Editor/OVRLint.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRLint.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f6763ce4cfe57644a593d773ec6e3cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
313
Assets/Oculus/VR/Editor/OVRManifestPreprocessor.cs
Normal file
313
Assets/Oculus/VR/Editor/OVRManifestPreprocessor.cs
Normal file
@@ -0,0 +1,313 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
|
||||
public class OVRManifestPreprocessor
|
||||
{
|
||||
[MenuItem("Oculus/Tools/Create store-compatible AndroidManifest.xml", false, 100000)]
|
||||
public static void GenerateManifestForSubmission()
|
||||
{
|
||||
var so = ScriptableObject.CreateInstance(typeof(OVRPluginUpdaterStub));
|
||||
var script = MonoScript.FromScriptableObject(so);
|
||||
string assetPath = AssetDatabase.GetAssetPath(script);
|
||||
string editorDir = Directory.GetParent(assetPath).FullName;
|
||||
string srcFile = editorDir + "/AndroidManifest.OVRSubmission.xml";
|
||||
|
||||
if (!File.Exists(srcFile))
|
||||
{
|
||||
Debug.LogError("Cannot find Android manifest template for submission." +
|
||||
" Please delete the OVR folder and reimport the Oculus Utilities.");
|
||||
return;
|
||||
}
|
||||
|
||||
string manifestFolder = Application.dataPath + "/Plugins/Android";
|
||||
|
||||
if (!Directory.Exists(manifestFolder))
|
||||
Directory.CreateDirectory(manifestFolder);
|
||||
|
||||
string dstFile = manifestFolder + "/AndroidManifest.xml";
|
||||
|
||||
if (File.Exists(dstFile))
|
||||
{
|
||||
if (!EditorUtility.DisplayDialog("AndroidManifest.xml Already Exists!", "Would you like to replace the existing manifest with a new one? All modifications will be lost.", "Replace", "Cancel"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PatchAndroidManifest(srcFile, dstFile, false);
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
[MenuItem("Oculus/Tools/Update AndroidManifest.xml")]
|
||||
public static void UpdateAndroidManifest()
|
||||
{
|
||||
string manifestFile = "Assets/Plugins/Android/AndroidManifest.xml";
|
||||
|
||||
if (!File.Exists(manifestFile))
|
||||
{
|
||||
Debug.LogError("Unable to update manifest because it does not exist! Run \"Create store-compatible AndroidManifest.xml\" first");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EditorUtility.DisplayDialog("Update AndroidManifest.xml", "This will overwrite all Oculus specific AndroidManifest Settings. Continue?", "Overwrite", "Cancel"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PatchAndroidManifest(manifestFile, skipExistingAttributes: false);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
[MenuItem("Oculus/Tools/Remove AndroidManifest.xml")]
|
||||
public static void RemoveAndroidManifest()
|
||||
{
|
||||
AssetDatabase.DeleteAsset("Assets/Plugins/Android/AndroidManifest.xml");
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
private static void AddOrRemoveTag(XmlDocument doc, string @namespace, string path, string elementName, string name, bool required, bool modifyIfFound, params string[] attrs) // name, value pairs
|
||||
{
|
||||
var nodes = doc.SelectNodes(path + "/" + elementName);
|
||||
XmlElement element = null;
|
||||
foreach (XmlElement e in nodes)
|
||||
{
|
||||
if (name == null || name == e.GetAttribute("name", @namespace))
|
||||
{
|
||||
element = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (required)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
var parent = doc.SelectSingleNode(path);
|
||||
element = doc.CreateElement(elementName);
|
||||
element.SetAttribute("name", @namespace, name);
|
||||
parent.AppendChild(element);
|
||||
}
|
||||
|
||||
for (int i = 0; i < attrs.Length; i += 2)
|
||||
{
|
||||
if (modifyIfFound || string.IsNullOrEmpty(element.GetAttribute(attrs[i], @namespace)))
|
||||
{
|
||||
if (attrs[i + 1] != null)
|
||||
{
|
||||
element.SetAttribute(attrs[i], @namespace, attrs[i + 1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
element.RemoveAttribute(attrs[i], @namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (element != null && modifyIfFound)
|
||||
{
|
||||
element.ParentNode.RemoveChild(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void PatchAndroidManifest(string sourceFile, string destinationFile = null, bool skipExistingAttributes = true, bool enableSecurity = false)
|
||||
{
|
||||
if (destinationFile == null)
|
||||
{
|
||||
destinationFile = sourceFile;
|
||||
}
|
||||
|
||||
bool modifyIfFound = !skipExistingAttributes;
|
||||
|
||||
try
|
||||
{
|
||||
OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig();
|
||||
|
||||
// Load android manfiest file
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(sourceFile);
|
||||
|
||||
string androidNamepsaceURI;
|
||||
XmlElement element = (XmlElement)doc.SelectSingleNode("/manifest");
|
||||
if (element == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Could not find manifest tag in android manifest.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get android namespace URI from the manifest
|
||||
androidNamepsaceURI = element.GetAttribute("xmlns:android");
|
||||
if (string.IsNullOrEmpty(androidNamepsaceURI))
|
||||
{
|
||||
UnityEngine.Debug.LogError("Could not find Android Namespace in manifest.");
|
||||
return;
|
||||
}
|
||||
|
||||
// remove launcher and leanback launcher
|
||||
AddOrRemoveTag(doc,
|
||||
androidNamepsaceURI,
|
||||
"/manifest/application/activity/intent-filter",
|
||||
"category",
|
||||
"android.intent.category.LAUNCHER",
|
||||
required: false,
|
||||
modifyIfFound: true); // always remove launcher
|
||||
AddOrRemoveTag(doc,
|
||||
androidNamepsaceURI,
|
||||
"/manifest/application/activity/intent-filter",
|
||||
"category",
|
||||
"android.intent.category.LEANBACK_LAUNCHER",
|
||||
required: false,
|
||||
modifyIfFound: true); // always remove leanback launcher
|
||||
// add info category
|
||||
AddOrRemoveTag(doc,
|
||||
androidNamepsaceURI,
|
||||
"/manifest/application/activity/intent-filter",
|
||||
"category",
|
||||
"android.intent.category.INFO",
|
||||
required: true,
|
||||
modifyIfFound: true); // always add info launcher
|
||||
|
||||
// First add or remove headtracking flag if targeting Quest
|
||||
AddOrRemoveTag(doc,
|
||||
androidNamepsaceURI,
|
||||
"/manifest",
|
||||
"uses-feature",
|
||||
"android.hardware.vr.headtracking",
|
||||
OVRDeviceSelector.isTargetDeviceQuestFamily,
|
||||
true,
|
||||
"version", "1",
|
||||
"required", "true");
|
||||
|
||||
// If Quest is the target device, add the handtracking manifest tags if needed
|
||||
// Mapping of project setting to manifest setting:
|
||||
// OVRProjectConfig.HandTrackingSupport.ControllersOnly => manifest entry not present
|
||||
// OVRProjectConfig.HandTrackingSupport.ControllersAndHands => manifest entry present and required=false
|
||||
// OVRProjectConfig.HandTrackingSupport.HandsOnly => manifest entry present and required=true
|
||||
OVRProjectConfig.HandTrackingSupport targetHandTrackingSupport = OVRProjectConfig.GetProjectConfig().handTrackingSupport;
|
||||
bool handTrackingEntryNeeded = OVRDeviceSelector.isTargetDeviceQuestFamily && (targetHandTrackingSupport != OVRProjectConfig.HandTrackingSupport.ControllersOnly);
|
||||
|
||||
AddOrRemoveTag(doc,
|
||||
androidNamepsaceURI,
|
||||
"/manifest",
|
||||
"uses-feature",
|
||||
"oculus.software.handtracking",
|
||||
handTrackingEntryNeeded,
|
||||
modifyIfFound,
|
||||
"required", (targetHandTrackingSupport == OVRProjectConfig.HandTrackingSupport.HandsOnly) ? "true" : "false");
|
||||
AddOrRemoveTag(doc,
|
||||
androidNamepsaceURI,
|
||||
"/manifest",
|
||||
"uses-permission",
|
||||
"com.oculus.permission.HAND_TRACKING",
|
||||
handTrackingEntryNeeded,
|
||||
modifyIfFound);
|
||||
|
||||
// Add focus aware tag if this app is targeting Quest Family
|
||||
AddOrRemoveTag(doc,
|
||||
androidNamepsaceURI,
|
||||
"/manifest/application/activity",
|
||||
"meta-data",
|
||||
"com.oculus.vr.focusaware",
|
||||
OVRDeviceSelector.isTargetDeviceQuestFamily,
|
||||
modifyIfFound,
|
||||
"value", projectConfig.focusAware ? "true" : "false");
|
||||
|
||||
// Add support devices manifest according to the target devices
|
||||
if (OVRDeviceSelector.isTargetDeviceQuestFamily)
|
||||
{
|
||||
string targetDeviceValue = "quest";
|
||||
if (OVRDeviceSelector.isTargetDeviceQuest && OVRDeviceSelector.isTargetDeviceQuest2)
|
||||
{
|
||||
targetDeviceValue = "quest|delmar";
|
||||
}
|
||||
else if (OVRDeviceSelector.isTargetDeviceQuest2)
|
||||
{
|
||||
targetDeviceValue = "delmar";
|
||||
}
|
||||
else if (OVRDeviceSelector.isTargetDeviceQuest)
|
||||
{
|
||||
targetDeviceValue = "quest";
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Unexpected target devices");
|
||||
}
|
||||
AddOrRemoveTag(doc,
|
||||
androidNamepsaceURI,
|
||||
"/manifest/application",
|
||||
"meta-data",
|
||||
"com.oculus.supportedDevices",
|
||||
true,
|
||||
modifyIfFound,
|
||||
"value", targetDeviceValue);
|
||||
}
|
||||
|
||||
// Add system keyboard tag
|
||||
AddOrRemoveTag(doc,
|
||||
androidNamepsaceURI,
|
||||
"/manifest",
|
||||
"uses-feature",
|
||||
"oculus.software.overlay_keyboard",
|
||||
projectConfig.focusAware && projectConfig.requiresSystemKeyboard,
|
||||
modifyIfFound,
|
||||
"required", "false");
|
||||
|
||||
// make sure the VR Mode tag is set in the manifest
|
||||
AddOrRemoveTag(doc,
|
||||
androidNamepsaceURI,
|
||||
"/manifest/application",
|
||||
"meta-data",
|
||||
"com.samsung.android.vr.application.mode",
|
||||
true,
|
||||
modifyIfFound,
|
||||
"value", "vr_only");
|
||||
|
||||
// make sure android label and icon are set in the manifest
|
||||
AddOrRemoveTag(doc,
|
||||
androidNamepsaceURI,
|
||||
"/manifest",
|
||||
"application",
|
||||
null,
|
||||
true,
|
||||
modifyIfFound,
|
||||
"label", "@string/app_name",
|
||||
"icon", "@mipmap/app_icon",
|
||||
// Disable allowBackup in manifest and add Android NSC XML file
|
||||
"allowBackup", projectConfig.disableBackups ? "false" : "true",
|
||||
"networkSecurityConfig", projectConfig.enableNSCConfig && enableSecurity ? "@xml/network_sec_config" : null
|
||||
);
|
||||
|
||||
doc.Save(destinationFile);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Assets/Oculus/VR/Editor/OVRManifestPreprocessor.cs.meta
Normal file
13
Assets/Oculus/VR/Editor/OVRManifestPreprocessor.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb6426f323b7f024ebb25886b5182c4c
|
||||
timeCreated: 1462825988
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- renderFrom: {fileID: 168286, guid: a5014611cefbb6b4398b7e4c82203d08, type: 2}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1217
Assets/Oculus/VR/Editor/OVRPlatformTool.cs
Normal file
1217
Assets/Oculus/VR/Editor/OVRPlatformTool.cs
Normal file
File diff suppressed because it is too large
Load Diff
13
Assets/Oculus/VR/Editor/OVRPlatformTool.cs.meta
Normal file
13
Assets/Oculus/VR/Editor/OVRPlatformTool.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6d58d9d4ff0e8f4ca5f73c5ec106551
|
||||
timeCreated: 1536960564
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
504
Assets/Oculus/VR/Editor/OVRPlatformToolSettings.cs
Normal file
504
Assets/Oculus/VR/Editor/OVRPlatformToolSettings.cs
Normal file
@@ -0,0 +1,504 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Assets.Oculus.VR.Editor
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.InitializeOnLoad]
|
||||
#endif
|
||||
public sealed class OVRPlatformToolSettings : ScriptableObject
|
||||
{
|
||||
private const string DEFAULT_RELEASE_CHANNEL = "Alpha";
|
||||
|
||||
static OVRPlatformToolSettings()
|
||||
{
|
||||
// BuildPipeline.isBuildingPlayer cannot be called in a static constructor
|
||||
// Run Update once to call TryInitialize then remove delegate
|
||||
EditorApplication.update += Update;
|
||||
}
|
||||
|
||||
static void Update()
|
||||
{
|
||||
// Initialize the instance only if a build is not currently running.
|
||||
TryInitialize();
|
||||
// Stop running Update
|
||||
EditorApplication.update -= Update;
|
||||
}
|
||||
|
||||
public static string AppID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None &&
|
||||
EditorPrefs.HasKey("OVRPlatformToolSettings_AppID" + (int)Instance.targetPlatform))
|
||||
{
|
||||
return EditorPrefs.GetString("OVRPlatformToolSettings_AppID" + (int)Instance.targetPlatform);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None)
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_AppID" + (int)Instance.targetPlatform, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReleaseNote
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None &&
|
||||
EditorPrefs.HasKey("OVRPlatformToolSettings_ReleaseNote" + (int)Instance.targetPlatform))
|
||||
{
|
||||
return EditorPrefs.GetString("OVRPlatformToolSettings_ReleaseNote" + (int)Instance.targetPlatform);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None)
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_ReleaseNote" + (int)Instance.targetPlatform, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReleaseChannel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None &&
|
||||
EditorPrefs.HasKey("OVRPlatformToolSettings_ReleaseChannel" + (int)Instance.targetPlatform))
|
||||
{
|
||||
return EditorPrefs.GetString("OVRPlatformToolSettings_ReleaseChannel" + (int)Instance.targetPlatform);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None)
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_ReleaseChannel" + (int)Instance.targetPlatform, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string ApkBuildPath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None &&
|
||||
EditorPrefs.HasKey("OVRPlatformToolSettings_ApkBuildPath" + (int)Instance.targetPlatform))
|
||||
{
|
||||
return EditorPrefs.GetString("OVRPlatformToolSettings_ApkBuildPath" + (int)Instance.targetPlatform);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None)
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_ApkBuildPath" + (int)Instance.targetPlatform, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string ObbFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None &&
|
||||
EditorPrefs.HasKey("OVRPlatformToolSettings_ObbFilePath" + (int)Instance.targetPlatform))
|
||||
{
|
||||
return EditorPrefs.GetString("OVRPlatformToolSettings_ObbFilePath" + (int)Instance.targetPlatform);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None)
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_ObbFilePath" + (int)Instance.targetPlatform, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string AssetsDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None &&
|
||||
EditorPrefs.HasKey("OVRPlatformToolSettings_AssetsDirectory" + (int)Instance.targetPlatform))
|
||||
{
|
||||
return EditorPrefs.GetString("OVRPlatformToolSettings_AssetsDirectory" + (int)Instance.targetPlatform);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None)
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_AssetsDirectory" + (int)Instance.targetPlatform, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string RiftBuildDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorPrefs.HasKey("OVRPlatformToolSettings_RiftBuildDirectory"))
|
||||
{
|
||||
return EditorPrefs.GetString("OVRPlatformToolSettings_RiftBuildDirectory");
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_RiftBuildDirectory", value);
|
||||
}
|
||||
}
|
||||
|
||||
public static string RiftBuildVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorPrefs.HasKey("OVRPlatformToolSettings_RiftBuildVersion"))
|
||||
{
|
||||
return EditorPrefs.GetString("OVRPlatformToolSettings_RiftBuildVersion");
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_RiftBuildVersion", value);
|
||||
}
|
||||
}
|
||||
|
||||
public static string RiftLaunchFile
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorPrefs.HasKey("OVRPlatformToolSettings_RiftLaunchFile"))
|
||||
{
|
||||
return EditorPrefs.GetString("OVRPlatformToolSettings_RiftLaunchFile");
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_RiftLaunchFile", value);
|
||||
}
|
||||
}
|
||||
|
||||
public static string RiftLaunchParams
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorPrefs.HasKey("OVRPlatformToolSettings_RiftLaunchParams"))
|
||||
{
|
||||
return EditorPrefs.GetString("OVRPlatformToolSettings_RiftLaunchParams");
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_RiftLaunchParams", value);
|
||||
}
|
||||
}
|
||||
|
||||
public static string Rift2DLaunchFile
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorPrefs.HasKey("OVRPlatformToolSettings_Rift2DLaunchFile"))
|
||||
{
|
||||
return EditorPrefs.GetString("OVRPlatformToolSettings_Rift2DLaunchFile");
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_Rift2DLaunchFile", value);
|
||||
}
|
||||
}
|
||||
|
||||
public static string Rift2DLaunchParams
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorPrefs.HasKey("OVRPlatformToolSettings_Rift2DLaunchParams"))
|
||||
{
|
||||
return EditorPrefs.GetString("OVRPlatformToolSettings_Rift2DLaunchParams");
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_Rift2DLaunchParams", value);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool RiftFirewallException
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorPrefs.HasKey("OVRPlatformToolSettings_RiftFirewallException"))
|
||||
{
|
||||
return EditorPrefs.GetBool("OVRPlatformToolSettings_RiftFirewallException");
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
EditorPrefs.SetBool("OVRPlatformToolSettings_RiftFirewallException", value);
|
||||
}
|
||||
}
|
||||
|
||||
public static OVRPlatformTool.GamepadType RiftGamepadEmulation
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorPrefs.HasKey("OVRPlatformToolSettings_RiftGamepadEmulation"))
|
||||
{
|
||||
return (OVRPlatformTool.GamepadType)EditorPrefs.GetInt("OVRPlatformToolSettings_RiftGamepadEmulation");
|
||||
}
|
||||
else
|
||||
{
|
||||
return OVRPlatformTool.GamepadType.OFF;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
EditorPrefs.SetInt("OVRPlatformToolSettings_RiftGamepadEmulation", (int)value);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<RedistPackage> RiftRedistPackages
|
||||
{
|
||||
get { return Instance.riftRedistPackages; }
|
||||
set { Instance.riftRedistPackages = value; }
|
||||
}
|
||||
|
||||
public static string LanguagePackDirectory
|
||||
{
|
||||
get { return Instance.languagePackDirectory; }
|
||||
set { Instance.languagePackDirectory = value; }
|
||||
}
|
||||
|
||||
public static List<AssetConfig> AssetConfigs
|
||||
{
|
||||
get
|
||||
{
|
||||
return Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None ? Instance.assetConfigs[(int)Instance.targetPlatform].configList : new List<AssetConfig>();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Instance.targetPlatform < OVRPlatformTool.TargetPlatform.None)
|
||||
{
|
||||
Instance.assetConfigs[(int)Instance.targetPlatform].configList = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static OVRPlatformTool.TargetPlatform TargetPlatform
|
||||
{
|
||||
get { return Instance.targetPlatform; }
|
||||
set { Instance.targetPlatform = value; }
|
||||
}
|
||||
|
||||
public static bool RunOvrLint
|
||||
{
|
||||
get { return Instance.runOvrLint; }
|
||||
set { Instance.runOvrLint = value; }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private List<RedistPackage> riftRedistPackages;
|
||||
|
||||
[SerializeField]
|
||||
private string languagePackDirectory = "";
|
||||
|
||||
[SerializeField]
|
||||
private AssetConfigList[] assetConfigs = new AssetConfigList[(int)OVRPlatformTool.TargetPlatform.None];
|
||||
|
||||
[SerializeField]
|
||||
private OVRPlatformTool.TargetPlatform targetPlatform = OVRPlatformTool.TargetPlatform.None;
|
||||
|
||||
[SerializeField]
|
||||
private bool runOvrLint = true;
|
||||
|
||||
public static bool TryInitialize()
|
||||
{
|
||||
// If not initialized and Build Player is current running, UnityEditor.AssetDatabase.CreateAsset
|
||||
// is unsafe to call and will cause a crash. Only load the resource if it already exists.
|
||||
if (instance == null && BuildPipeline.isBuildingPlayer)
|
||||
{
|
||||
instance = Resources.Load<OVRPlatformToolSettings>("OVRPlatformToolSettings");
|
||||
return instance != null;
|
||||
}
|
||||
// Otherwise create/load the resource instance normally.
|
||||
return Instance != null;
|
||||
}
|
||||
|
||||
private static OVRPlatformToolSettings instance;
|
||||
public static OVRPlatformToolSettings Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = Resources.Load<OVRPlatformToolSettings>("OVRPlatformToolSettings");
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
if (BuildPipeline.isBuildingPlayer)
|
||||
{
|
||||
// UnityEditor.AssetDatabase.CreateAsset is unsafe to call during a build and
|
||||
// may cause a crash.
|
||||
// This should be rare as the asset is created in the static constructor and should
|
||||
// usually exist.
|
||||
throw new UnityEditor.Build.BuildFailedException(
|
||||
"Cannot create OVRPlatformToolSettings asset while building.");
|
||||
}
|
||||
instance = ScriptableObject.CreateInstance<OVRPlatformToolSettings>();
|
||||
|
||||
string properPath = System.IO.Path.Combine(UnityEngine.Application.dataPath, "Resources");
|
||||
if (!System.IO.Directory.Exists(properPath))
|
||||
{
|
||||
UnityEditor.AssetDatabase.CreateFolder("Assets", "Resources");
|
||||
}
|
||||
|
||||
string fullPath = System.IO.Path.Combine(
|
||||
System.IO.Path.Combine("Assets", "Resources"),
|
||||
"OVRPlatformToolSettings.asset"
|
||||
);
|
||||
UnityEditor.AssetDatabase.CreateAsset(instance, fullPath);
|
||||
|
||||
// Initialize cross platform default values for the new instance of OVRPlatformToolSettings here
|
||||
if (instance != null)
|
||||
{
|
||||
for (int i = 0; i < (int)OVRPlatformTool.TargetPlatform.None; i++)
|
||||
{
|
||||
EditorPrefs.SetString("OVRPlatformToolSettings_ReleaseChannel" + i, DEFAULT_RELEASE_CHANNEL);
|
||||
instance.assetConfigs[i] = new AssetConfigList();
|
||||
}
|
||||
|
||||
instance.riftRedistPackages = new List<RedistPackage>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
set
|
||||
{
|
||||
instance = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper for asset config list so that it can be serialized properly
|
||||
[System.Serializable]
|
||||
public class AssetConfigList
|
||||
{
|
||||
public List<AssetConfig> configList;
|
||||
|
||||
public AssetConfigList()
|
||||
{
|
||||
configList = new List<AssetConfig>();
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class AssetConfig
|
||||
{
|
||||
public enum AssetType
|
||||
{
|
||||
DEFAULT,
|
||||
STORE,
|
||||
LANGUAGE_PACK,
|
||||
};
|
||||
|
||||
public string name;
|
||||
public bool required;
|
||||
public AssetType type;
|
||||
public string sku;
|
||||
|
||||
private bool foldout;
|
||||
|
||||
public AssetConfig(string assetName)
|
||||
{
|
||||
name = assetName;
|
||||
}
|
||||
|
||||
public bool GetFoldoutState()
|
||||
{
|
||||
return foldout;
|
||||
}
|
||||
|
||||
public void SetFoldoutState(bool state)
|
||||
{
|
||||
foldout = state;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class RedistPackage
|
||||
{
|
||||
public bool include = false;
|
||||
public string name;
|
||||
public string id;
|
||||
|
||||
public RedistPackage(string pkgName, string pkgId)
|
||||
{
|
||||
name = pkgName;
|
||||
id = pkgId;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Oculus/VR/Editor/OVRPlatformToolSettings.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRPlatformToolSettings.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd7bb81df5b74b34dadbf531f381a26b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
642
Assets/Oculus/VR/Editor/OVRPluginUpdater.cs
Normal file
642
Assets/Oculus/VR/Editor/OVRPluginUpdater.cs
Normal file
@@ -0,0 +1,642 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
[InitializeOnLoad]
|
||||
class OVRPluginUpdater
|
||||
{
|
||||
enum PluginPlatform
|
||||
{
|
||||
Android,
|
||||
AndroidUniversal,
|
||||
OSXUniversal,
|
||||
Win,
|
||||
Win64,
|
||||
}
|
||||
class PluginPackage
|
||||
{
|
||||
public string RootPath;
|
||||
public System.Version Version;
|
||||
public Dictionary<PluginPlatform, string> Plugins = new Dictionary<PluginPlatform, string>();
|
||||
|
||||
public bool IsBundledPluginPackage()
|
||||
{
|
||||
return (RootPath == GetBundledPluginRootPath());
|
||||
}
|
||||
|
||||
public bool IsEnabled()
|
||||
{
|
||||
// TODO: Check each individual platform rather than using the Win64 DLL status for the overall package status.
|
||||
string path = "";
|
||||
if (Plugins.TryGetValue(PluginPlatform.Win64, out path))
|
||||
{
|
||||
return File.Exists(path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsAndroidUniversalEnabled()
|
||||
{
|
||||
string path = "";
|
||||
if (Plugins.TryGetValue(PluginPlatform.AndroidUniversal, out path))
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
string basePath = GetCurrentProjectPath();
|
||||
string relPath = path.Substring(basePath.Length + 1);
|
||||
|
||||
PluginImporter pi = PluginImporter.GetAtPath(relPath) as PluginImporter;
|
||||
if (pi != null)
|
||||
{
|
||||
return pi.GetCompatibleWithPlatform(BuildTarget.Android);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsAndroidUniversalPresent()
|
||||
{
|
||||
string path = "";
|
||||
if (Plugins.TryGetValue(PluginPlatform.AndroidUniversal, out path))
|
||||
{
|
||||
string disabledPath = path + GetDisabledPluginSuffix();
|
||||
|
||||
if (File.Exists(path) || File.Exists(disabledPath))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool restartPending = false;
|
||||
private static bool unityRunningInBatchmode = false;
|
||||
private static bool unityVersionSupportsAndroidUniversal = false;
|
||||
private static bool enableAndroidUniversalSupport = true;
|
||||
|
||||
private static System.Version invalidVersion = new System.Version("0.0.0");
|
||||
|
||||
static OVRPluginUpdater()
|
||||
{
|
||||
EditorApplication.delayCall += OnDelayCall;
|
||||
}
|
||||
|
||||
static void OnDelayCall()
|
||||
{
|
||||
if (System.Environment.CommandLine.Contains("-batchmode"))
|
||||
{
|
||||
unityRunningInBatchmode = true;
|
||||
}
|
||||
|
||||
if (enableAndroidUniversalSupport)
|
||||
{
|
||||
unityVersionSupportsAndroidUniversal = true;
|
||||
}
|
||||
|
||||
if (ShouldAttemptPluginUpdate())
|
||||
{
|
||||
AttemptPluginUpdate(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static PluginPackage GetPluginPackage(string rootPath)
|
||||
{
|
||||
return new PluginPackage()
|
||||
{
|
||||
RootPath = rootPath,
|
||||
Version = GetPluginVersion(rootPath),
|
||||
Plugins = new Dictionary<PluginPlatform, string>()
|
||||
{
|
||||
{ PluginPlatform.Android, rootPath + GetPluginBuildTargetSubPath(PluginPlatform.Android) },
|
||||
{ PluginPlatform.AndroidUniversal, rootPath + GetPluginBuildTargetSubPath(PluginPlatform.AndroidUniversal) },
|
||||
{ PluginPlatform.OSXUniversal, rootPath + GetPluginBuildTargetSubPath(PluginPlatform.OSXUniversal) },
|
||||
{ PluginPlatform.Win, rootPath + GetPluginBuildTargetSubPath(PluginPlatform.Win) },
|
||||
{ PluginPlatform.Win64, rootPath + GetPluginBuildTargetSubPath(PluginPlatform.Win64) },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static PluginPackage GetBundledPluginPackage()
|
||||
{
|
||||
return GetPluginPackage(GetBundledPluginRootPath());
|
||||
}
|
||||
|
||||
private static List<PluginPackage> GetAllUtilitiesPluginPackages()
|
||||
{
|
||||
string pluginRootPath = GetUtilitiesPluginRootPath();
|
||||
List<PluginPackage> packages = new List<PluginPackage>();
|
||||
|
||||
if (Directory.Exists(pluginRootPath))
|
||||
{
|
||||
var dirs = Directory.GetDirectories(pluginRootPath);
|
||||
|
||||
foreach(string dir in dirs)
|
||||
{
|
||||
packages.Add(GetPluginPackage(dir));
|
||||
}
|
||||
}
|
||||
|
||||
return packages;
|
||||
}
|
||||
|
||||
private static string GetCurrentProjectPath()
|
||||
{
|
||||
return Directory.GetParent(Application.dataPath).FullName;
|
||||
}
|
||||
|
||||
private static string GetUtilitiesPluginRootPath()
|
||||
{
|
||||
return GetUtilitiesRootPath() + @"/Plugins";
|
||||
}
|
||||
|
||||
private static string GetUtilitiesRootPath()
|
||||
{
|
||||
var so = ScriptableObject.CreateInstance(typeof(OVRPluginUpdaterStub));
|
||||
var script = MonoScript.FromScriptableObject(so);
|
||||
string assetPath = AssetDatabase.GetAssetPath(script);
|
||||
string editorDir = Directory.GetParent(assetPath).FullName;
|
||||
string ovrDir = Directory.GetParent(editorDir).FullName;
|
||||
|
||||
return ovrDir;
|
||||
}
|
||||
|
||||
private static string GetBundledPluginRootPath()
|
||||
{
|
||||
string basePath = EditorApplication.applicationContentsPath;
|
||||
string pluginPath = @"/UnityExtensions/Unity/VR";
|
||||
|
||||
return basePath + pluginPath;
|
||||
}
|
||||
|
||||
private static string GetPluginBuildTargetSubPath(PluginPlatform target)
|
||||
{
|
||||
string path = string.Empty;
|
||||
|
||||
switch (target)
|
||||
{
|
||||
case PluginPlatform.Android:
|
||||
path = @"/Android/OVRPlugin.aar";
|
||||
break;
|
||||
case PluginPlatform.AndroidUniversal:
|
||||
path = @"/AndroidUniversal/OVRPlugin.aar";
|
||||
break;
|
||||
case PluginPlatform.OSXUniversal:
|
||||
path = @"/OSXUniversal/OVRPlugin.bundle";
|
||||
break;
|
||||
case PluginPlatform.Win:
|
||||
path = @"/Win/OVRPlugin.dll";
|
||||
break;
|
||||
case PluginPlatform.Win64:
|
||||
path = @"/Win64/OVRPlugin.dll";
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Attempted GetPluginBuildTargetSubPath() for unsupported BuildTarget: " + target);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private static string GetDisabledPluginSuffix()
|
||||
{
|
||||
return @".disabled";
|
||||
}
|
||||
|
||||
private static System.Version GetPluginVersion(string path)
|
||||
{
|
||||
System.Version pluginVersion = invalidVersion;
|
||||
|
||||
try
|
||||
{
|
||||
pluginVersion = new System.Version(Path.GetFileName(path));
|
||||
}
|
||||
catch
|
||||
{
|
||||
pluginVersion = invalidVersion;
|
||||
}
|
||||
|
||||
if (pluginVersion == invalidVersion)
|
||||
{
|
||||
//Unable to determine version from path, fallback to Win64 DLL meta data
|
||||
path += GetPluginBuildTargetSubPath(PluginPlatform.Win64);
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
path += GetDisabledPluginSuffix();
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return invalidVersion;
|
||||
}
|
||||
}
|
||||
|
||||
FileVersionInfo pluginVersionInfo = FileVersionInfo.GetVersionInfo(path);
|
||||
if (pluginVersionInfo == null || pluginVersionInfo.ProductVersion == null || pluginVersionInfo.ProductVersion == "")
|
||||
{
|
||||
return invalidVersion;
|
||||
}
|
||||
|
||||
pluginVersion = new System.Version(pluginVersionInfo.ProductVersion);
|
||||
}
|
||||
|
||||
return pluginVersion;
|
||||
}
|
||||
|
||||
public static string GetVersionDescription(System.Version version)
|
||||
{
|
||||
bool isVersionValid = (version != invalidVersion);
|
||||
return isVersionValid ? version.ToString() : "(Unknown)";
|
||||
}
|
||||
|
||||
private static bool ShouldAttemptPluginUpdate()
|
||||
{
|
||||
if (unityRunningInBatchmode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return !UnitySupportsEnabledAndroidPlugin() || (autoUpdateEnabled && !restartPending && !Application.isPlaying);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DisableAllUtilitiesPluginPackages()
|
||||
{
|
||||
List<PluginPackage> allUtilsPluginPkgs = GetAllUtilitiesPluginPackages();
|
||||
|
||||
foreach(PluginPackage pluginPkg in allUtilsPluginPkgs)
|
||||
{
|
||||
foreach(string path in pluginPkg.Plugins.Values)
|
||||
{
|
||||
if ((Directory.Exists(path)) || (File.Exists(path)))
|
||||
{
|
||||
string basePath = GetCurrentProjectPath();
|
||||
string relPath = path.Substring(basePath.Length + 1);
|
||||
string relDisabledPath = relPath + GetDisabledPluginSuffix();
|
||||
|
||||
AssetDatabase.MoveAsset(relPath, relDisabledPath);
|
||||
AssetDatabase.ImportAsset(relDisabledPath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
private static void EnablePluginPackage(PluginPackage pluginPkg)
|
||||
{
|
||||
foreach(var kvp in pluginPkg.Plugins)
|
||||
{
|
||||
PluginPlatform platform = kvp.Key;
|
||||
string path = kvp.Value;
|
||||
|
||||
if ((Directory.Exists(path + GetDisabledPluginSuffix())) || (File.Exists(path + GetDisabledPluginSuffix())))
|
||||
{
|
||||
string basePath = GetCurrentProjectPath();
|
||||
string relPath = path.Substring(basePath.Length + 1);
|
||||
string relDisabledPath = relPath + GetDisabledPluginSuffix();
|
||||
|
||||
AssetDatabase.MoveAsset(relDisabledPath, relPath);
|
||||
AssetDatabase.ImportAsset(relPath, ImportAssetOptions.ForceUpdate);
|
||||
|
||||
PluginImporter pi = PluginImporter.GetAtPath(relPath) as PluginImporter;
|
||||
if (pi == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Disable support for all platforms, then conditionally enable desired support below
|
||||
pi.SetCompatibleWithEditor(false);
|
||||
pi.SetCompatibleWithAnyPlatform(false);
|
||||
pi.SetCompatibleWithPlatform(BuildTarget.Android, false);
|
||||
pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false);
|
||||
pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false);
|
||||
pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, false);
|
||||
|
||||
switch (platform)
|
||||
{
|
||||
case PluginPlatform.Android:
|
||||
pi.SetCompatibleWithPlatform(BuildTarget.Android, !unityVersionSupportsAndroidUniversal);
|
||||
if (!unityVersionSupportsAndroidUniversal)
|
||||
{
|
||||
pi.SetPlatformData(BuildTarget.Android, "CPU", "ARMv7");
|
||||
}
|
||||
break;
|
||||
case PluginPlatform.AndroidUniversal:
|
||||
pi.SetCompatibleWithPlatform(BuildTarget.Android, unityVersionSupportsAndroidUniversal);
|
||||
break;
|
||||
case PluginPlatform.OSXUniversal:
|
||||
pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, true);
|
||||
pi.SetCompatibleWithEditor(true);
|
||||
pi.SetEditorData("CPU", "AnyCPU");
|
||||
pi.SetEditorData("OS", "OSX");
|
||||
pi.SetPlatformData("Editor", "CPU", "AnyCPU");
|
||||
pi.SetPlatformData("Editor", "OS", "OSX");
|
||||
break;
|
||||
case PluginPlatform.Win:
|
||||
pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, true);
|
||||
pi.SetCompatibleWithEditor(true);
|
||||
pi.SetEditorData("CPU", "X86");
|
||||
pi.SetEditorData("OS", "Windows");
|
||||
pi.SetPlatformData("Editor", "CPU", "X86");
|
||||
pi.SetPlatformData("Editor", "OS", "Windows");
|
||||
break;
|
||||
case PluginPlatform.Win64:
|
||||
pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, true);
|
||||
pi.SetCompatibleWithEditor(true);
|
||||
pi.SetEditorData("CPU", "X86_64");
|
||||
pi.SetEditorData("OS", "Windows");
|
||||
pi.SetPlatformData("Editor", "CPU", "X86_64");
|
||||
pi.SetPlatformData("Editor", "OS", "Windows");
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Attempted EnablePluginPackage() for unsupported BuildTarget: " + platform);
|
||||
}
|
||||
|
||||
AssetDatabase.ImportAsset(relPath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
private static readonly string autoUpdateEnabledKey = "Oculus_Utilities_OVRPluginUpdater_AutoUpdate_" + OVRManager.utilitiesVersion;
|
||||
private static bool autoUpdateEnabled
|
||||
{
|
||||
get {
|
||||
return PlayerPrefs.GetInt(autoUpdateEnabledKey, 1) == 1;
|
||||
}
|
||||
|
||||
set {
|
||||
PlayerPrefs.SetInt(autoUpdateEnabledKey, value ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Oculus/Tools/Disable OVR Utilities Plugin")]
|
||||
private static void AttemptPluginDisable()
|
||||
{
|
||||
List<PluginPackage> allUtilsPluginPkgs = GetAllUtilitiesPluginPackages();
|
||||
|
||||
PluginPackage enabledUtilsPluginPkg = null;
|
||||
|
||||
foreach(PluginPackage pluginPkg in allUtilsPluginPkgs)
|
||||
{
|
||||
if (pluginPkg.IsEnabled())
|
||||
{
|
||||
if ((enabledUtilsPluginPkg == null) || (pluginPkg.Version > enabledUtilsPluginPkg.Version))
|
||||
{
|
||||
enabledUtilsPluginPkg = pluginPkg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (enabledUtilsPluginPkg == null)
|
||||
{
|
||||
if (unityRunningInBatchmode
|
||||
|| EditorUtility.DisplayDialog("Disable Oculus Utilities Plugin",
|
||||
"The OVRPlugin included with Oculus Utilities is already disabled."
|
||||
+ " The OVRPlugin installed through the Package Manager will continue to be used.\n",
|
||||
"Ok",
|
||||
""))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (unityRunningInBatchmode
|
||||
|| EditorUtility.DisplayDialog("Disable Oculus Utilities Plugin",
|
||||
"Do you want to disable the OVRPlugin included with Oculus Utilities and revert to the OVRPlugin installed through the Package Manager?\n\n"
|
||||
+ "Current version: " + GetVersionDescription(enabledUtilsPluginPkg.Version),
|
||||
"Yes",
|
||||
"No"))
|
||||
{
|
||||
DisableAllUtilitiesPluginPackages();
|
||||
|
||||
if (unityRunningInBatchmode
|
||||
|| EditorUtility.DisplayDialog("Restart Unity",
|
||||
"Now you will be using the OVRPlugin installed through Package Manager."
|
||||
+ "\n\nPlease restart the Unity Editor to complete the update process.",
|
||||
"Restart",
|
||||
"Not Now"))
|
||||
{
|
||||
RestartUnityEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Oculus/Tools/Update OVR Utilities Plugin")]
|
||||
private static void RunPluginUpdate()
|
||||
{
|
||||
autoUpdateEnabled = true;
|
||||
AttemptPluginUpdate(false);
|
||||
}
|
||||
|
||||
// Separate entry point needed since "-executeMethod" does not support parameters or default parameter values
|
||||
private static void BatchmodePluginUpdate()
|
||||
{
|
||||
OnDelayCall(); // manually invoke when running editor in batchmode
|
||||
AttemptPluginUpdate(false);
|
||||
}
|
||||
|
||||
private static void AttemptPluginUpdate(bool triggeredByAutoUpdate)
|
||||
{
|
||||
OVRPlugin.SendEvent("attempt_plugin_update_auto", triggeredByAutoUpdate.ToString());
|
||||
|
||||
PluginPackage bundledPluginPkg = GetBundledPluginPackage();
|
||||
List<PluginPackage> allUtilsPluginPkgs = GetAllUtilitiesPluginPackages();
|
||||
|
||||
PluginPackage enabledUtilsPluginPkg = null;
|
||||
PluginPackage newestUtilsPluginPkg = null;
|
||||
|
||||
foreach(PluginPackage pluginPkg in allUtilsPluginPkgs)
|
||||
{
|
||||
if ((newestUtilsPluginPkg == null) || (pluginPkg.Version > newestUtilsPluginPkg.Version))
|
||||
{
|
||||
newestUtilsPluginPkg = pluginPkg;
|
||||
}
|
||||
|
||||
if (pluginPkg.IsEnabled())
|
||||
{
|
||||
if ((enabledUtilsPluginPkg == null) || (pluginPkg.Version > enabledUtilsPluginPkg.Version))
|
||||
{
|
||||
enabledUtilsPluginPkg = pluginPkg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool reenableCurrentPluginPkg = false;
|
||||
PluginPackage targetPluginPkg = null;
|
||||
|
||||
if ((newestUtilsPluginPkg != null) && (newestUtilsPluginPkg.Version > bundledPluginPkg.Version))
|
||||
{
|
||||
if ((enabledUtilsPluginPkg == null) || (enabledUtilsPluginPkg.Version != newestUtilsPluginPkg.Version))
|
||||
{
|
||||
targetPluginPkg = newestUtilsPluginPkg;
|
||||
}
|
||||
}
|
||||
else if ((enabledUtilsPluginPkg != null) && (enabledUtilsPluginPkg.Version < bundledPluginPkg.Version))
|
||||
{
|
||||
targetPluginPkg = bundledPluginPkg;
|
||||
}
|
||||
|
||||
PluginPackage currentPluginPkg = (enabledUtilsPluginPkg != null) ? enabledUtilsPluginPkg : bundledPluginPkg;
|
||||
|
||||
if ((targetPluginPkg == null) && !UnitySupportsEnabledAndroidPlugin())
|
||||
{
|
||||
// Force reenabling the current package to configure the correct android plugin for this unity version.
|
||||
reenableCurrentPluginPkg = true;
|
||||
targetPluginPkg = currentPluginPkg;
|
||||
}
|
||||
|
||||
if (targetPluginPkg == null)
|
||||
{
|
||||
if (!triggeredByAutoUpdate && !unityRunningInBatchmode)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Update Oculus Utilities Plugin",
|
||||
"OVRPlugin is already up to date.\n\nCurrent version: "
|
||||
+ GetVersionDescription(currentPluginPkg.Version),
|
||||
"Ok",
|
||||
"");
|
||||
}
|
||||
|
||||
return; // No update necessary.
|
||||
}
|
||||
|
||||
System.Version targetVersion = targetPluginPkg.Version;
|
||||
|
||||
bool userAcceptsUpdate = false;
|
||||
|
||||
if (unityRunningInBatchmode)
|
||||
{
|
||||
userAcceptsUpdate = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
string dialogBody = "Oculus Utilities has detected that a newer OVRPlugin is available."
|
||||
+ " Using the newest version is recommended. Do you want to enable it?\n\n"
|
||||
+ "Current version: "
|
||||
+ GetVersionDescription(currentPluginPkg.Version)
|
||||
+ "\nAvailable version: "
|
||||
+ targetVersion;
|
||||
|
||||
if (reenableCurrentPluginPkg)
|
||||
{
|
||||
dialogBody = "Oculus Utilities has detected a configuration change that requires re-enabling the current OVRPlugin."
|
||||
+ " Do you want to proceed?\n\nCurrent version: "
|
||||
+ GetVersionDescription(currentPluginPkg.Version);
|
||||
}
|
||||
|
||||
int dialogResult = EditorUtility.DisplayDialogComplex("Update Oculus Utilities Plugin", dialogBody, "Yes", "No, Don't Ask Again", "No");
|
||||
|
||||
switch (dialogResult)
|
||||
{
|
||||
case 0: // "Yes"
|
||||
userAcceptsUpdate = true;
|
||||
break;
|
||||
case 1: // "No, Don't Ask Again"
|
||||
autoUpdateEnabled = false;
|
||||
|
||||
EditorUtility.DisplayDialog("Oculus Utilities OVRPlugin",
|
||||
"To manually update in the future, use the following menu option:\n\n"
|
||||
+ "[Oculus -> Tools -> Update OVR Utilities Plugin]",
|
||||
"Ok",
|
||||
"");
|
||||
return;
|
||||
case 2: // "No"
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (userAcceptsUpdate)
|
||||
{
|
||||
DisableAllUtilitiesPluginPackages();
|
||||
|
||||
if (!targetPluginPkg.IsBundledPluginPackage())
|
||||
{
|
||||
EnablePluginPackage(targetPluginPkg);
|
||||
}
|
||||
|
||||
if (unityRunningInBatchmode
|
||||
|| EditorUtility.DisplayDialog("Restart Unity",
|
||||
"OVRPlugin has been updated to "
|
||||
+ GetVersionDescription(targetPluginPkg.Version)
|
||||
+ ".\n\nPlease restart the Unity Editor to complete the update process."
|
||||
,
|
||||
"Restart",
|
||||
"Not Now"))
|
||||
{
|
||||
RestartUnityEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool UnitySupportsEnabledAndroidPlugin()
|
||||
{
|
||||
List<PluginPackage> allUtilsPluginPkgs = GetAllUtilitiesPluginPackages();
|
||||
|
||||
foreach(PluginPackage pluginPkg in allUtilsPluginPkgs)
|
||||
{
|
||||
if (pluginPkg.IsEnabled())
|
||||
{
|
||||
if (pluginPkg.IsAndroidUniversalEnabled() && !unityVersionSupportsAndroidUniversal)
|
||||
{
|
||||
// Android Universal should only be enabled on supported Unity versions since it can prevent app launch.
|
||||
return false;
|
||||
}
|
||||
else if (!pluginPkg.IsAndroidUniversalEnabled() && pluginPkg.IsAndroidUniversalPresent() && unityVersionSupportsAndroidUniversal)
|
||||
{
|
||||
// Android Universal is present and should be enabled on supported Unity versions since ARM64 config will fail otherwise.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void RestartUnityEditor()
|
||||
{
|
||||
if (unityRunningInBatchmode)
|
||||
{
|
||||
EditorApplication.Exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
restartPending = true;
|
||||
EditorApplication.OpenProject(GetCurrentProjectPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Oculus/VR/Editor/OVRPluginUpdater.cs.meta
Normal file
12
Assets/Oculus/VR/Editor/OVRPluginUpdater.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e64a3a065da39f4caa17a7372962df6
|
||||
timeCreated: 1493086775
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
29
Assets/Oculus/VR/Editor/OVRPluginUpdaterStub.cs
Normal file
29
Assets/Oculus/VR/Editor/OVRPluginUpdaterStub.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class OVRPluginUpdaterStub : ScriptableObject
|
||||
{
|
||||
// Stub helper class to locate OVR Utilities Path through Unity Editor API.
|
||||
// Required to be a standalone class in a separate file or else MonoScript.FromScriptableObject() returns an empty string path.
|
||||
}
|
||||
12
Assets/Oculus/VR/Editor/OVRPluginUpdaterStub.cs.meta
Normal file
12
Assets/Oculus/VR/Editor/OVRPluginUpdaterStub.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 791840c2fc67dd3409b79f212fad7dd4
|
||||
timeCreated: 1493148044
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
145
Assets/Oculus/VR/Editor/OVRProjectConfig.cs
Normal file
145
Assets/Oculus/VR/Editor/OVRProjectConfig.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
using System;
|
||||
|
||||
[System.Serializable]
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.InitializeOnLoad]
|
||||
#endif
|
||||
public class OVRProjectConfig : ScriptableObject
|
||||
{
|
||||
public enum DeviceType
|
||||
{
|
||||
//GearVrOrGo = 0, // DEPRECATED
|
||||
Quest = 1,
|
||||
Quest2 = 2
|
||||
}
|
||||
|
||||
public enum HandTrackingSupport
|
||||
{
|
||||
ControllersOnly = 0,
|
||||
ControllersAndHands = 1,
|
||||
HandsOnly = 2
|
||||
}
|
||||
|
||||
public List<DeviceType> targetDeviceTypes;
|
||||
public HandTrackingSupport handTrackingSupport;
|
||||
|
||||
public bool disableBackups;
|
||||
public bool enableNSCConfig;
|
||||
public string securityXmlPath;
|
||||
|
||||
public bool skipUnneededShaders;
|
||||
public bool focusAware;
|
||||
public bool requiresSystemKeyboard;
|
||||
|
||||
//public const string OculusProjectConfigAssetPath = "Assets/Oculus/OculusProjectConfig.asset";
|
||||
|
||||
static OVRProjectConfig()
|
||||
{
|
||||
// BuildPipeline.isBuildingPlayer cannot be called in a static constructor
|
||||
// Run Update once to call GetProjectConfig then remove delegate
|
||||
EditorApplication.update += Update;
|
||||
}
|
||||
|
||||
static void Update()
|
||||
{
|
||||
// Initialize the asset if it doesn't exist
|
||||
GetProjectConfig();
|
||||
// Stop running Update
|
||||
EditorApplication.update -= Update;
|
||||
}
|
||||
|
||||
private static string GetOculusProjectConfigAssetPath()
|
||||
{
|
||||
var so = ScriptableObject.CreateInstance(typeof(OVRPluginUpdaterStub));
|
||||
var script = MonoScript.FromScriptableObject(so);
|
||||
string assetPath = AssetDatabase.GetAssetPath(script);
|
||||
string editorDir = Directory.GetParent(assetPath).FullName;
|
||||
string ovrDir = Directory.GetParent(editorDir).FullName;
|
||||
string oculusDir = Directory.GetParent(ovrDir).FullName;
|
||||
string configAssetPath = Path.GetFullPath(Path.Combine(oculusDir, "OculusProjectConfig.asset"));
|
||||
Uri configUri = new Uri(configAssetPath);
|
||||
Uri projectUri = new Uri(Application.dataPath);
|
||||
Uri relativeUri = projectUri.MakeRelativeUri(configUri);
|
||||
|
||||
return relativeUri.ToString();
|
||||
}
|
||||
|
||||
public static OVRProjectConfig GetProjectConfig()
|
||||
{
|
||||
OVRProjectConfig projectConfig = null;
|
||||
string oculusProjectConfigAssetPath = GetOculusProjectConfigAssetPath();
|
||||
try
|
||||
{
|
||||
projectConfig = AssetDatabase.LoadAssetAtPath(oculusProjectConfigAssetPath, typeof(OVRProjectConfig)) as OVRProjectConfig;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogWarningFormat("Unable to load ProjectConfig from {0}, error {1}", oculusProjectConfigAssetPath, e.Message);
|
||||
}
|
||||
// Initialize the asset only if a build is not currently running.
|
||||
if (projectConfig == null && !BuildPipeline.isBuildingPlayer)
|
||||
{
|
||||
projectConfig = ScriptableObject.CreateInstance<OVRProjectConfig>();
|
||||
projectConfig.targetDeviceTypes = new List<DeviceType>();
|
||||
projectConfig.targetDeviceTypes.Add(DeviceType.Quest);
|
||||
projectConfig.targetDeviceTypes.Add(DeviceType.Quest2);
|
||||
projectConfig.handTrackingSupport = HandTrackingSupport.ControllersOnly;
|
||||
projectConfig.disableBackups = true;
|
||||
projectConfig.enableNSCConfig = true;
|
||||
projectConfig.skipUnneededShaders = false;
|
||||
projectConfig.focusAware = true;
|
||||
projectConfig.requiresSystemKeyboard = false;
|
||||
AssetDatabase.CreateAsset(projectConfig, oculusProjectConfigAssetPath);
|
||||
}
|
||||
// Force migration to Quest device if still on legacy GearVR/Go device type
|
||||
if (projectConfig.targetDeviceTypes.Contains((DeviceType)0)) // deprecated GearVR/Go device
|
||||
{
|
||||
projectConfig.targetDeviceTypes.Remove((DeviceType)0); // deprecated GearVR/Go device
|
||||
if (!projectConfig.targetDeviceTypes.Contains(DeviceType.Quest))
|
||||
{
|
||||
projectConfig.targetDeviceTypes.Add(DeviceType.Quest);
|
||||
}
|
||||
if (!projectConfig.targetDeviceTypes.Contains(DeviceType.Quest2))
|
||||
{
|
||||
projectConfig.targetDeviceTypes.Add(DeviceType.Quest2);
|
||||
}
|
||||
}
|
||||
return projectConfig;
|
||||
}
|
||||
|
||||
public static void CommitProjectConfig(OVRProjectConfig projectConfig)
|
||||
{
|
||||
string oculusProjectConfigAssetPath = GetOculusProjectConfigAssetPath();
|
||||
if (AssetDatabase.GetAssetPath(projectConfig) != oculusProjectConfigAssetPath)
|
||||
{
|
||||
Debug.LogWarningFormat("The asset path of ProjectConfig is wrong. Expect {0}, get {1}", oculusProjectConfigAssetPath, AssetDatabase.GetAssetPath(projectConfig));
|
||||
}
|
||||
EditorUtility.SetDirty(projectConfig);
|
||||
}
|
||||
}
|
||||
11
Assets/Oculus/VR/Editor/OVRProjectConfig.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRProjectConfig.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05d394ae2a81edd4cbc3c51917e766e3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
216
Assets/Oculus/VR/Editor/OVRScreenshotWizard.cs
Normal file
216
Assets/Oculus/VR/Editor/OVRScreenshotWizard.cs
Normal file
@@ -0,0 +1,216 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// From the selected transform, takes a cubemap screenshot that can be submitted with the application
|
||||
/// as a screenshot (or additionally used for reflection shaders).
|
||||
/// </summary>
|
||||
class OVRScreenshotWizard : ScriptableWizard
|
||||
{
|
||||
public enum TexFormat
|
||||
{
|
||||
JPEG, // 512kb at 1k x 1k resolution vs
|
||||
PNG, // 5.3mb
|
||||
}
|
||||
|
||||
public enum SaveMode {
|
||||
SaveCubemapScreenshot,
|
||||
SaveUnityCubemap,
|
||||
SaveBoth,
|
||||
}
|
||||
|
||||
public GameObject renderFrom = null;
|
||||
public int size = 2048;
|
||||
public SaveMode saveMode = SaveMode.SaveUnityCubemap;
|
||||
public string cubeMapFolder = "Assets/Textures/Cubemaps";
|
||||
public TexFormat textureFormat = TexFormat.PNG;
|
||||
|
||||
/// <summary>
|
||||
/// Validates the user's input
|
||||
/// </summary>
|
||||
void OnWizardUpdate()
|
||||
{
|
||||
helpString = "Select a game object positioned in the place where\nyou want to render the cubemap screenshot from: ";
|
||||
isValid = (renderFrom != null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the asset path if it is not available.
|
||||
/// Assuming the newFolderPath is stated with "Assets", which is a requirement.
|
||||
/// </summary>
|
||||
static bool CreateAssetPath( string newFolderPath )
|
||||
{
|
||||
const int maxFoldersCount = 32;
|
||||
string currentPath;
|
||||
string[] pathFolders;
|
||||
|
||||
pathFolders = newFolderPath.Split (new char[]{ '/' }, maxFoldersCount);
|
||||
|
||||
if (!string.Equals ("Assets", pathFolders [0], System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Debug.LogError( "Folder path has to be started with \" Assets \" " );
|
||||
return false;
|
||||
}
|
||||
|
||||
currentPath = "Assets";
|
||||
for (int i = 1; i < pathFolders.Length; i++)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(pathFolders[i]))
|
||||
{
|
||||
string newPath = currentPath + "/" + pathFolders[i];
|
||||
if (!AssetDatabase.IsValidFolder(newPath))
|
||||
AssetDatabase.CreateFolder(currentPath, pathFolders[i]);
|
||||
currentPath = newPath;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log( "Created path: " + currentPath );
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the cubemap
|
||||
/// </summary>
|
||||
void OnWizardCreate()
|
||||
{
|
||||
if ( !AssetDatabase.IsValidFolder( cubeMapFolder ) )
|
||||
{
|
||||
if (!CreateAssetPath(cubeMapFolder))
|
||||
{
|
||||
Debug.LogError( "Created path failed: " + cubeMapFolder );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool existingCamera = true;
|
||||
bool existingCameraStateSave = true;
|
||||
Camera camera = renderFrom.GetComponent<Camera>();
|
||||
if (camera == null)
|
||||
{
|
||||
camera = renderFrom.AddComponent<Camera>();
|
||||
camera.farClipPlane = 10000f;
|
||||
existingCamera = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
existingCameraStateSave = camera.enabled;
|
||||
camera.enabled = true;
|
||||
}
|
||||
// find the last screenshot saved
|
||||
if (cubeMapFolder[cubeMapFolder.Length-1] != '/')
|
||||
{
|
||||
cubeMapFolder += "/";
|
||||
}
|
||||
int idx = 0;
|
||||
string[] fileNames = Directory.GetFiles(cubeMapFolder);
|
||||
foreach(string fileName in fileNames)
|
||||
{
|
||||
if (!fileName.ToLower().EndsWith(".cubemap"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string temp = fileName.Replace(cubeMapFolder + "vr_screenshot_", string.Empty);
|
||||
temp = temp.Replace(".cubemap", string.Empty);
|
||||
int tempIdx = 0;
|
||||
if (int.TryParse( temp, out tempIdx ))
|
||||
{
|
||||
if (tempIdx > idx)
|
||||
{
|
||||
idx = tempIdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
string pathName = string.Format("{0}vr_screenshot_{1}.cubemap", cubeMapFolder, (++idx).ToString("d2"));
|
||||
Cubemap cubemap = new Cubemap(size, TextureFormat.RGB24, false);
|
||||
|
||||
// render into cubemap
|
||||
if ((camera != null) && (cubemap != null))
|
||||
{
|
||||
// set up cubemap defaults
|
||||
OVRCubemapCapture.RenderIntoCubemap(camera, cubemap);
|
||||
if (existingCamera)
|
||||
{
|
||||
camera.enabled = existingCameraStateSave;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyImmediate(camera);
|
||||
}
|
||||
// generate a regular texture as well?
|
||||
if ( ( saveMode == SaveMode.SaveCubemapScreenshot ) || ( saveMode == SaveMode.SaveBoth ) )
|
||||
{
|
||||
GenerateTexture(cubemap, pathName);
|
||||
}
|
||||
|
||||
if ( ( saveMode == SaveMode.SaveUnityCubemap ) || ( saveMode == SaveMode.SaveBoth ) )
|
||||
{
|
||||
Debug.Log( "Saving: " + pathName );
|
||||
// by default the unity cubemap isn't saved
|
||||
AssetDatabase.CreateAsset( cubemap, pathName );
|
||||
// reimport as necessary
|
||||
AssetDatabase.SaveAssets();
|
||||
// select it in the project tree so developers can find it
|
||||
EditorGUIUtility.PingObject( cubemap );
|
||||
Selection.activeObject = cubemap;
|
||||
}
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a NPOT 6x1 cubemap in the following format PX NX PY NY PZ NZ
|
||||
/// </summary>
|
||||
void GenerateTexture(Cubemap cubemap, string pathName)
|
||||
{
|
||||
// Encode the texture and save it to disk
|
||||
pathName = pathName.Replace(".cubemap", (textureFormat == TexFormat.PNG) ? ".png" : ".jpg" ).ToLower();
|
||||
pathName = pathName.Replace( cubeMapFolder.ToLower(), "" );
|
||||
string format = textureFormat.ToString();
|
||||
string fullPath = EditorUtility.SaveFilePanel( string.Format( "Save Cubemap Screenshot as {0}", format ), "", pathName, format.ToLower() );
|
||||
if ( !string.IsNullOrEmpty( fullPath ) )
|
||||
{
|
||||
Debug.Log( "Saving: " + fullPath );
|
||||
OVRCubemapCapture.SaveCubemapCapture(cubemap, fullPath);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unity Editor menu option to take a screenshot
|
||||
/// </summary>
|
||||
[MenuItem("Oculus/Tools/OVR Screenshot Wizard", false, 100000)]
|
||||
static void TakeOVRScreenshot()
|
||||
{
|
||||
OVRScreenshotWizard wizard = ScriptableWizard.DisplayWizard<OVRScreenshotWizard>("OVR Screenshot Wizard", "Render Cubemap");
|
||||
if (wizard != null)
|
||||
{
|
||||
if (Selection.activeGameObject != null)
|
||||
wizard.renderFrom = Selection.activeGameObject;
|
||||
else
|
||||
wizard.renderFrom = Camera.main.gameObject;
|
||||
|
||||
wizard.isValid = (wizard.renderFrom != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Assets/Oculus/VR/Editor/OVRScreenshotWizard.cs.meta
Normal file
13
Assets/Oculus/VR/Editor/OVRScreenshotWizard.cs.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8b9ee1d7b188284f90d944cd54eb026
|
||||
timeCreated: 1462825988
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- renderFrom: {fileID: 168286, guid: a5014611cefbb6b4398b7e4c82203d08, type: 2}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
54
Assets/Oculus/VR/Editor/OVRShaderBuildProcessor.cs
Normal file
54
Assets/Oculus/VR/Editor/OVRShaderBuildProcessor.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Rendering;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
public class OVRShaderBuildProcessor : IPreprocessShaders
|
||||
{
|
||||
public int callbackOrder { get { return 0; } }
|
||||
|
||||
public void OnProcessShader(
|
||||
Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> shaderCompilerData)
|
||||
{
|
||||
var projectConfig = OVRProjectConfig.GetProjectConfig();
|
||||
if (projectConfig == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!projectConfig.skipUnneededShaders)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (EditorUserBuildSettings.activeBuildTarget != BuildTarget.Android)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var strippedGraphicsTiers = new HashSet<GraphicsTier>();
|
||||
|
||||
// Unity only uses shader Tier2 on Quest and Go (regardless of graphics API)
|
||||
if (projectConfig.targetDeviceTypes.Contains(OVRProjectConfig.DeviceType.Quest) ||
|
||||
projectConfig.targetDeviceTypes.Contains(OVRProjectConfig.DeviceType.Quest2))
|
||||
{
|
||||
strippedGraphicsTiers.Add(GraphicsTier.Tier1);
|
||||
strippedGraphicsTiers.Add(GraphicsTier.Tier3);
|
||||
}
|
||||
|
||||
if (strippedGraphicsTiers.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = shaderCompilerData.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (strippedGraphicsTiers.Contains(shaderCompilerData[i].graphicsTier))
|
||||
{
|
||||
shaderCompilerData.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Oculus/VR/Editor/OVRShaderBuildProcessor.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRShaderBuildProcessor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb08fbbe69f983b4dbac5e1b413fea34
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
685
Assets/Oculus/VR/Editor/OVRSystemProfilerPanel.cs
Normal file
685
Assets/Oculus/VR/Editor/OVRSystemProfilerPanel.cs
Normal file
@@ -0,0 +1,685 @@
|
||||
/************************************************************************************
|
||||
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Oculus SDK License Version 3.4.1 (the "License");
|
||||
you may not use the Oculus SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://developer.oculus.com/licenses/sdk-3.4.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Text;
|
||||
|
||||
public class OVRSystemProfilerPanel : EditorWindow {
|
||||
[MenuItem("Oculus/Tools/Oculus Profiler Panel")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
EditorWindow.GetWindow(typeof(OVRSystemProfilerPanel), false, "Oculus Profiler");
|
||||
OVRPlugin.SendEvent("oculus_profiler_panel", "show_window");
|
||||
}
|
||||
|
||||
bool showAndroidOptions = false;
|
||||
OVRNetwork.OVRNetworkTcpClient tcpClient = new OVRNetwork.OVRNetworkTcpClient();
|
||||
int remoteListeningPort = OVRSystemPerfMetrics.TcpListeningPort;
|
||||
|
||||
//OVRSystemPerfMetrics.PerfMetrics lastReceivedMetrics;
|
||||
|
||||
const int maxMetricsFrames = 120;
|
||||
const float metricsHistoryDuration = 1.0f;
|
||||
|
||||
List<OVRSystemPerfMetrics.PerfMetrics> receivedMetricsList = new List<OVRSystemPerfMetrics.PerfMetrics>();
|
||||
bool pauseReceiveMetrics = false;
|
||||
bool repaintRequested = false;
|
||||
|
||||
const float labelWidth = 140.0f;
|
||||
const float panelInnerRightPad = 6.0f;
|
||||
const float progressBarPad = 5.0f;
|
||||
const float progressBarHeight = 18.0f;
|
||||
|
||||
string androidSdkRootPath;
|
||||
OVRADBTool adbTool;
|
||||
|
||||
// The actual window code goes here
|
||||
void OnGUI()
|
||||
{
|
||||
showAndroidOptions = EditorGUILayout.Foldout(showAndroidOptions, "Android Tools");
|
||||
|
||||
if (showAndroidOptions)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Android SDK root path: ", androidSdkRootPath);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Start Server"))
|
||||
{
|
||||
if (adbTool == null)
|
||||
{
|
||||
adbTool = new OVRADBTool(androidSdkRootPath);
|
||||
}
|
||||
if (adbTool.isReady)
|
||||
{
|
||||
int exitCode = adbTool.StartServer(null);
|
||||
EditorUtility.DisplayDialog("ADB StartServer", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok");
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok");
|
||||
}
|
||||
}
|
||||
if (GUILayout.Button("Kill Server"))
|
||||
{
|
||||
if (adbTool == null)
|
||||
{
|
||||
adbTool = new OVRADBTool(androidSdkRootPath);
|
||||
}
|
||||
if (adbTool.isReady)
|
||||
{
|
||||
int exitCode = adbTool.KillServer(null);
|
||||
EditorUtility.DisplayDialog("ADB KillServer", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok");
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok");
|
||||
}
|
||||
}
|
||||
if (GUILayout.Button("Forward Port"))
|
||||
{
|
||||
if (adbTool == null)
|
||||
{
|
||||
adbTool = new OVRADBTool(androidSdkRootPath);
|
||||
}
|
||||
if (adbTool.isReady)
|
||||
{
|
||||
int exitCode = adbTool.ForwardPort(remoteListeningPort, null);
|
||||
EditorUtility.DisplayDialog("ADB ForwardPort", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok");
|
||||
OVRPlugin.SendEvent("device_metrics_profiler", (exitCode == 0 ? "adb_forward_success" : "adb_forward_failure"));
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok");
|
||||
}
|
||||
}
|
||||
if (GUILayout.Button("Release Port"))
|
||||
{
|
||||
if (adbTool == null)
|
||||
{
|
||||
adbTool = new OVRADBTool(androidSdkRootPath);
|
||||
}
|
||||
if (adbTool.isReady)
|
||||
{
|
||||
int exitCode = adbTool.ReleasePort(remoteListeningPort, null);
|
||||
EditorUtility.DisplayDialog("ADB ReleasePort", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok");
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok");
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
remoteListeningPort = EditorGUILayout.DelayedIntField("Remote Port", remoteListeningPort);
|
||||
|
||||
if (tcpClient.connectionState == OVRNetwork.OVRNetworkTcpClient.ConnectionState.Disconnected)
|
||||
{
|
||||
if (GUILayout.Button("Connect"))
|
||||
{
|
||||
ConnectPerfMetricsTcpServer();
|
||||
pauseReceiveMetrics = false;
|
||||
OVRPlugin.SendEvent("device_metrics_profiler", "connect");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tcpClient.connectionState == OVRNetwork.OVRNetworkTcpClient.ConnectionState.Connecting)
|
||||
{
|
||||
if (GUILayout.Button("Connecting ... Click again to Cancel"))
|
||||
{
|
||||
DisconnectPerfMetricsTcpServer();
|
||||
OVRPlugin.SendEvent("device_metrics_profiler", "cancel");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUILayout.Button("Disconnect"))
|
||||
{
|
||||
DisconnectPerfMetricsTcpServer();
|
||||
OVRPlugin.SendEvent("device_metrics_profiler", "disconnect");
|
||||
}
|
||||
|
||||
if (GUILayout.Button(pauseReceiveMetrics ? "Continue" : "Pause"))
|
||||
{
|
||||
pauseReceiveMetrics = !pauseReceiveMetrics;
|
||||
}
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
|
||||
|
||||
lock (receivedMetricsList)
|
||||
{
|
||||
PresentIntProperty("Frame Count", "frameCount");
|
||||
PresentIntProperty("Dropped Frame Count", "compositorDroppedFrameCount");
|
||||
|
||||
float? avgFrameTime = GetAveragePerfValueFloat("deltaFrameTime");
|
||||
if (avgFrameTime.HasValue)
|
||||
{
|
||||
float fps = 1.0f / avgFrameTime.Value;
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("FPS", GUILayout.Width(labelWidth));
|
||||
EditorGUILayout.LabelField(string.Format("{0:F1}", fps));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
int? deviceCpuClockLevel = GetLatestPerfValueInt("deviceCpuClockLevel");
|
||||
int? deviceGpuClockLevel = GetLatestPerfValueInt("deviceGpuClockLevel");
|
||||
float? deviceCpuClockFrequencyInMHz = GetLatestPerfValueFloat("deviceCpuClockFrequencyInMHz");
|
||||
float? deviceGpuClockFrequencyInMHz = GetLatestPerfValueFloat("deviceGpuClockFrequencyInMHz");
|
||||
|
||||
if (deviceCpuClockLevel.HasValue || deviceCpuClockFrequencyInMHz.HasValue)
|
||||
{
|
||||
string cpuLabel;
|
||||
string cpuText;
|
||||
if (deviceCpuClockLevel.HasValue && deviceCpuClockFrequencyInMHz.HasValue)
|
||||
{
|
||||
cpuLabel = "CPU Level (Freq)";
|
||||
cpuText = string.Format("{0} ({1:F0} MHz)", deviceCpuClockLevel, deviceCpuClockFrequencyInMHz);
|
||||
}
|
||||
else if (deviceCpuClockLevel.HasValue)
|
||||
{
|
||||
cpuLabel = "CPU Level";
|
||||
cpuText = string.Format("{0}", deviceCpuClockLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuLabel = "CPU Frequency";
|
||||
cpuText = string.Format("{0:F0} MHz", deviceCpuClockFrequencyInMHz);
|
||||
}
|
||||
PresentText(cpuLabel, cpuText);
|
||||
}
|
||||
|
||||
if (deviceGpuClockLevel.HasValue || deviceGpuClockFrequencyInMHz.HasValue)
|
||||
{
|
||||
string cpuLabel;
|
||||
string cpuText;
|
||||
if (deviceGpuClockLevel.HasValue && deviceGpuClockFrequencyInMHz.HasValue)
|
||||
{
|
||||
cpuLabel = "GPU Level (Freq)";
|
||||
cpuText = string.Format("{0} ({1:F0} MHz)", deviceGpuClockLevel, deviceGpuClockFrequencyInMHz);
|
||||
}
|
||||
else if (deviceGpuClockLevel.HasValue)
|
||||
{
|
||||
cpuLabel = "GPU Level";
|
||||
cpuText = string.Format("{0}", deviceGpuClockLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuLabel = "GPU Frequency";
|
||||
cpuText = string.Format("{0:F0} MHz", deviceGpuClockFrequencyInMHz);
|
||||
}
|
||||
PresentText(cpuLabel, cpuText);
|
||||
}
|
||||
|
||||
PresentColumnTitles("Current", "Average", "Peak");
|
||||
|
||||
PresentFloatTimeInMs("Frame Time", "deltaFrameTime", 0.020f, true, true);
|
||||
PresentFloatTimeInMs("App CPU Time", "appCpuTime", 0.020f, true, true);
|
||||
PresentFloatTimeInMs("App GPU Time", "appGpuTime", 0.020f, true, true);
|
||||
PresentFloatTimeInMs("Compositor CPU Time", "compositorCpuTime", 0.020f, true, true);
|
||||
PresentFloatTimeInMs("Compositor GPU Time", "compositorGpuTime", 0.020f, true, true);
|
||||
PresentFloatPercentage("CPU Util (Average)", "systemCpuUtilAveragePercentage", false, false);
|
||||
PresentFloatPercentage("CPU Util (Worst Core)", "systemCpuUtilWorstPercentage", false, false);
|
||||
PresentFloatPercentage("GPU Util", "systemGpuUtilPercentage", false, false);
|
||||
}
|
||||
}
|
||||
|
||||
void GetMetricsField(string propertyName, out FieldInfo baseFieldInfo, out FieldInfo validalityFieldInfo)
|
||||
{
|
||||
baseFieldInfo = typeof(OVRSystemPerfMetrics.PerfMetrics).GetField(propertyName);
|
||||
validalityFieldInfo = typeof(OVRSystemPerfMetrics.PerfMetrics).GetField(propertyName + "_IsValid");
|
||||
}
|
||||
|
||||
bool HasValidPerfMetrics(string propertyName)
|
||||
{
|
||||
FieldInfo baseFieldInfo, validalityFieldInfo;
|
||||
GetMetricsField(propertyName, out baseFieldInfo, out validalityFieldInfo);
|
||||
|
||||
if (baseFieldInfo == null || (validalityFieldInfo != null && validalityFieldInfo.FieldType != typeof(bool)))
|
||||
{
|
||||
Debug.LogWarning("[OVRSystemProfilerPanel] Unable to find property " + propertyName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (validalityFieldInfo == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = receivedMetricsList.Count - 1; i >= 0; --i)
|
||||
{
|
||||
var metrics = receivedMetricsList[i];
|
||||
if (validalityFieldInfo != null && (bool)validalityFieldInfo.GetValue(metrics))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int? GetLatestPerfValueInt(string propertyName)
|
||||
{
|
||||
FieldInfo baseFieldInfo, validalityFieldInfo;
|
||||
GetMetricsField(propertyName, out baseFieldInfo, out validalityFieldInfo);
|
||||
|
||||
if (baseFieldInfo == null || baseFieldInfo.FieldType != typeof(int) ||
|
||||
(validalityFieldInfo != null && validalityFieldInfo.FieldType != typeof(bool)))
|
||||
{
|
||||
Debug.LogWarning("[OVRSystemProfilerPanel] GetLatestPerfValueInt(): Type mismatch");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (receivedMetricsList.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = receivedMetricsList.Count - 1; i >= 0; --i)
|
||||
{
|
||||
var metrics = receivedMetricsList[i];
|
||||
if (validalityFieldInfo == null || (validalityFieldInfo != null && (bool)validalityFieldInfo.GetValue(metrics)))
|
||||
{
|
||||
return (int)baseFieldInfo.GetValue(metrics);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
float? GetLatestPerfValueFloat(string propertyName)
|
||||
{
|
||||
FieldInfo baseFieldInfo, validalityFieldInfo;
|
||||
GetMetricsField(propertyName, out baseFieldInfo, out validalityFieldInfo);
|
||||
|
||||
if (baseFieldInfo == null || baseFieldInfo.FieldType != typeof(float) ||
|
||||
(validalityFieldInfo != null && validalityFieldInfo.FieldType != typeof(bool)))
|
||||
{
|
||||
Debug.LogWarning("[OVRSystemProfilerPanel] GetLatestPerfValueFloat(): Type mismatch");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (receivedMetricsList.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = receivedMetricsList.Count - 1; i >= 0; --i)
|
||||
{
|
||||
var metrics = receivedMetricsList[i];
|
||||
if (validalityFieldInfo == null || (validalityFieldInfo != null && (bool)validalityFieldInfo.GetValue(metrics)))
|
||||
{
|
||||
return (float)baseFieldInfo.GetValue(metrics);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
float? GetAveragePerfValueFloat(string propertyName)
|
||||
{
|
||||
FieldInfo baseFieldInfo, validalityFieldInfo;
|
||||
GetMetricsField(propertyName, out baseFieldInfo, out validalityFieldInfo);
|
||||
|
||||
if (baseFieldInfo == null || baseFieldInfo.FieldType != typeof(float) ||
|
||||
(validalityFieldInfo != null && validalityFieldInfo.FieldType != typeof(bool)))
|
||||
{
|
||||
Debug.LogWarning("[OVRSystemProfilerPanel] GetAveragePerfValueFloat(): Type mismatch");
|
||||
return null;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
float sum = 0;
|
||||
|
||||
OVRSystemPerfMetrics.PerfMetrics lastMetrics = null;
|
||||
int metricsIndex;
|
||||
for (metricsIndex = receivedMetricsList.Count - 1; metricsIndex >= 0; --metricsIndex)
|
||||
{
|
||||
var metrics = receivedMetricsList[metricsIndex];
|
||||
if (validalityFieldInfo != null && !(bool)validalityFieldInfo.GetValue(metrics))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
lastMetrics = metrics;
|
||||
break;
|
||||
}
|
||||
|
||||
if (lastMetrics == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (; metricsIndex >=0; -- metricsIndex)
|
||||
{
|
||||
var metrics = receivedMetricsList[metricsIndex];
|
||||
if (metrics.frameTime < lastMetrics.frameTime - metricsHistoryDuration)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (validalityFieldInfo != null && !(bool)validalityFieldInfo.GetValue(metrics))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
sum += (float)baseFieldInfo.GetValue(metrics);
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sum / count;
|
||||
}
|
||||
}
|
||||
|
||||
float? GetMaxPerfValueFloat(string propertyName)
|
||||
{
|
||||
FieldInfo baseFieldInfo, validalityFieldInfo;
|
||||
GetMetricsField(propertyName, out baseFieldInfo, out validalityFieldInfo);
|
||||
|
||||
if (baseFieldInfo == null || baseFieldInfo.FieldType != typeof(float) ||
|
||||
(validalityFieldInfo != null && validalityFieldInfo.FieldType != typeof(bool)))
|
||||
{
|
||||
Debug.LogWarning("[OVRSystemProfilerPanel] GetMaxPerfValueFloat(): Type mismatch");
|
||||
return null;
|
||||
}
|
||||
|
||||
OVRSystemPerfMetrics.PerfMetrics lastMetrics = null;
|
||||
int metricsIndex;
|
||||
for (metricsIndex = receivedMetricsList.Count - 1; metricsIndex >= 0; --metricsIndex)
|
||||
{
|
||||
var metrics = receivedMetricsList[metricsIndex];
|
||||
if (validalityFieldInfo != null && !(bool)validalityFieldInfo.GetValue(metrics))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
lastMetrics = metrics;
|
||||
break;
|
||||
}
|
||||
|
||||
if (lastMetrics == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
float? result = null;
|
||||
|
||||
for (; metricsIndex >= 0; --metricsIndex)
|
||||
{
|
||||
var metrics = receivedMetricsList[metricsIndex];
|
||||
if (metrics.frameTime < lastMetrics.frameTime - metricsHistoryDuration)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (validalityFieldInfo != null && !(bool)validalityFieldInfo.GetValue(metrics))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
float value = (float)baseFieldInfo.GetValue(metrics);
|
||||
if (!result.HasValue || result.Value < value)
|
||||
{
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PresentFloatPercentage(string label, string propertyName, bool displayAverage, bool displayMaximum)
|
||||
{
|
||||
float? lastValue = GetLatestPerfValueFloat(propertyName);
|
||||
if (!lastValue.HasValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(label, GUILayout.Width(labelWidth));
|
||||
|
||||
Rect r = EditorGUILayout.BeginVertical();
|
||||
|
||||
float barWidth = (r.width - panelInnerRightPad - progressBarPad * 2) / 3.0f;
|
||||
EditorGUI.ProgressBar(new Rect(r.x, r.y, barWidth, r.height), lastValue.Value, string.Format("{0:F1}%", lastValue.Value * 100.0f));
|
||||
|
||||
if (displayAverage)
|
||||
{
|
||||
float? averageValue = GetAveragePerfValueFloat(propertyName);
|
||||
if (averageValue.HasValue)
|
||||
{
|
||||
EditorGUI.ProgressBar(new Rect(r.x + barWidth + progressBarPad, r.y, barWidth, r.height), averageValue.Value, string.Format("{0:F1}%", averageValue.Value * 100.0f));
|
||||
}
|
||||
}
|
||||
|
||||
if (displayMaximum)
|
||||
{
|
||||
float? maxValue = GetMaxPerfValueFloat(propertyName);
|
||||
if (maxValue.HasValue)
|
||||
{
|
||||
EditorGUI.ProgressBar(new Rect(r.x + (barWidth + progressBarPad) * 2, r.y, barWidth, r.height), maxValue.Value, string.Format("{0:F1}%", maxValue.Value * 100.0f));
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.Space(progressBarHeight);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
void PresentFloatTimeInMs(string label, string propertyName, float maxScale, bool displayAverage, bool displayMaximum)
|
||||
{
|
||||
float? lastValue = GetLatestPerfValueFloat(propertyName);
|
||||
if (!lastValue.HasValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(label, GUILayout.Width(labelWidth));
|
||||
|
||||
Rect r = EditorGUILayout.BeginVertical();
|
||||
|
||||
float barWidth = (r.width - panelInnerRightPad - progressBarPad * 2) / 3.0f;
|
||||
EditorGUI.ProgressBar(new Rect(r.x, r.y, barWidth, r.height), lastValue.Value/maxScale, string.Format("{0:F1} ms", lastValue.Value * 1000.0f));
|
||||
|
||||
if (displayAverage)
|
||||
{
|
||||
float? averageValue = GetAveragePerfValueFloat(propertyName);
|
||||
if (averageValue.HasValue)
|
||||
{
|
||||
EditorGUI.ProgressBar(new Rect(r.x + barWidth + progressBarPad, r.y, barWidth, r.height), averageValue.Value / maxScale, string.Format("{0:F1} ms", averageValue.Value * 1000.0f));
|
||||
}
|
||||
}
|
||||
|
||||
if (displayMaximum)
|
||||
{
|
||||
float? maxValue = GetMaxPerfValueFloat(propertyName);
|
||||
if (maxValue.HasValue)
|
||||
{
|
||||
EditorGUI.ProgressBar(new Rect(r.x + (barWidth + progressBarPad) * 2, r.y, barWidth, r.height), maxValue.Value / maxScale, string.Format("{0:F1} ms", maxValue.Value * 1000.0f));
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.Space(progressBarHeight);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
void PresentIntProperty(string label, string propertyName)
|
||||
{
|
||||
int? lastValue = GetLatestPerfValueInt(propertyName);
|
||||
if (!lastValue.HasValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PresentText(label, lastValue.Value.ToString());
|
||||
}
|
||||
|
||||
void PresentText(string label, string text)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(label, GUILayout.Width(labelWidth));
|
||||
EditorGUILayout.LabelField(text);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
void PresentColumnTitles(string title0, string title1, string title2)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("", GUILayout.Width(labelWidth));
|
||||
|
||||
float windowWidth = position.width;
|
||||
float barWidth = (windowWidth - labelWidth - panelInnerRightPad * 3 ) / 3.0f;
|
||||
EditorGUILayout.LabelField(title0, GUILayout.Width(barWidth));
|
||||
EditorGUILayout.LabelField(title1, GUILayout.Width(barWidth));
|
||||
EditorGUILayout.LabelField(title2, GUILayout.Width(barWidth));
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
// Called as the new window is opened.
|
||||
private void Awake()
|
||||
{
|
||||
InitializeAndroidSdkPath();
|
||||
minSize = new Vector2(400, 300);
|
||||
}
|
||||
|
||||
void InitializeAndroidSdkPath()
|
||||
{
|
||||
androidSdkRootPath = OVRConfig.Instance.GetAndroidSDKPath();
|
||||
}
|
||||
|
||||
// OnDestroy is called to close the EditorWindow window.
|
||||
private void OnDestroy()
|
||||
{
|
||||
DisconnectPerfMetricsTcpServer();
|
||||
}
|
||||
|
||||
// Called multiple times per second on all visible windows.
|
||||
private void Update()
|
||||
{
|
||||
if (tcpClient != null && tcpClient.Connected)
|
||||
{
|
||||
tcpClient.Tick();
|
||||
}
|
||||
|
||||
if (repaintRequested)
|
||||
{
|
||||
Repaint();
|
||||
repaintRequested = false;
|
||||
}
|
||||
}
|
||||
|
||||
void OnConnectionStateChanged()
|
||||
{
|
||||
repaintRequested = true;
|
||||
|
||||
if (tcpClient.connectionState == OVRNetwork.OVRNetworkTcpClient.ConnectionState.Disconnected)
|
||||
{
|
||||
tcpClient.connectionStateChangedCallback -= OnConnectionStateChanged;
|
||||
tcpClient.payloadReceivedCallback -= OnPayloadReceived;
|
||||
}
|
||||
}
|
||||
|
||||
void OnPayloadReceived(int payloadType, byte[] buffer, int start, int length)
|
||||
{
|
||||
if (payloadType == OVRSystemPerfMetrics.PayloadTypeMetrics)
|
||||
{
|
||||
string message = Encoding.UTF8.GetString(buffer, start, length);
|
||||
OnMessageReceived(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarningFormat("[OVRSystemProfilerPanel] unrecongized payload type {0}", payloadType);
|
||||
}
|
||||
}
|
||||
|
||||
void OnMessageReceived(string message)
|
||||
{
|
||||
if (pauseReceiveMetrics)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var metrics = new OVRSystemPerfMetrics.PerfMetrics();
|
||||
if (!metrics.LoadFromJSON(message))
|
||||
{
|
||||
Debug.LogWarning("Cannot analyze metrics: " + message);
|
||||
return;
|
||||
}
|
||||
lock(receivedMetricsList)
|
||||
{
|
||||
if (receivedMetricsList.Count >= maxMetricsFrames)
|
||||
{
|
||||
receivedMetricsList.RemoveAt(0);
|
||||
}
|
||||
receivedMetricsList.Add(metrics);
|
||||
}
|
||||
repaintRequested = true;
|
||||
}
|
||||
|
||||
void ConnectPerfMetricsTcpServer()
|
||||
{
|
||||
tcpClient.connectionStateChangedCallback += OnConnectionStateChanged;
|
||||
tcpClient.payloadReceivedCallback += OnPayloadReceived;
|
||||
|
||||
tcpClient.Connect(remoteListeningPort);
|
||||
|
||||
EditorApplication.playModeStateChanged += OnApplicationPlayModeStateChanged;
|
||||
}
|
||||
|
||||
void DisconnectPerfMetricsTcpServer()
|
||||
{
|
||||
EditorApplication.playModeStateChanged -= OnApplicationPlayModeStateChanged;
|
||||
|
||||
tcpClient.Disconnect();
|
||||
}
|
||||
|
||||
void OnApplicationPlayModeStateChanged(PlayModeStateChange change)
|
||||
{
|
||||
Debug.LogFormat("[OVRSystemPerfMetricsWindow] OnApplicationPlayModeStateChanged {0}", change.ToString());
|
||||
if (change == PlayModeStateChange.ExitingPlayMode)
|
||||
{
|
||||
tcpClient.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
11
Assets/Oculus/VR/Editor/OVRSystemProfilerPanel.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/OVRSystemProfilerPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60f797c78d731a54e9d4a949cfa2f989
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
Assets/Oculus/VR/Editor/Oculus.VR.Editor.asmdef
Normal file
24
Assets/Oculus/VR/Editor/Oculus.VR.Editor.asmdef
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Oculus.VR.Editor",
|
||||
"references": [
|
||||
"Oculus.VR"
|
||||
],
|
||||
"optionalUnityReferences": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.unity.xr.management",
|
||||
"expression": "",
|
||||
"define": "USING_XR_MANAGEMENT"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.xr.oculus",
|
||||
"expression": "",
|
||||
"define": "USING_XR_SDK_OCULUS"
|
||||
}
|
||||
]
|
||||
}
|
||||
7
Assets/Oculus/VR/Editor/Oculus.VR.Editor.asmdef.meta
Normal file
7
Assets/Oculus/VR/Editor/Oculus.VR.Editor.asmdef.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2761a0af0f567748a72629d4bb18a26
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
26
Assets/Oculus/VR/Editor/PathHelper.cs
Normal file
26
Assets/Oculus/VR/Editor/PathHelper.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
public static class PathHelper
|
||||
{
|
||||
public static string MakeRelativePath(string fromPath, string toPath)
|
||||
{
|
||||
var fromUri = new Uri(Path.GetFullPath(fromPath));
|
||||
var toUri = new Uri(Path.GetFullPath(toPath));
|
||||
|
||||
if (fromUri.Scheme != toUri.Scheme)
|
||||
{
|
||||
return toPath;
|
||||
}
|
||||
|
||||
var relativeUri = fromUri.MakeRelativeUri(toUri);
|
||||
var relativePath = Uri.UnescapeDataString(relativeUri.ToString());
|
||||
|
||||
if (toUri.Scheme.Equals("file", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
}
|
||||
|
||||
return relativePath;
|
||||
}
|
||||
}
|
||||
11
Assets/Oculus/VR/Editor/PathHelper.cs.meta
Normal file
11
Assets/Oculus/VR/Editor/PathHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e97d8d54c1d1f16468e12a2079fdd060
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Oculus/VR/Editor/Scenes.meta
Normal file
8
Assets/Oculus/VR/Editor/Scenes.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f177e155338d57548977e581b2950d6a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
671
Assets/Oculus/VR/Editor/Scenes/OVRTransitionScene.unity
Normal file
671
Assets/Oculus/VR/Editor/Scenes/OVRTransitionScene.unity
Normal file
@@ -0,0 +1,671 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!29 &1
|
||||
OcclusionCullingSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_OcclusionBakeSettings:
|
||||
smallestOccluder: 5
|
||||
smallestHole: 0.25
|
||||
backfaceThreshold: 100
|
||||
m_SceneGUID: 00000000000000000000000000000000
|
||||
m_OcclusionCullingData: {fileID: 0}
|
||||
--- !u!104 &2
|
||||
RenderSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 8
|
||||
m_Fog: 0
|
||||
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
||||
m_FogMode: 3
|
||||
m_FogDensity: 0.01
|
||||
m_LinearFogStart: 0
|
||||
m_LinearFogEnd: 300
|
||||
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
|
||||
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
|
||||
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
|
||||
m_AmbientIntensity: 1
|
||||
m_AmbientMode: 0
|
||||
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
|
||||
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_HaloStrength: 0.5
|
||||
m_FlareStrength: 1
|
||||
m_FlareFadeSpeed: 3
|
||||
m_HaloTexture: {fileID: 0}
|
||||
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_DefaultReflectionMode: 0
|
||||
m_DefaultReflectionResolution: 128
|
||||
m_ReflectionBounces: 1
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 0}
|
||||
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 11
|
||||
m_GIWorkflowMode: 1
|
||||
m_GISettings:
|
||||
serializedVersion: 2
|
||||
m_BounceScale: 1
|
||||
m_IndirectOutputScale: 1
|
||||
m_AlbedoBoost: 1
|
||||
m_TemporalCoherenceThreshold: 1
|
||||
m_EnvironmentLightingMode: 0
|
||||
m_EnableBakedLightmaps: 1
|
||||
m_EnableRealtimeLightmaps: 1
|
||||
m_LightmapEditorSettings:
|
||||
serializedVersion: 9
|
||||
m_Resolution: 2
|
||||
m_BakeResolution: 40
|
||||
m_TextureWidth: 1024
|
||||
m_TextureHeight: 1024
|
||||
m_AO: 0
|
||||
m_AOMaxDistance: 1
|
||||
m_CompAOExponent: 1
|
||||
m_CompAOExponentDirect: 0
|
||||
m_Padding: 2
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_LightmapsBakeMode: 1
|
||||
m_TextureCompression: 1
|
||||
m_FinalGather: 0
|
||||
m_FinalGatherFiltering: 1
|
||||
m_FinalGatherRayCount: 256
|
||||
m_ReflectionCompression: 2
|
||||
m_MixedBakeMode: 2
|
||||
m_BakeBackend: 1
|
||||
m_PVRSampling: 1
|
||||
m_PVRDirectSampleCount: 32
|
||||
m_PVRSampleCount: 512
|
||||
m_PVRBounces: 2
|
||||
m_PVRFilterTypeDirect: 0
|
||||
m_PVRFilterTypeIndirect: 0
|
||||
m_PVRFilterTypeAO: 0
|
||||
m_PVRFilteringMode: 1
|
||||
m_PVRCulling: 1
|
||||
m_PVRFilteringGaussRadiusDirect: 1
|
||||
m_PVRFilteringGaussRadiusIndirect: 5
|
||||
m_PVRFilteringGaussRadiusAO: 2
|
||||
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||
m_ShowResolutionOverlay: 1
|
||||
m_LightingDataAsset: {fileID: 0}
|
||||
m_UseShadowmask: 1
|
||||
--- !u!196 &4
|
||||
NavMeshSettings:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_BuildSettings:
|
||||
serializedVersion: 2
|
||||
agentTypeID: 0
|
||||
agentRadius: 0.5
|
||||
agentHeight: 2
|
||||
agentSlope: 45
|
||||
agentClimb: 0.4
|
||||
ledgeDropHeight: 0
|
||||
maxJumpAcrossDistance: 0
|
||||
minRegionArea: 2
|
||||
manualCellSize: 0
|
||||
cellSize: 0.16666667
|
||||
manualTileSize: 0
|
||||
tileSize: 256
|
||||
accuratePlacement: 0
|
||||
debug:
|
||||
m_Flags: 0
|
||||
m_NavMeshData: {fileID: 0}
|
||||
--- !u!1 &25651912
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 25651914}
|
||||
- component: {fileID: 25651913}
|
||||
m_Layer: 0
|
||||
m_Name: Directional Light
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!108 &25651913
|
||||
Light:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 25651912}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 8
|
||||
m_Type: 1
|
||||
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
|
||||
m_Intensity: 1
|
||||
m_Range: 10
|
||||
m_SpotAngle: 30
|
||||
m_CookieSize: 10
|
||||
m_Shadows:
|
||||
m_Type: 2
|
||||
m_Resolution: -1
|
||||
m_CustomResolution: -1
|
||||
m_Strength: 1
|
||||
m_Bias: 0.05
|
||||
m_NormalBias: 0.4
|
||||
m_NearPlane: 0.2
|
||||
m_Cookie: {fileID: 0}
|
||||
m_DrawHalo: 0
|
||||
m_Flare: {fileID: 0}
|
||||
m_RenderMode: 0
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_Lightmapping: 4
|
||||
m_AreaSize: {x: 1, y: 1}
|
||||
m_BounceIntensity: 1
|
||||
m_ColorTemperature: 6570
|
||||
m_UseColorTemperature: 0
|
||||
m_ShadowRadius: 0
|
||||
m_ShadowAngle: 0
|
||||
--- !u!4 &25651914
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 25651912}
|
||||
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
|
||||
m_LocalPosition: {x: 0, y: 3, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
||||
--- !u!1 &1500274086
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 1500274089}
|
||||
- component: {fileID: 1500274088}
|
||||
- component: {fileID: 1500274087}
|
||||
m_Layer: 0
|
||||
m_Name: EventSystem
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &1500274087
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1500274086}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1077351063, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HorizontalAxis: Horizontal
|
||||
m_VerticalAxis: Vertical
|
||||
m_SubmitButton: Submit
|
||||
m_CancelButton: Cancel
|
||||
m_InputActionsPerSecond: 10
|
||||
m_RepeatDelay: 0.5
|
||||
m_ForceModuleActive: 0
|
||||
--- !u!114 &1500274088
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1500274086}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -619905303, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_FirstSelected: {fileID: 0}
|
||||
m_sendNavigationEvents: 1
|
||||
m_DragThreshold: 5
|
||||
--- !u!4 &1500274089
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1500274086}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 3
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1802766121
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 1802766122}
|
||||
- component: {fileID: 1802766124}
|
||||
- component: {fileID: 1802766123}
|
||||
m_Layer: 5
|
||||
m_Name: Title
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1802766122
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1802766121}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 2026874869}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 1}
|
||||
m_AnchorMax: {x: 0.5, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -15}
|
||||
m_SizeDelta: {x: 290, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1802766123
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1802766121}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 24
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 2
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 3
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: OVR Transition Scene
|
||||
--- !u!222 &1802766124
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1802766121}
|
||||
--- !u!1 &1955265764
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 1955265765}
|
||||
- component: {fileID: 1955265767}
|
||||
- component: {fileID: 1955265766}
|
||||
m_Layer: 5
|
||||
m_Name: Log
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1955265765
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1955265764}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 2026874869}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: -15}
|
||||
m_SizeDelta: {x: 290, y: 270}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1955265766
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1955265764}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 0
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 1
|
||||
m_LineSpacing: 1
|
||||
m_Text:
|
||||
--- !u!222 &1955265767
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1955265764}
|
||||
--- !u!1 &2026874868
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 2026874869}
|
||||
- component: {fileID: 2026874871}
|
||||
- component: {fileID: 2026874870}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2026874869
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2026874868}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 1802766122}
|
||||
- {fileID: 1955265765}
|
||||
m_Father: {fileID: 2063971652}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &2026874870
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2026874868}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!222 &2026874871
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2026874868}
|
||||
--- !u!1 &2060762002
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 2060762004}
|
||||
- component: {fileID: 2060762003}
|
||||
m_Layer: 0
|
||||
m_Name: OVRSceneLoader
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &2060762003
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2060762002}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: a6d444f79f5ee4646b26c6d746385e80, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
sceneCheckIntervalSeconds: 1
|
||||
mainCanvas: {fileID: 2063971651}
|
||||
logTextBox: {fileID: 1955265766}
|
||||
--- !u!4 &2060762004
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2060762002}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 2063971652}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &2063971648
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 2063971652}
|
||||
- component: {fileID: 2063971651}
|
||||
- component: {fileID: 2063971650}
|
||||
- component: {fileID: 2063971649}
|
||||
m_Layer: 5
|
||||
m_Name: Canvas
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &2063971649
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2063971648}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1301386320, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreReversedGraphics: 1
|
||||
m_BlockingObjects: 0
|
||||
m_BlockingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
--- !u!114 &2063971650
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2063971648}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1980459831, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_UiScaleMode: 0
|
||||
m_ReferencePixelsPerUnit: 100
|
||||
m_ScaleFactor: 1
|
||||
m_ReferenceResolution: {x: 800, y: 600}
|
||||
m_ScreenMatchMode: 0
|
||||
m_MatchWidthOrHeight: 0
|
||||
m_PhysicalUnit: 3
|
||||
m_FallbackScreenDPI: 96
|
||||
m_DefaultSpriteDPI: 96
|
||||
m_DynamicPixelsPerUnit: 1
|
||||
--- !u!223 &2063971651
|
||||
Canvas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2063971648}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 2
|
||||
m_Camera: {fileID: 2122420806}
|
||||
m_PlaneDistance: 100
|
||||
m_PixelPerfect: 0
|
||||
m_ReceivesEvents: 1
|
||||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 0
|
||||
m_TargetDisplay: 0
|
||||
--- !u!224 &2063971652
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2063971648}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 1}
|
||||
m_LocalScale: {x: 0.003, y: 0.003, z: 0.003}
|
||||
m_Children:
|
||||
- {fileID: 2026874869}
|
||||
m_Father: {fileID: 2060762004}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 300, y: 300}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1 &2122420804
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 2122420807}
|
||||
- component: {fileID: 2122420806}
|
||||
- component: {fileID: 2122420805}
|
||||
m_Layer: 0
|
||||
m_Name: Main Camera
|
||||
m_TagString: MainCamera
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!81 &2122420805
|
||||
AudioListener:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2122420804}
|
||||
m_Enabled: 1
|
||||
--- !u!20 &2122420806
|
||||
Camera:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2122420804}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 2
|
||||
m_ClearFlags: 2
|
||||
m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0}
|
||||
m_NormalizedViewPortRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
near clip plane: 0.3
|
||||
far clip plane: 1000
|
||||
field of view: 60
|
||||
orthographic: 0
|
||||
orthographic size: 5
|
||||
m_Depth: -1
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_RenderingPath: -1
|
||||
m_TargetTexture: {fileID: 0}
|
||||
m_TargetDisplay: 0
|
||||
m_TargetEye: 3
|
||||
m_HDR: 1
|
||||
m_AllowMSAA: 1
|
||||
m_AllowDynamicResolution: 0
|
||||
m_ForceIntoRT: 0
|
||||
m_OcclusionCulling: 1
|
||||
m_StereoConvergence: 10
|
||||
m_StereoSeparation: 0.022
|
||||
--- !u!4 &2122420807
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 2122420804}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d04724945584d684c80c6c509a8ece34
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Oculus/VR/Editor/Tools.meta
Normal file
8
Assets/Oculus/VR/Editor/Tools.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0139b03797a58f45a5178bcb84fc38b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Oculus/VR/Editor/Tools/ovr-platform-util.exe
Normal file
BIN
Assets/Oculus/VR/Editor/Tools/ovr-platform-util.exe
Normal file
Binary file not shown.
7
Assets/Oculus/VR/Editor/Tools/ovr-platform-util.exe.meta
Normal file
7
Assets/Oculus/VR/Editor/Tools/ovr-platform-util.exe.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2198e4210ef342c40a7fdea8f9bab35d
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
4
Assets/Oculus/VR/Editor/network_sec_config.xml
Normal file
4
Assets/Oculus/VR/Editor/network_sec_config.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="false"></base-config>
|
||||
</network-security-config>
|
||||
7
Assets/Oculus/VR/Editor/network_sec_config.xml.meta
Normal file
7
Assets/Oculus/VR/Editor/network_sec_config.xml.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b69c9b95ff9fc8a44b5e162bbca8fbcc
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
107
Assets/Oculus/VR/LICENSE.txt
Normal file
107
Assets/Oculus/VR/LICENSE.txt
Normal file
@@ -0,0 +1,107 @@
|
||||
Oculus Master SDK License Agreement - 1.0
|
||||
|
||||
Effective date: 6/1/2020
|
||||
|
||||
Copyright © Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
The text of this may be found at: https://developer.oculus.com/licenses/oculusmastersdk-1.0/
|
||||
|
||||
This Oculus Master SDK License Agreement ("Agreement") is a legal agreement between you and Oculus governing your use of our Oculus Software Development Kit. Oculus Software Development Kit means any SDK, application programming interfaces ("APIs"), tools, plugins, code, technology, specification, documentation, Platform Services, and/or content made available by us to others, including app developers and content providers (collectively, the "SDK").
|
||||
|
||||
By downloading or using our SDK, you are agreeing to this Agreement along with other applicable terms and conditions such as the additional terms or documents accompanying the SDK, the Oculus Terms of Service, and our Privacy Policy (collectively, "Terms"). If you use the SDK as an interface to, or in conjunction with other Oculus products or services, then the terms for those other products or services also apply.
|
||||
Here, "Oculus" means Facebook Technologies, LLC, formerly known as Oculus VR, LLC, a Delaware limited liability company with its principal place of business at 1 Hacker Way, Menlo Park, California 94025, United States unless set forth otherwise. We may refer to "Oculus" as "we", "our", or "us" in the Agreement.
|
||||
|
||||
You may not use the SDK and may not accept the Agreement if (1) you are a person with whom Oculus is prohibited from transacting business under applicable law, or (2) you are a person barred from using or receiving the SDK by Oculus or under the applicable laws of the United States or other countries including the country in which you are resident or from which you use the SDK. If you are using the SDK on behalf of an entity, you represent and warrant that you have authority to bind that entity to the Agreement and by accepting the Agreement, you are doing so on behalf of that entity (and all references to "you" in the Agreement refer to that entity).
|
||||
|
||||
This Agreement requires the resolution of most disputes between you and Oculus by binding arbitration on an individual basis; class actions and jury trials are not permitted.
|
||||
|
||||
1 License Grant
|
||||
|
||||
1.1 License. Subject to the Terms and the restrictions in this Section, Oculus hereby grants you a limited, royalty-free, non-exclusive, non-transferrable, non-sublicensable, revocable copyright license ("License") during the term of this Agreement to use and reproduce the SDK solely to develop, test, or distribute your Application (defined below) and to enable you and/or your end users access to Oculus features through your Application. You may only use the SDK to develop Applications in connection with Oculus approved hardware and software products ("Oculus Approved Products") unless the documentation accompanying the SDK expressly authorizes broader use such as with other third-party platforms.
|
||||
1.1.1 If the SDK includes any libraries, sample source code, or other materials that we make available specifically for incorporation in your Application (as indicated by applicable documentation), you may incorporate those materials and reproduce and distribute them as part of your Application, including by distributing those materials to third parties contributing to your Application.
|
||||
1.1.2 The SDK may include other content (e.g., sample code) that is for demonstration, reference, or other purposes and is subject to terms and conditions included with such materials. Such materials will be clearly marked in the applicable documentation. Absent such additional terms and conditions, you may modify, distribute, and sublicense any sample source made available as part of the SDK pursuant to the Terms.
|
||||
1.1.3 The SDK may include Oculus content that is subject to your additional right to display the content to your end users through the use of the corresponding SDK, as contemplated by the documentation accompanying such SDK. For example, the SDK may include avatars that you may display to your end users.
|
||||
|
||||
1.2 General Restrictions. The License grant in this Section is solely for the purpose of developing, testing, and promoting your engines, tools, applications, content, games and demos, or other products and features (collectively, "Application") and providing you and/or your end users access to Oculus services and features through your Application as contemplated by applicable documentation accompanying the SDK. You may not (or allow those acting on your behalf to):
|
||||
1.2.1 modify or create derivative works from any SDK or its component (other than sample source code described in this Section or expressly authorized by the documents accompanying the SDK);
|
||||
1.2.2 misrepresent or mask either your identity or your Application's identity when using the SDK or developer accounts;
|
||||
1.2.3 attempt to circumvent any limitations documented with the SDK (e.g., limiting the number of requests you may make or end users you may serve);
|
||||
1.2.4 reverse engineer, decompile, disassemble, or otherwise attempt to extract the source code from the SDK, except to the extent that applicable law expressly permits despite this limitation;
|
||||
1.2.5 alter, restrict, or interfere with the normal operation or functionality of the SDK, the Oculus hardware or software, or Oculus Approved Products, including, but not limited to: (a) the behavior of the "Oculus button" and "XBox button" implemented by the Oculus system software; (b) any on-screen messages or information; (c) the behavior of the proximity sensor in the Oculus hardware implemented by the Oculus system software; (d) any Oculus hardware or software security features; (e) any end user's settings; and (f) the Oculus Flash Screen Warnings or Health and Safety Warnings;
|
||||
1.2.6 use the SDK or your Application in a manner that violates: (a) the Oculus Data Use Policy (where applicable); (b) the Oculus Content Guidelines, or other applicable terms and policies made available on our Developer Policy portal; (c) any rights of Oculus or third parties; (d) applicable laws (such as laws regarding import, export, privacy, health & safety); or (e) other terms of service with Oculus or its affiliates;
|
||||
1.2.7 remove, obscure, or alter any Oculus Terms or any links to or notices of those Terms; or
|
||||
1.28 use or redistribute the SDK or any portion thereof in any manner that would cause the SDK (or any portion thereof) or Oculus to become subject to the terms of any open source license or other restrictions.
|
||||
|
||||
1.3 Distribution and Sublicense Restrictions. The redistribution and sublicense rights under this Section are further subject to the following restrictions: (1) redistribution of sample source code or other materials must include the following copyright notice: "Copyright © Facebook Technologies, LLC and its affiliates. All rights reserved;" and (2) If the sample source code or other materials include a "License" or "Notice" text file, you must provide a copy of the License or Notice file with the sample code.
|
||||
|
||||
1.4 Privacy and Security.
|
||||
1.4.1 You are responsible for the data of your Application and agree to comply with all applicable privacy and data protection laws, as well as our applicable terms and policies, particularly the Oculus Developer Data Use Policy. You represent and warrant that you have provided robust and sufficiently prominent notice to users regarding data processing that includes, at a minimum, that third parties, including Oculus and its affiliates, may collect or receive information from your Application.
|
||||
1.4.2 For purposes of the GDPR, you acknowledge and agree that you are a separate and independent controller of the Developer User Data (as defined in the Oculus Developer Data Use Policy) and Facebook Technologies Ireland Limited (an affiliate of Oculus) is a separate and independent controller of the Oculus User Data (as defined in the Oculus Developer Data Use Policy). The parties do not and will not process Developer User Data nor Oculus User Data as joint controllers. Each party shall comply with the obligations that apply to it as a controller under the GDPR, and each party shall be individually and separately responsible for its own compliance.
|
||||
1.4.3 Notwithstanding the foregoing, to the extent the Developer User Data contain personal data which you process subject to the GDPR, you acknowledge and agree that only for purposes of providing/operating some APIs (for example, Spatial Audio VoIP API) as described in the Data Processing Terms, you have instructed Facebook Technologies Ireland Limited to process such personal data on your behalf as your processor pursuant to this Agreement and the Data Processing Terms, which are incorporated herein by reference.
|
||||
1.4.4 "Personal data," "controller," "processor," and "process" in this Section have the meanings set out in the Data Processing Terms.
|
||||
|
||||
1.5 No Obligations. You have no obligations under this Agreement to license or make available your Application to Oculus or any third parties. Nothing in this Agreement obligates Oculus to enable you or any of your Applications to access, interact with, or retrieve or publish content to any Oculus platform or service. However, Oculus may require you to agree to additional terms as a condition of providing you with such platform services in connection with your use of the SDK. You acknowledge and agree that Oculus may develop products or services that may compete with your Application or any other products or services of yours.
|
||||
|
||||
2 Oculus Platform Services. Oculus and/or its affiliates makes certain Platform Services (defined below) available to you to include and enable in your Application on our Platform. An Application that enables or includes any Platform Service must implement the Oculus Platform Framework with the Application. Once your Application has been authorized for use of the Platform Services, you are not required to update your Application to include new Platform Services that Oculus and/or its affiliates may make available as part of the Oculus Platform Framework. For more information, please visit https://developer.oculus.com.
|
||||
|
||||
2.1 For the purpose of this Section,
|
||||
2.1.1 "Application Services" means services provided by Oculus and/or its affiliates associated with the Platform, including, but not limited to, in-app purchasing, multiplayer matchmaking, friends, leader boards, achievements, Virtual Reality Real Time Systems ("VERTS"), voice over IP and cloud saves, which list may be changed from time to time in Oculus' or its affiliates' sole discretion.
|
||||
2.1.2 "Oculus Platform Framework" means the suite of Oculus platform services, including, but not limited to, the Oculus file distribution and update system (enabling distribution and updates of Applications by Oculus and/or its affiliates, including through generated activation Keys), entitlement system, and account authentication, which list may be changed from time to time in Oculus' or its affiliates' sole discretion.
|
||||
2.1.3 "Platform" means the virtual, mixed, and augmented reality platform made available by Oculus and/or its affiliates, including, but not limited to, the user experience, user interface, store, and social features, usable on hardware approved by Oculus or its affiliates or any third-party device or operating system, including, but not limited to, iOS, Android, Windows, OS X, Linux, and Windows Mobile.
|
||||
2.1.4 "Platform Services" means the Oculus Platform Framework and the Application Services.
|
||||
|
||||
2.2 Key Provision and Redemption. If you request that Oculus generate activation keys for your Application on the Platform ("Keys") and Oculus agrees, you hereby grant Oculus and its affiliates (1) the right to generate Keys for you and (2) a license to make available, reproduce, distribute, perform, and display the Application to end users who have submitted a Key to Oculus or its affiliates. Oculus agrees to authenticate and make the Application available to any end user supplying a valid Key (or have its affiliates do so) (unless the Application has been removed or withdrawn).
|
||||
|
||||
2.3 Platform Services Requirements. You will not make any use of any API, software, code or other item or information supplied by Oculus or its affiliates in connection with the Platform Services other than to enhance the functionality of your Application. In particular, you must not (nor enable others to): (1) defame, abuse, harass, stalk, or threaten others, or to promote or facilitate any prohibited or illegal activities; (2) enable any functionality in your Application that would generate excessive traffic over the Oculus network or servers that would negatively impact other users' experience, or otherwise interfere with or restrict the operation of the Platform Services, or Oculus' or its affiliates' servers or networks providing the Platform Services; (3) remove, obscure, or alter any license terms, policies or terms of service or any links to or notices thereto provided by Oculus or its affiliates; or (4) violate any rights of Oculus, its affiliates, or any third parties. You may not sublicense any software, firmware or other item or information supplied by Oculus or its affiliates in connection with the Platform Services for use by a third party, unless expressly authorized by Oculus or its affiliates to do so. You agree not to use (or encourage the use of) the Platform Services for mission critical, life saving or ultra-hazardous activities. Oculus or its affiliates may suspend operation of or remove any Application that does not comply with the restrictions in this Agreement.
|
||||
|
||||
2.4 Oculus and/or its affiliates may discontinue or change functionality of the Platform Services at any time, and your continued use of the Platform Services or use of any modified or additional Platform Services is conditioned upon your adherence to the terms of this Agreement, as modified by Oculus or its affiliates from time to time.
|
||||
|
||||
3 Intellectual Property
|
||||
|
||||
3.1 Ownership. As between you and Oculus, Oculus and/or its affiliates or licensors own all rights, title, and interest, including all Intellectual Property Rights, in and to the SDK (including associated Oculus content and sample code) and all derivatives thereof. Oculus reserves all rights not expressly granted under the License. As between you and Oculus, you and/or your licensors own all rights, title, and interest in and to your Application, (excluding our SDK), including all Intellectual Property Rights. "Intellectual Property Rights" means any and all worldwide rights under applicable laws of patent, copyright, trade secret, trademark, rights of publicity and privacy, and other proprietary rights.
|
||||
|
||||
3.2 Third-Party Materials. Our SDK may include third-party software offered under an open source license or third-party content subject to a separate third-party agreement. To the extent any of such third-party terms conflicts with this Agreement, such third-party terms will control solely with respect to such third-party software or content.
|
||||
|
||||
3.3 Feedback. If you provide comments, suggestions, recommendations, or other feedback about our SDK or any other Oculus or affiliate product or service, we (and our affiliates and those we allow) may use such information for any purposes without obligation to you.
|
||||
|
||||
3.4 Brand Attribution. This Agreement does not grant you or any third party permission to use our trade names, trademarks, service marks, logos, domain names, and other distinctive brand features (collectively, "Brand Features") except as required for reasonable and customary use in describing the origin of the SDK or reproduction of the copyright notice as required under the License grant. You will not make any statement regarding the SDK or your Application which suggests partnership with, sponsorship by, or endorsement by Oculus or its employee, contractor, contributor, licensor, affiliate, or partner without our prior written permission.
|
||||
|
||||
4 Confidentiality
|
||||
|
||||
4.1 Confidentiality. Our communications to you and our SDK may contain Oculus confidential information, which includes information that is marked confidential or that would normally be considered confidential under the circumstances. If you receive any such information, you will not disclose it to any third party without Oculus' prior written consent. Oculus confidential information does not include information that you independently developed, that was rightfully given to you by a third party without a confidentiality obligation with regard to such information, or that becomes public through no fault of your own. You may disclose Oculus confidential information when compelled to do so by law if you provide us reasonable prior notice, unless a court order prohibits such notice.
|
||||
|
||||
5 Termination
|
||||
|
||||
5.1 Termination. The term of this Agreement will begin on the date on which you click accept, download, or use the SDK or any of its components and will continue until terminated as set forth in this Agreement. Oculus reserves the right to terminate this Agreement with you, or to discontinue or suspend the SDK or any portion or feature or your access thereto for any reason or no reason and at any time without liability or other obligation to you. Without limiting the generality of the foregoing, Oculus reserves the right to terminate this Agreement, including the License, immediately in the event you breach any material provisions of this Agreement or the Terms.
|
||||
|
||||
5.2 Effect of Termination. Upon termination of this Agreement, you will immediately stop using, distributing, or otherwise making available the SDK and all Applications that incorporate the SDK or any of its components, cease all use of the Oculus Brand Features, and destroy or return any cached or stored content, software, or other materials obtained through our SDK.
|
||||
|
||||
5.3 Surviving Provisions. When the Agreement comes to an end, those terms that by their nature are intended to continue indefinitely will continue to apply, including, but not limited to, Section 3 (Intellectual Property), Section 4 (Confidentiality), Section 5 (Termination), Section 6 (Liability) and Section 7 (General Provisions).
|
||||
|
||||
6 Liability
|
||||
|
||||
6.1 Indemnification. Unless prohibited by applicable law, you will indemnify and (at Oculus's option), defend Oculus, its affiliates, subsidiaries, agents, licensors, contributors, directors, officers, employees, suppliers, and distributors (collectively, "Oculus Parties") against all liabilities, damages, losses, costs, fees (including legal fees), and expenses relating to any allegation or third-party legal proceeding arising from: (1) your use of the SDK, or any negligence or misconduct by you, or your employees, agents, vendors, or contractors (collectively "Developer Parties"); (2) any Developer Parties' violation of the Agreement, Terms, or any applicable law and regulation; (3) any of your Application; or (4) End User Data (defined in SDK Data Use Policy).
|
||||
|
||||
6.2 WARRANTIES. EXCEPT AS EXPRESSLY SET OUT IN THE TERMS, THE SDK IS PROVIDED "AS IS" WITHOUT ANY SPECIFIC PROMISES OR WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ANY COMMITMENTS ABOUT THE CONTENT ACCESSED THROUGH THE SDK, THE SPECIFIC FUNCTIONS OF THE SDK OR OUR PLATFORM SERVICE, OR THEIR RELIABILITY, AVAILABILITY, OR ABILITY TO MEET YOUR NEEDS. THE OCULUS PARTIES HEREBY DISCLAIM ANY IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. SOME JURISDICTIONS DO NOT PERMIT THE EXCLUSION OR LIMITATION OF IMPLIED WARRANTIES, SO YOU MAY HAVE ADDITIONAL RIGHTS.
|
||||
|
||||
6.3 LIMITATION OF LIABILITY. TO THE EXTENT PERMITTED BY APPLICABLE LAW, OCULUS PARTIES WILL NOT BE RESPONSIBLE FOR LOST PROFITS, BUSINESS OR GOODWILL, REVENUES, OR DATA; FINANCIAL LOSSES; OR INDIRECT, SPECIAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING AS A RESULT OF THIS AGREEMENT, USE OF THE SDK OR ANY MODIFIED SAMPLE CODE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. YOU AGREE THAT YOUR REMEDIES UNDER THIS AGREEMENT ARE LIMITED SOLELY TO THE RIGHT TO COLLECT MONEY DAMAGES, IF ANY, AND YOU HEREBY WAIVE YOUR RIGHT TO SEEK INJUNCTIVE RELIEF OR OTHER EQUITABLE RELIEF. IF YOU ARE A CALIFORNIA RESIDENT, YOU AGREE TO WAIVE CALIFORNIA CIVIL CODE § 1542, WHICH SAYS: "A GENERAL RELEASE DOES NOT EXTEND TO CLAIMS WHICH THE CREDITOR DOES NOT KNOW OR SUSPECT TO EXIST IN HIS OR HER FAVOR AT THE TIME OF EXECUTING THE RELEASE, WHICH IF KNOWN BY HIM OR HER MUST HAVE MATERIALLY AFFECTED HIS OR HER SETTLEMENT WITH THE DEBTOR." TO THE EXTENT PERMITTED BY LAW, THE CUMULATIVE, AGGREGATE LIABILITY OF OCULUS PARTIES, FOR ANY CLAIM UNDER THE AGREEMENT SHALL NOT EXCEED THE GREATER OF ONE HUNDRED US DOLLARS ($100) OR THE AMOUNT YOU HAVE PAID US IN THE PAST TWELVE MONTHS. IN ALL CASES, OCULUS PARTIES WILL NOT BE LIABLE FOR ANY EXPENSE, LOSS, OR DAMAGE THAT IS NOT REASONABLY FORESEEABLE.
|
||||
|
||||
7 General Provisions
|
||||
|
||||
7.1 Updates. We may need to update the Agreement from time to time, including to accurately reflect the access or uses of our SDK, and so we encourage you to check the Agreement regularly. By continuing to access or use our SDK after any notice of an update to this Agreement, you agree to be bound by them. Any updates to the Disputes section of this Agreement will apply only to disputes that arise after notice of the update takes place. If you do not agree to the updated terms, please stop all access or use of our SDK or. You cannot sidestep your compliance obligations under an updated version of the Agreement by developing against an older release of the SDK or relying on the older Agreement and all updates to your application are subject to the modified Agreement.
|
||||
|
||||
7.2 Authorization. You hereby grant Oculus and its contractors and affiliates the authorization reasonably necessary for Oculus to exercise its rights and perform its obligations under this Agreement, including a limited, royalty-free, non-exclusive license to use, perform, and display the Application you provide to Oculus for testing, evaluation, and approval purposes.
|
||||
|
||||
7.3 General Provisions. You and Oculus are independent contractors with regard to each other. The Agreement does not create any third-party beneficiary rights or any agency, partnership, employment, or joint venture. We are not liable for failure or delay in performance to the extent caused by circumstances beyond our reasonable control. If you do not comply with the Agreement, and Oculus does not take action right away or does not enforce any provision of the Agreement, this inaction or lack of enforcement will not act as a waiver by Oculus of any rights that it may have (such as taking action in the future) or in any way affect the validity of this Agreement or parts thereof. If a particular provision of this Agreement is deemed unenforceable, it will be deemed modified to the minimum extent necessary to render it enforceable and most nearly reflect the intent of the original provision, and all other provisions in this Agreement shall remain in full force and effect. You may not assign or delegate this Agreement or any obligations under this Agreement without our advance written consent. Any such prohibited attempted assignment will be void. Oculus may assign or delegate this Agreement and any of its rights or obligations under the Agreement without your consent or notice to you. This Agreement shall bind the parties and their respective heirs, successors, and permitted assigns. The Agreement is the entire agreement between you and Oculus relating to its subject and supersede any prior or contemporaneous agreements on that subject.
|
||||
|
||||
7.4 Dispute Resolution.
|
||||
7.4.1 If you reside outside the US or your business is located outside the US: You agree that any claim, cause of action, or dispute you have against us that arises out of or relates to any access or use of the SDK must be resolved exclusively in the U.S. District Court for the Northern District of California or a state court located in San Mateo County, that you submit to the personal jurisdiction of either of these courts for the purpose of litigating any such claim, and that the laws of the State of California will govern this Agreement and any such claim, without regard to conflict of law provisions.
|
||||
7.4.2 If you reside in the US or your business is located in the US: You and we agree to arbitrate any claim, cause of action, or dispute between you and us that arises out of or relates to any access or use of the SDK for business or commercial purposes ("commercial claim"). This provision does not cover any commercial claims relating to violations of your or our intellectual property rights, including, but not limited to, copyright infringement, patent infringement, trademark infringement, violations of the brand guidelines, violations of your or our confidential information or trade secrets, or efforts to interfere with our products or engage with our products in unauthorized ways (for example, automated ways).
|
||||
7.4.3 We and you agree that, by entering into this arbitration provision all parties are waiving their respective rights to a trial by jury or to participate in a class or representative action. THE PARTIES AGREE THAT EACH MAY BRING COMMERCIAL CLAIMS AGAINST THE OTHER ONLY IN ITS INDIVIDUAL CAPACITY, AND NOT AS A PLAINTIFF OR CLASS MEMBER IN ANY PURPORTED CLASS, REPRESENTATIVE, OR PRIVATE ATTORNEY GENERAL PROCEEDING. You may bring a commercial claim only on your own behalf and cannot seek relief that would affect other parties. If there is a final judicial determination that any particular commercial claim (or a request for particular relief) cannot be arbitrated in accordance with this paragraph's limitations, then only that commercial claim (or only that request for relief) may be brought in court. All other commercial claims (or requests for relief) remain subject to this paragraph.
|
||||
7.4.4 The Federal Arbitration Act governs the interpretation and enforcement of this arbitration provision. All issues are for an arbitrator to decide, except that only a court may decide issues relating to the scope or enforceability of this arbitration provision or the interpretation of the prohibition of class and representative actions.
|
||||
7.4.5 If any party intends to seek arbitration of a dispute, that party must provide the other party with notice in writing.
|
||||
7.4.6 The arbitration will be governed by the AAA's Commercial Arbitration Rules ("AAA Rules"), as modified by this Agreement, and will be administered by the AAA. If the AAA is unavailable, the parties will agree to another arbitration provider or the court will appoint a substitute. The arbitrator will not be bound by rulings in other arbitrations in which you are not a party. To the fullest extent permitted by applicable law, any evidentiary submissions made in arbitration will be maintained as confidential in the absence of good cause for its disclosure. The arbitrator's award will be maintained as confidential only to the extent necessary to protect either party's trade secrets or proprietary business information or to comply with a legal requirement mandating confidentiality. Each party will be responsible for paying any AAA filing, administrative and arbitrator fees in accordance with AAA Rules, except that we will pay for your filing, administrative, and arbitrator fees if your commercial claim for damages does not exceed $75,000 and is non-frivolous (as measured by the standards set forth in Federal Rule of Civil Procedure 11(b)).
|
||||
7.4.7 If you do not wish to be bound by this provision (including its waiver of class and representative claims), you must notify us as set forth below within 30 days of the first acceptance date of any version of this Agreement containing an arbitration provision. Your notice to us under this subsection must be submitted to the address here: Facebook Technologies, LLC, 1 Hacker Way, Menlo Park, California 94025
|
||||
7.4.8 All commercial claims between us, whether subject to arbitration or not, will be governed by California law, excluding California's conflict of laws rules, except to the extent that California law is contrary to or preempted by federal law.
|
||||
7.4.9 If a commercial claim between you and us is not subject to arbitration, you agree that the claim must be resolved exclusively in the U.S. District Court for the Northern District of California or a state court located in San Mateo County, and that you submit to the personal jurisdiction of either of these courts for the purpose of litigating any such claim.
|
||||
7.4.10 If any provision of this dispute resolution provision is found unenforceable, that provision will be severed and the balance of the dispute resolution provision will remain in full force and effect.
|
||||
7
Assets/Oculus/VR/LICENSE.txt.meta
Normal file
7
Assets/Oculus/VR/LICENSE.txt.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea216613534b07f45adfcdd5ba09cf4e
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
4
Assets/Oculus/VR/Materials.meta
Normal file
4
Assets/Oculus/VR/Materials.meta
Normal file
@@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 981b5bce7fc4a2d43a2169710da4b892
|
||||
DefaultImporter:
|
||||
userData:
|
||||
64
Assets/Oculus/VR/Materials/Arrow.mat
Normal file
64
Assets/Oculus/VR/Materials/Arrow.mat
Normal file
@@ -0,0 +1,64 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 3
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: Arrow
|
||||
m_Shader: {fileID: 10101, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_ShaderKeywords: []
|
||||
m_CustomRenderQueue: -1
|
||||
m_SavedProperties:
|
||||
serializedVersion: 2
|
||||
m_TexEnvs:
|
||||
data:
|
||||
first:
|
||||
name: _MainTex
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
data:
|
||||
first:
|
||||
name: _Shininess
|
||||
second: .699999988
|
||||
data:
|
||||
first:
|
||||
name: _Stencil
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _StencilReadMask
|
||||
second: 255
|
||||
data:
|
||||
first:
|
||||
name: _StencilWriteMask
|
||||
second: 255
|
||||
data:
|
||||
first:
|
||||
name: _StencilComp
|
||||
second: 8
|
||||
data:
|
||||
first:
|
||||
name: _StencilOp
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _ColorMask
|
||||
second: 15
|
||||
m_Colors:
|
||||
data:
|
||||
first:
|
||||
name: _Color
|
||||
second: {r: 1, g: 0, b: 0, a: 1}
|
||||
data:
|
||||
first:
|
||||
name: _Emission
|
||||
second: {r: 0, g: 0, b: 0, a: 0}
|
||||
data:
|
||||
first:
|
||||
name: _SpecColor
|
||||
second: {r: 1, g: 1, b: 1, a: 1}
|
||||
4
Assets/Oculus/VR/Materials/Arrow.mat.meta
Normal file
4
Assets/Oculus/VR/Materials/Arrow.mat.meta
Normal file
@@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 669025377795b574da66d9bb2472fcab
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
76
Assets/Oculus/VR/Materials/BasicHandMaterial.mat
Normal file
76
Assets/Oculus/VR/Materials/BasicHandMaterial.mat
Normal file
@@ -0,0 +1,76 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: BasicHandMaterial
|
||||
m_Shader: {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: c00bf1ce0c68d5646ad7ea3d26b3486d, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 0.508
|
||||
- _Glossiness: 0.389
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
8
Assets/Oculus/VR/Materials/BasicHandMaterial.mat.meta
Normal file
8
Assets/Oculus/VR/Materials/BasicHandMaterial.mat.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ba7d209f622bb44e87b47ce27ee27b7
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
29
Assets/Oculus/VR/Materials/CubeMaterial.mat
Normal file
29
Assets/Oculus/VR/Materials/CubeMaterial.mat
Normal file
@@ -0,0 +1,29 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 5
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: CubeMaterial
|
||||
m_Shader: {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 5
|
||||
m_CustomRenderQueue: -1
|
||||
m_SavedProperties:
|
||||
serializedVersion: 2
|
||||
m_TexEnvs:
|
||||
data:
|
||||
first:
|
||||
name: _MainTex
|
||||
second:
|
||||
m_Texture: {fileID: 2800000, guid: 020d1a102a7f2a14ebf6cefe7b977303, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats: {}
|
||||
m_Colors:
|
||||
data:
|
||||
first:
|
||||
name: _Color
|
||||
second: {r: 1, g: 1, b: 1, a: 1}
|
||||
4
Assets/Oculus/VR/Materials/CubeMaterial.mat.meta
Normal file
4
Assets/Oculus/VR/Materials/CubeMaterial.mat.meta
Normal file
@@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 62db2d638434d5a488dfb1e789e34b37
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
43
Assets/Oculus/VR/Materials/GazePointer.mat
Normal file
43
Assets/Oculus/VR/Materials/GazePointer.mat
Normal file
@@ -0,0 +1,43 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: GazePointer
|
||||
m_Shader: {fileID: 4800000, guid: 38ad33c152e32ee46a9bbbb0e656f7e1, type: 3}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 5
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _AlphaTex:
|
||||
m_Texture: {fileID: 2800000, guid: 8b000a1e9077a124f9ad4e81392fccba, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _Illum:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: 82026cb669304dc4897d2c11d3753141, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _AlphaCutoff: 0
|
||||
- _Cutoff: 0.5
|
||||
- _EmissionLM: 0
|
||||
- _EndRadius: 0.8
|
||||
- _Fill: 0.5
|
||||
- _InvFade: 1.11
|
||||
- _StartRadius: 0.2
|
||||
m_Colors:
|
||||
- _Color: {r: 0, g: 1, b: 0.006896496, a: 1}
|
||||
- _TintColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
|
||||
4
Assets/Oculus/VR/Materials/GazePointer.mat.meta
Normal file
4
Assets/Oculus/VR/Materials/GazePointer.mat.meta
Normal file
@@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fac3b9744290eb4c89b0e4ffd5fe085
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
77
Assets/Oculus/VR/Materials/PlainMaterial.mat
Normal file
77
Assets/Oculus/VR/Materials/PlainMaterial.mat
Normal file
@@ -0,0 +1,77 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: PlainMaterial
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
8
Assets/Oculus/VR/Materials/PlainMaterial.mat.meta
Normal file
8
Assets/Oculus/VR/Materials/PlainMaterial.mat.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26cadeeaa29498d4889f43542f3add58
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
43
Assets/Oculus/VR/Materials/cursor_timer_material.mat
Normal file
43
Assets/Oculus/VR/Materials/cursor_timer_material.mat
Normal file
@@ -0,0 +1,43 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 3
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: cursor_timer_material
|
||||
m_Shader: {fileID: 4800000, guid: b95caf64e2cc3614892026a94bb2be84, type: 3}
|
||||
m_ShaderKeywords: []
|
||||
m_CustomRenderQueue: -1
|
||||
m_SavedProperties:
|
||||
serializedVersion: 2
|
||||
m_TexEnvs:
|
||||
data:
|
||||
first:
|
||||
name: _MainTex
|
||||
second:
|
||||
m_Texture: {fileID: 2800000, guid: 79a33e7a7166c6142ad50f46a9a23d3e, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _ColorRamp
|
||||
second:
|
||||
m_Texture: {fileID: 2800000, guid: 8929c8bc5148a624b8c9d6df0ee6f0ca, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
data:
|
||||
first:
|
||||
name: _Cutoff
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _ColorRampOffset
|
||||
second: 0
|
||||
m_Colors:
|
||||
data:
|
||||
first:
|
||||
name: _Color
|
||||
second: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9531aa878fd5c4749b288b72024e8d2f
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
28
Assets/Oculus/VR/Materials/gaze_cursor.mat
Normal file
28
Assets/Oculus/VR/Materials/gaze_cursor.mat
Normal file
@@ -0,0 +1,28 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 3
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: gaze_cursor
|
||||
m_Shader: {fileID: 4800000, guid: 05b53b473302943b58b8e33c93a38dac, type: 3}
|
||||
m_ShaderKeywords: []
|
||||
m_CustomRenderQueue: -1
|
||||
m_SavedProperties:
|
||||
serializedVersion: 2
|
||||
m_TexEnvs:
|
||||
data:
|
||||
first:
|
||||
name: _MainTex
|
||||
second:
|
||||
m_Texture: {fileID: 2800000, guid: 077028084dceb584798dade6c58d1978, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats: {}
|
||||
m_Colors:
|
||||
data:
|
||||
first:
|
||||
name: _Color
|
||||
second: {r: 1, g: 1, b: 1, a: 1}
|
||||
4
Assets/Oculus/VR/Materials/gaze_cursor.mat.meta
Normal file
4
Assets/Oculus/VR/Materials/gaze_cursor.mat.meta
Normal file
@@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f31de375e167154aa45929466af30e4
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
5
Assets/Oculus/VR/Meshes.meta
Normal file
5
Assets/Oculus/VR/Meshes.meta
Normal file
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db348133d6680dd459f3e1cb19922746
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
BIN
Assets/Oculus/VR/Meshes/Cone.obj
LFS
Normal file
BIN
Assets/Oculus/VR/Meshes/Cone.obj
LFS
Normal file
Binary file not shown.
67
Assets/Oculus/VR/Meshes/Cone.obj.meta
Normal file
67
Assets/Oculus/VR/Meshes/Cone.obj.meta
Normal file
@@ -0,0 +1,67 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c28fa8d61f81fb742b1180a6d4516625
|
||||
ModelImporter:
|
||||
serializedVersion: 16
|
||||
fileIDToRecycleName:
|
||||
100000: //RootNode
|
||||
100002: Mesh1_Model
|
||||
400000: //RootNode
|
||||
400002: Mesh1_Model
|
||||
2300000: Mesh1_Model
|
||||
3300000: Mesh1_Model
|
||||
4300000: Mesh1_Model
|
||||
9500000: //RootNode
|
||||
materials:
|
||||
importMaterials: 0
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
animationCompression: 1
|
||||
animationRotationError: .5
|
||||
animationPositionError: .5
|
||||
animationScaleError: .5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
clipAnimations: []
|
||||
isReadable: 1
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
importBlendShapes: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
optimizeMeshForGPU: 1
|
||||
weldVertices: 1
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVPackMargin: 4
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 90
|
||||
splitTangentsAcrossUV: 0
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 1
|
||||
importAnimation: 1
|
||||
copyAvatar: 0
|
||||
humanDescription:
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: .5
|
||||
foreArmTwist: .5
|
||||
upperLegTwist: .5
|
||||
legTwist: .5
|
||||
armStretch: .0500000007
|
||||
legStretch: .0500000007
|
||||
feetSpacing: 0
|
||||
rootMotionBoneName:
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
animationType: 2
|
||||
additionalBone: 0
|
||||
userData:
|
||||
8
Assets/Oculus/VR/Meshes/HandTracking.meta
Normal file
8
Assets/Oculus/VR/Meshes/HandTracking.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2351ce5621709f649877ae8b768dff34
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Oculus/VR/Meshes/HandTracking/OculusHand_L.fbx
LFS
Normal file
BIN
Assets/Oculus/VR/Meshes/HandTracking/OculusHand_L.fbx
LFS
Normal file
Binary file not shown.
249
Assets/Oculus/VR/Meshes/HandTracking/OculusHand_L.fbx.meta
Normal file
249
Assets/Oculus/VR/Meshes/HandTracking/OculusHand_L.fbx.meta
Normal file
@@ -0,0 +1,249 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 442d5b4503ed83c4897ef44659446587
|
||||
ModelImporter:
|
||||
serializedVersion: 22
|
||||
fileIDToRecycleName:
|
||||
100000: b_l_forearm_stub
|
||||
100002: b_l_index1
|
||||
100004: b_l_index2
|
||||
100006: b_l_index3
|
||||
100008: b_l_index_null
|
||||
100010: b_l_middle1
|
||||
100012: b_l_middle2
|
||||
100014: b_l_middle3
|
||||
100016: b_l_middle_null
|
||||
100018: b_l_pinky0
|
||||
100020: b_l_pinky1
|
||||
100022: b_l_pinky2
|
||||
100024: b_l_pinky3
|
||||
100026: b_l_pinky_null
|
||||
100028: b_l_ring1
|
||||
100030: b_l_ring2
|
||||
100032: b_l_ring3
|
||||
100034: b_l_ring_null
|
||||
100036: b_l_thumb0
|
||||
100038: b_l_thumb1
|
||||
100040: b_l_thumb2
|
||||
100042: b_l_thumb3
|
||||
100044: b_l_thumb_null
|
||||
100046: b_l_wrist
|
||||
100048: l_handMeshNode
|
||||
100050: l_index_dip_fe_axis_marker
|
||||
100052: l_index_finger_pad_marker
|
||||
100054: l_index_finger_tip_marker
|
||||
100056: l_index_fingernail_marker
|
||||
100058: l_index_knuckle_marker
|
||||
100060: l_index_mcp_aa_axis_marker
|
||||
100062: l_index_mcp_fe_axis_marker
|
||||
100064: l_index_palm_collider_base0_marker
|
||||
100066: l_index_palm_collider_base1_marker
|
||||
100068: l_index_palm_knuckle_marker
|
||||
100070: l_index_pip_fe_axis_marker
|
||||
100072: l_middle_dip_fe_axis_marker
|
||||
100074: l_middle_finger_pad_marker
|
||||
100076: l_middle_finger_tip_marker
|
||||
100078: l_middle_fingernail_marker
|
||||
100080: l_middle_knuckle_marker
|
||||
100082: l_middle_mcp_aa_axis_marker
|
||||
100084: l_middle_mcp_fe_axis_marker
|
||||
100086: l_middle_palm_collider_base0_marker
|
||||
100088: l_middle_palm_collider_base1_marker
|
||||
100090: l_middle_palm_knuckle_marker
|
||||
100092: l_middle_pip_fe_axis_marker
|
||||
100094: l_palm_center_marker
|
||||
100096: l_pinky_dip_fe_axis_marker
|
||||
100098: l_pinky_finger_pad_marker
|
||||
100100: l_pinky_finger_tip_marker
|
||||
100102: l_pinky_fingernail_marker
|
||||
100104: l_pinky_knuckle_marker
|
||||
100106: l_pinky_mcp_aa_axis_marker
|
||||
100108: l_pinky_mcp_fe_axis_marker
|
||||
100110: l_pinky_palm_collider_base0_marker
|
||||
100112: l_pinky_palm_collider_base1_marker
|
||||
100114: l_pinky_palm_knuckle_marker
|
||||
100116: l_pinky_pip_fe_axis_marker
|
||||
100118: l_ring_dip_fe_axis_marker
|
||||
100120: l_ring_finger_pad_marker
|
||||
100122: l_ring_finger_tip_marker
|
||||
100124: l_ring_fingernail_marker
|
||||
100126: l_ring_knuckle_marker
|
||||
100128: l_ring_mcp_aa_axis_marker
|
||||
100130: l_ring_mcp_fe_axis_marker
|
||||
100132: l_ring_palm_collider_base0_marker
|
||||
100134: l_ring_palm_collider_base1_marker
|
||||
100136: l_ring_palm_knuckle_marker
|
||||
100138: l_ring_pip_fe_axis_marker
|
||||
100140: l_thumb_cmc_aa_axis_marker
|
||||
100142: l_thumb_cmc_fe_axis_marker
|
||||
100144: l_thumb_finger_pad_marker
|
||||
100146: l_thumb_finger_tip_marker
|
||||
100148: l_thumb_fingernail_marker
|
||||
100150: l_thumb_ip_fe_axis_marker
|
||||
100152: l_thumb_knuckle_marker
|
||||
100154: l_thumb_mcp_fe_axis_marker
|
||||
100156: l_thumb_palm_knuckle_marker
|
||||
100158: //RootNode
|
||||
400000: b_l_forearm_stub
|
||||
400002: b_l_index1
|
||||
400004: b_l_index2
|
||||
400006: b_l_index3
|
||||
400008: b_l_index_null
|
||||
400010: b_l_middle1
|
||||
400012: b_l_middle2
|
||||
400014: b_l_middle3
|
||||
400016: b_l_middle_null
|
||||
400018: b_l_pinky0
|
||||
400020: b_l_pinky1
|
||||
400022: b_l_pinky2
|
||||
400024: b_l_pinky3
|
||||
400026: b_l_pinky_null
|
||||
400028: b_l_ring1
|
||||
400030: b_l_ring2
|
||||
400032: b_l_ring3
|
||||
400034: b_l_ring_null
|
||||
400036: b_l_thumb0
|
||||
400038: b_l_thumb1
|
||||
400040: b_l_thumb2
|
||||
400042: b_l_thumb3
|
||||
400044: b_l_thumb_null
|
||||
400046: b_l_wrist
|
||||
400048: l_handMeshNode
|
||||
400050: l_index_dip_fe_axis_marker
|
||||
400052: l_index_finger_pad_marker
|
||||
400054: l_index_finger_tip_marker
|
||||
400056: l_index_fingernail_marker
|
||||
400058: l_index_knuckle_marker
|
||||
400060: l_index_mcp_aa_axis_marker
|
||||
400062: l_index_mcp_fe_axis_marker
|
||||
400064: l_index_palm_collider_base0_marker
|
||||
400066: l_index_palm_collider_base1_marker
|
||||
400068: l_index_palm_knuckle_marker
|
||||
400070: l_index_pip_fe_axis_marker
|
||||
400072: l_middle_dip_fe_axis_marker
|
||||
400074: l_middle_finger_pad_marker
|
||||
400076: l_middle_finger_tip_marker
|
||||
400078: l_middle_fingernail_marker
|
||||
400080: l_middle_knuckle_marker
|
||||
400082: l_middle_mcp_aa_axis_marker
|
||||
400084: l_middle_mcp_fe_axis_marker
|
||||
400086: l_middle_palm_collider_base0_marker
|
||||
400088: l_middle_palm_collider_base1_marker
|
||||
400090: l_middle_palm_knuckle_marker
|
||||
400092: l_middle_pip_fe_axis_marker
|
||||
400094: l_palm_center_marker
|
||||
400096: l_pinky_dip_fe_axis_marker
|
||||
400098: l_pinky_finger_pad_marker
|
||||
400100: l_pinky_finger_tip_marker
|
||||
400102: l_pinky_fingernail_marker
|
||||
400104: l_pinky_knuckle_marker
|
||||
400106: l_pinky_mcp_aa_axis_marker
|
||||
400108: l_pinky_mcp_fe_axis_marker
|
||||
400110: l_pinky_palm_collider_base0_marker
|
||||
400112: l_pinky_palm_collider_base1_marker
|
||||
400114: l_pinky_palm_knuckle_marker
|
||||
400116: l_pinky_pip_fe_axis_marker
|
||||
400118: l_ring_dip_fe_axis_marker
|
||||
400120: l_ring_finger_pad_marker
|
||||
400122: l_ring_finger_tip_marker
|
||||
400124: l_ring_fingernail_marker
|
||||
400126: l_ring_knuckle_marker
|
||||
400128: l_ring_mcp_aa_axis_marker
|
||||
400130: l_ring_mcp_fe_axis_marker
|
||||
400132: l_ring_palm_collider_base0_marker
|
||||
400134: l_ring_palm_collider_base1_marker
|
||||
400136: l_ring_palm_knuckle_marker
|
||||
400138: l_ring_pip_fe_axis_marker
|
||||
400140: l_thumb_cmc_aa_axis_marker
|
||||
400142: l_thumb_cmc_fe_axis_marker
|
||||
400144: l_thumb_finger_pad_marker
|
||||
400146: l_thumb_finger_tip_marker
|
||||
400148: l_thumb_fingernail_marker
|
||||
400150: l_thumb_ip_fe_axis_marker
|
||||
400152: l_thumb_knuckle_marker
|
||||
400154: l_thumb_mcp_fe_axis_marker
|
||||
400156: l_thumb_palm_knuckle_marker
|
||||
400158: //RootNode
|
||||
2100000: lambert2
|
||||
4300000: l_handMeshNode
|
||||
9500000: //RootNode
|
||||
13700000: l_handMeshNode
|
||||
externalObjects: {}
|
||||
materials:
|
||||
importMaterials: 1
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
materialLocation: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
rigImportErrors:
|
||||
rigImportWarnings:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
importAnimatedCustomProperties: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
extraUserProperties: []
|
||||
clipAnimations: []
|
||||
isReadable: 1
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
importVisibility: 1
|
||||
importBlendShapes: 1
|
||||
importCameras: 1
|
||||
importLights: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
optimizeMeshForGPU: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
preserveHierarchy: 0
|
||||
indexFormat: 0
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
normalCalculationMode: 4
|
||||
importAnimation: 1
|
||||
copyAvatar: 0
|
||||
humanDescription:
|
||||
serializedVersion: 2
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
rootMotionBoneName:
|
||||
rootMotionBoneRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 1
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
animationType: 2
|
||||
humanoidOversampling: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Oculus/VR/Meshes/HandTracking/OculusHand_R.fbx
LFS
Normal file
BIN
Assets/Oculus/VR/Meshes/HandTracking/OculusHand_R.fbx
LFS
Normal file
Binary file not shown.
249
Assets/Oculus/VR/Meshes/HandTracking/OculusHand_R.fbx.meta
Normal file
249
Assets/Oculus/VR/Meshes/HandTracking/OculusHand_R.fbx.meta
Normal file
@@ -0,0 +1,249 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88e2e1bfe11ec6c438b0ade27eaeded1
|
||||
ModelImporter:
|
||||
serializedVersion: 22
|
||||
fileIDToRecycleName:
|
||||
100000: b_r_forearm_stub
|
||||
100002: b_r_index1
|
||||
100004: b_r_index2
|
||||
100006: b_r_index3
|
||||
100008: b_r_index_null
|
||||
100010: b_r_middle1
|
||||
100012: b_r_middle2
|
||||
100014: b_r_middle3
|
||||
100016: b_r_middle_null
|
||||
100018: b_r_pinky0
|
||||
100020: b_r_pinky1
|
||||
100022: b_r_pinky2
|
||||
100024: b_r_pinky3
|
||||
100026: b_r_pinky_null
|
||||
100028: b_r_ring1
|
||||
100030: b_r_ring2
|
||||
100032: b_r_ring3
|
||||
100034: b_r_ring_null
|
||||
100036: b_r_thumb0
|
||||
100038: b_r_thumb1
|
||||
100040: b_r_thumb2
|
||||
100042: b_r_thumb3
|
||||
100044: b_r_thumb_null
|
||||
100046: b_r_wrist
|
||||
100048: //RootNode
|
||||
100050: r_handMeshNode
|
||||
100052: r_index_dip_fe_axis_marker
|
||||
100054: r_index_finger_pad_marker
|
||||
100056: r_index_finger_tip_marker
|
||||
100058: r_index_fingernail_marker
|
||||
100060: r_index_knuckle_marker
|
||||
100062: r_index_mcp_aa_axis_marker
|
||||
100064: r_index_mcp_fe_axis_marker
|
||||
100066: r_index_palm_collider_base0_marker
|
||||
100068: r_index_palm_collider_base1_marker
|
||||
100070: r_index_palm_knuckle_marker
|
||||
100072: r_index_pip_fe_axis_marker
|
||||
100074: r_middle_dip_fe_axis_marker
|
||||
100076: r_middle_finger_pad_marker
|
||||
100078: r_middle_finger_tip_marker
|
||||
100080: r_middle_fingernail_marker
|
||||
100082: r_middle_knuckle_marker
|
||||
100084: r_middle_mcp_aa_axis_marker
|
||||
100086: r_middle_mcp_fe_axis_marker
|
||||
100088: r_middle_palm_collider_base0_marker
|
||||
100090: r_middle_palm_collider_base1_marker
|
||||
100092: r_middle_palm_knuckle_marker
|
||||
100094: r_middle_pip_fe_axis_marker
|
||||
100096: r_palm_center_marker
|
||||
100098: r_pinky_dip_fe_axis_marker
|
||||
100100: r_pinky_finger_pad_marker
|
||||
100102: r_pinky_finger_tip_marker
|
||||
100104: r_pinky_fingernail_marker
|
||||
100106: r_pinky_knuckle_marker
|
||||
100108: r_pinky_mcp_aa_axis_marker
|
||||
100110: r_pinky_mcp_fe_axis_marker
|
||||
100112: r_pinky_palm_collider_base0_marker
|
||||
100114: r_pinky_palm_collider_base1_marker
|
||||
100116: r_pinky_palm_knuckle_marker
|
||||
100118: r_pinky_pip_fe_axis_marker
|
||||
100120: r_ring_dip_fe_axis_marker
|
||||
100122: r_ring_finger_pad_marker
|
||||
100124: r_ring_finger_tip_marker
|
||||
100126: r_ring_fingernail_marker
|
||||
100128: r_ring_knuckle_marker
|
||||
100130: r_ring_mcp_aa_axis_marker
|
||||
100132: r_ring_mcp_fe_axis_marker
|
||||
100134: r_ring_palm_collider_base0_marker
|
||||
100136: r_ring_palm_collider_base1_marker
|
||||
100138: r_ring_palm_knuckle_marker
|
||||
100140: r_ring_pip_fe_axis_marker
|
||||
100142: r_thumb_cmc_aa_axis_marker
|
||||
100144: r_thumb_cmc_fe_axis_marker
|
||||
100146: r_thumb_finger_pad_marker
|
||||
100148: r_thumb_finger_tip_marker
|
||||
100150: r_thumb_fingernail_marker
|
||||
100152: r_thumb_ip_fe_axis_marker
|
||||
100154: r_thumb_knuckle_marker
|
||||
100156: r_thumb_mcp_fe_axis_marker
|
||||
100158: r_thumb_palm_knuckle_marker
|
||||
400000: b_r_forearm_stub
|
||||
400002: b_r_index1
|
||||
400004: b_r_index2
|
||||
400006: b_r_index3
|
||||
400008: b_r_index_null
|
||||
400010: b_r_middle1
|
||||
400012: b_r_middle2
|
||||
400014: b_r_middle3
|
||||
400016: b_r_middle_null
|
||||
400018: b_r_pinky0
|
||||
400020: b_r_pinky1
|
||||
400022: b_r_pinky2
|
||||
400024: b_r_pinky3
|
||||
400026: b_r_pinky_null
|
||||
400028: b_r_ring1
|
||||
400030: b_r_ring2
|
||||
400032: b_r_ring3
|
||||
400034: b_r_ring_null
|
||||
400036: b_r_thumb0
|
||||
400038: b_r_thumb1
|
||||
400040: b_r_thumb2
|
||||
400042: b_r_thumb3
|
||||
400044: b_r_thumb_null
|
||||
400046: b_r_wrist
|
||||
400048: //RootNode
|
||||
400050: r_handMeshNode
|
||||
400052: r_index_dip_fe_axis_marker
|
||||
400054: r_index_finger_pad_marker
|
||||
400056: r_index_finger_tip_marker
|
||||
400058: r_index_fingernail_marker
|
||||
400060: r_index_knuckle_marker
|
||||
400062: r_index_mcp_aa_axis_marker
|
||||
400064: r_index_mcp_fe_axis_marker
|
||||
400066: r_index_palm_collider_base0_marker
|
||||
400068: r_index_palm_collider_base1_marker
|
||||
400070: r_index_palm_knuckle_marker
|
||||
400072: r_index_pip_fe_axis_marker
|
||||
400074: r_middle_dip_fe_axis_marker
|
||||
400076: r_middle_finger_pad_marker
|
||||
400078: r_middle_finger_tip_marker
|
||||
400080: r_middle_fingernail_marker
|
||||
400082: r_middle_knuckle_marker
|
||||
400084: r_middle_mcp_aa_axis_marker
|
||||
400086: r_middle_mcp_fe_axis_marker
|
||||
400088: r_middle_palm_collider_base0_marker
|
||||
400090: r_middle_palm_collider_base1_marker
|
||||
400092: r_middle_palm_knuckle_marker
|
||||
400094: r_middle_pip_fe_axis_marker
|
||||
400096: r_palm_center_marker
|
||||
400098: r_pinky_dip_fe_axis_marker
|
||||
400100: r_pinky_finger_pad_marker
|
||||
400102: r_pinky_finger_tip_marker
|
||||
400104: r_pinky_fingernail_marker
|
||||
400106: r_pinky_knuckle_marker
|
||||
400108: r_pinky_mcp_aa_axis_marker
|
||||
400110: r_pinky_mcp_fe_axis_marker
|
||||
400112: r_pinky_palm_collider_base0_marker
|
||||
400114: r_pinky_palm_collider_base1_marker
|
||||
400116: r_pinky_palm_knuckle_marker
|
||||
400118: r_pinky_pip_fe_axis_marker
|
||||
400120: r_ring_dip_fe_axis_marker
|
||||
400122: r_ring_finger_pad_marker
|
||||
400124: r_ring_finger_tip_marker
|
||||
400126: r_ring_fingernail_marker
|
||||
400128: r_ring_knuckle_marker
|
||||
400130: r_ring_mcp_aa_axis_marker
|
||||
400132: r_ring_mcp_fe_axis_marker
|
||||
400134: r_ring_palm_collider_base0_marker
|
||||
400136: r_ring_palm_collider_base1_marker
|
||||
400138: r_ring_palm_knuckle_marker
|
||||
400140: r_ring_pip_fe_axis_marker
|
||||
400142: r_thumb_cmc_aa_axis_marker
|
||||
400144: r_thumb_cmc_fe_axis_marker
|
||||
400146: r_thumb_finger_pad_marker
|
||||
400148: r_thumb_finger_tip_marker
|
||||
400150: r_thumb_fingernail_marker
|
||||
400152: r_thumb_ip_fe_axis_marker
|
||||
400154: r_thumb_knuckle_marker
|
||||
400156: r_thumb_mcp_fe_axis_marker
|
||||
400158: r_thumb_palm_knuckle_marker
|
||||
2100000: lambert2
|
||||
4300000: r_handMeshNode
|
||||
9500000: //RootNode
|
||||
13700000: r_handMeshNode
|
||||
externalObjects: {}
|
||||
materials:
|
||||
importMaterials: 1
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
materialLocation: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
rigImportErrors:
|
||||
rigImportWarnings:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
importAnimatedCustomProperties: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
extraUserProperties: []
|
||||
clipAnimations: []
|
||||
isReadable: 1
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
importVisibility: 1
|
||||
importBlendShapes: 1
|
||||
importCameras: 1
|
||||
importLights: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
optimizeMeshForGPU: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
preserveHierarchy: 0
|
||||
indexFormat: 0
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
normalCalculationMode: 4
|
||||
importAnimation: 1
|
||||
copyAvatar: 0
|
||||
humanDescription:
|
||||
serializedVersion: 2
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
rootMotionBoneName:
|
||||
rootMotionBoneRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 1
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
animationType: 2
|
||||
humanoidOversampling: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Oculus/VR/Meshes/OculusTouchForQuest2.meta
Normal file
8
Assets/Oculus/VR/Meshes/OculusTouchForQuest2.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba23c36ea16dd114fa00c8030cd603b8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b444df89af4e85a4bb475195ea2786c2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: OculusTouchForQuest2_Left
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords: _METALLICGLOSSMAP
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: 0368149f02b42c14095151aaff644f46, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 2800000, guid: 561aabc57cbcf9046873810d9988f99e, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _Shininess: 0.078125
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ec1bc286fd619a4684490e761da7545
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: OculusTouchForQuest2_Right
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords: _METALLICGLOSSMAP
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: e441be63d6e5c294aae032fe28daf965, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 2800000, guid: 561aabc57cbcf9046873810d9988f99e, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0cd3ed1aad0963f4a8819e086ec6909f
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Oculus/VR/Meshes/OculusTouchForQuest2/OculusTouchForQuest2_Left.fbx
LFS
Normal file
BIN
Assets/Oculus/VR/Meshes/OculusTouchForQuest2/OculusTouchForQuest2_Left.fbx
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,155 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4470b2e79e849934cbb5781e7100483b
|
||||
ModelImporter:
|
||||
serializedVersion: 23
|
||||
fileIDToRecycleName:
|
||||
100000: b_button_oculus
|
||||
100002: b_button_x
|
||||
100004: b_button_y
|
||||
100006: b_thumbstick
|
||||
100008: b_trigger_front
|
||||
100010: b_trigger_grip
|
||||
100012: f_button_oculus
|
||||
100014: f_button_oculus_hmnul
|
||||
100016: f_button_x
|
||||
100018: f_button_x_hmnul
|
||||
100020: f_button_y
|
||||
100022: f_button_y_hmnul
|
||||
100024: f_thumbstick
|
||||
100026: f_thumbstick_hmnul
|
||||
100028: f_trigger_front
|
||||
100030: f_trigger_front_hmnul
|
||||
100032: f_trigger_grip
|
||||
100034: f_trigger_grip_hmnul
|
||||
100036: f_world
|
||||
100038: //RootNode
|
||||
100040: left_oculus_controller_rig
|
||||
100042: left_oculus_controller_world
|
||||
100044: oculus_controller_l_mesh
|
||||
100046: oculus_controller_l_skm
|
||||
100048: RIG_left_oculus_controller_world
|
||||
100050: left_laser_begin
|
||||
100052: pasted__laser_end_pointer
|
||||
400000: b_button_oculus
|
||||
400002: b_button_x
|
||||
400004: b_button_y
|
||||
400006: b_thumbstick
|
||||
400008: b_trigger_front
|
||||
400010: b_trigger_grip
|
||||
400012: f_button_oculus
|
||||
400014: f_button_oculus_hmnul
|
||||
400016: f_button_x
|
||||
400018: f_button_x_hmnul
|
||||
400020: f_button_y
|
||||
400022: f_button_y_hmnul
|
||||
400024: f_thumbstick
|
||||
400026: f_thumbstick_hmnul
|
||||
400028: f_trigger_front
|
||||
400030: f_trigger_front_hmnul
|
||||
400032: f_trigger_grip
|
||||
400034: f_trigger_grip_hmnul
|
||||
400036: f_world
|
||||
400038: //RootNode
|
||||
400040: left_oculus_controller_rig
|
||||
400042: left_oculus_controller_world
|
||||
400044: oculus_controller_l_mesh
|
||||
400046: oculus_controller_l_skm
|
||||
400048: RIG_left_oculus_controller_world
|
||||
400050: left_laser_begin
|
||||
400052: pasted__laser_end_pointer
|
||||
2100000: left_controler_blinn
|
||||
4300000: oculus_controller_l_mesh
|
||||
7400000: Take 001
|
||||
9500000: //RootNode
|
||||
13700000: oculus_controller_l_mesh
|
||||
externalObjects:
|
||||
- first:
|
||||
type: UnityEngine:Material
|
||||
assembly: UnityEngine.CoreModule
|
||||
name: left_controler_blinn
|
||||
second: {fileID: 2100000, guid: 9ec1bc286fd619a4684490e761da7545, type: 2}
|
||||
materials:
|
||||
importMaterials: 1
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
materialLocation: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
rigImportErrors:
|
||||
rigImportWarnings:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
importAnimatedCustomProperties: 0
|
||||
importConstraints: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
extraUserProperties: []
|
||||
clipAnimations: []
|
||||
isReadable: 1
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
useSRGBMaterialColor: 1
|
||||
importVisibility: 1
|
||||
importBlendShapes: 1
|
||||
importCameras: 1
|
||||
importLights: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
optimizeMeshForGPU: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
preserveHierarchy: 0
|
||||
indexFormat: 0
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
previousCalculatedGlobalScale: 0.01
|
||||
hasPreviousCalculatedGlobalScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
normalCalculationMode: 4
|
||||
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
|
||||
blendShapeNormalImportMode: 1
|
||||
normalSmoothingSource: 0
|
||||
importAnimation: 1
|
||||
copyAvatar: 0
|
||||
humanDescription:
|
||||
serializedVersion: 2
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 1
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
animationType: 2
|
||||
humanoidOversampling: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Oculus/VR/Meshes/OculusTouchForQuest2/OculusTouchForQuest2_Right.fbx
LFS
Normal file
BIN
Assets/Oculus/VR/Meshes/OculusTouchForQuest2/OculusTouchForQuest2_Right.fbx
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,161 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47b4082d2994ed045925b7ff6c245fb5
|
||||
ModelImporter:
|
||||
serializedVersion: 23
|
||||
fileIDToRecycleName:
|
||||
100000: b_button_a
|
||||
100002: b_button_b
|
||||
100004: b_button_oculus
|
||||
100006: b_thumbstick
|
||||
100008: b_trigger_front
|
||||
100010: b_trigger_grip
|
||||
100012: f_button_a
|
||||
100014: f_button_a_hmnul
|
||||
100016: f_button_b
|
||||
100018: f_button_b_hmnul
|
||||
100020: f_button_oculus
|
||||
100022: f_button_oculus_hmnul
|
||||
100024: f_thumbstick
|
||||
100026: f_thumbstick_hmnul
|
||||
100028: f_trigger_front
|
||||
100030: f_trigger_front_hmnul
|
||||
100032: f_trigger_grip
|
||||
100034: f_trigger_grip_hmnul
|
||||
100036: f_world
|
||||
100038: oculus_controller_r_mesh
|
||||
100040: oculus_controller_r_skm
|
||||
100042: RIG_right_oculus_controller_world
|
||||
100044: //RootNode
|
||||
100046: right_oculus_controller_rig
|
||||
100048: right_oculus_controller_world
|
||||
100050: pasted__laser_end_pointer
|
||||
100052: right_laser_begin
|
||||
400000: b_button_a
|
||||
400002: b_button_b
|
||||
400004: b_button_oculus
|
||||
400006: b_thumbstick
|
||||
400008: b_trigger_front
|
||||
400010: b_trigger_grip
|
||||
400012: f_button_a
|
||||
400014: f_button_a_hmnul
|
||||
400016: f_button_b
|
||||
400018: f_button_b_hmnul
|
||||
400020: f_button_oculus
|
||||
400022: f_button_oculus_hmnul
|
||||
400024: f_thumbstick
|
||||
400026: f_thumbstick_hmnul
|
||||
400028: f_trigger_front
|
||||
400030: f_trigger_front_hmnul
|
||||
400032: f_trigger_grip
|
||||
400034: f_trigger_grip_hmnul
|
||||
400036: f_world
|
||||
400038: oculus_controller_r_mesh
|
||||
400040: oculus_controller_r_skm
|
||||
400042: RIG_right_oculus_controller_world
|
||||
400044: //RootNode
|
||||
400046: right_oculus_controller_rig
|
||||
400048: right_oculus_controller_world
|
||||
400050: pasted__laser_end_pointer
|
||||
400052: right_laser_begin
|
||||
2100000: right_controller_blinn
|
||||
2100002: right_controler_blinn
|
||||
4300000: oculus_controller_r_mesh
|
||||
7400000: Take 001
|
||||
9500000: //RootNode
|
||||
13700000: oculus_controller_r_mesh
|
||||
externalObjects:
|
||||
- first:
|
||||
type: UnityEngine:Material
|
||||
assembly: UnityEngine.CoreModule
|
||||
name: right_controler_blinn
|
||||
second: {fileID: 2100000, guid: 0cd3ed1aad0963f4a8819e086ec6909f, type: 2}
|
||||
- first:
|
||||
type: UnityEngine:Material
|
||||
assembly: UnityEngine.CoreModule
|
||||
name: right_controller_blinn
|
||||
second: {fileID: 2100000, guid: 0cd3ed1aad0963f4a8819e086ec6909f, type: 2}
|
||||
materials:
|
||||
importMaterials: 1
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
materialLocation: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
rigImportErrors:
|
||||
rigImportWarnings:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
importAnimatedCustomProperties: 0
|
||||
importConstraints: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
extraUserProperties: []
|
||||
clipAnimations: []
|
||||
isReadable: 1
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
useSRGBMaterialColor: 1
|
||||
importVisibility: 1
|
||||
importBlendShapes: 1
|
||||
importCameras: 1
|
||||
importLights: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
optimizeMeshForGPU: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
preserveHierarchy: 0
|
||||
indexFormat: 0
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
previousCalculatedGlobalScale: 0.01
|
||||
hasPreviousCalculatedGlobalScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
normalCalculationMode: 4
|
||||
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
|
||||
blendShapeNormalImportMode: 1
|
||||
normalSmoothingSource: 0
|
||||
importAnimation: 1
|
||||
copyAvatar: 0
|
||||
humanDescription:
|
||||
serializedVersion: 2
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 1
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
animationType: 2
|
||||
humanoidOversampling: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Oculus/VR/Meshes/OculusTouchForQuestAndRiftS.meta
Normal file
8
Assets/Oculus/VR/Meshes/OculusTouchForQuestAndRiftS.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2fd2b8bc5b4516243b0b24003c6e439d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e2780dbfd762e7241a81199a8839ea4a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,76 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: OculusTouchForQuestAndRiftS_Material
|
||||
m_Shader: {fileID: 10703, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: a53d1d4e8207acf45b310f189c342b70, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 0.21960786, g: 0.21960786, b: 0.21960786, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01ac879f6ce09924e9c26663f798beaf
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user