diff --git a/Assets/Scenes/Test Scenes/Static Ring.unity b/Assets/Scenes/Test Scenes/Static Ring.unity index bdd974c..8c0c359 100644 --- a/Assets/Scenes/Test Scenes/Static Ring.unity +++ b/Assets/Scenes/Test Scenes/Static Ring.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27c7e58bdeea7e6776bb5fbb5763674ff0265ba2834da59602e4ccf244ca4e3f -size 21859941 +oid sha256:59be6dd0cde72afc669f40ed37ef142881d480a0f9959356ebb5669c0207360f +size 22472672 diff --git a/Assets/Scripts/DemoUtility.meta b/Assets/Scripts/DemoUtility.meta new file mode 100644 index 0000000..1d4d2e2 --- /dev/null +++ b/Assets/Scripts/DemoUtility.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bc2dd9d1274c0e04fa36b500a6c86c71 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/DemoUtility/SmoothFollowBehaviour.cs b/Assets/Scripts/DemoUtility/SmoothFollowBehaviour.cs new file mode 100644 index 0000000..27acba3 --- /dev/null +++ b/Assets/Scripts/DemoUtility/SmoothFollowBehaviour.cs @@ -0,0 +1,25 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace EMD.DemoUtility +{ + public class SmoothFollowBehaviour : MonoBehaviour + { + + [SerializeField] + private Transform m_Target; + + [SerializeField] + private float m_SmoothValue = 0.5f; + + void LateUpdate() + { + if (m_Target != null) + { + transform.position = Vector3.Lerp(transform.position, m_Target.position, m_SmoothValue); + transform.rotation = Quaternion.Lerp(transform.rotation, m_Target.rotation, m_SmoothValue); + } + } + } +} diff --git a/Assets/Scripts/DemoUtility/SmoothFollowBehaviour.cs.meta b/Assets/Scripts/DemoUtility/SmoothFollowBehaviour.cs.meta new file mode 100644 index 0000000..b7441b0 --- /dev/null +++ b/Assets/Scripts/DemoUtility/SmoothFollowBehaviour.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 068e885c69b62b14fac7da48f837e74d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Static Physics/ArtificialGravity.cs b/Assets/Scripts/Static Physics/ArtificialGravity.cs index d4bec99..87cda21 100644 --- a/Assets/Scripts/Static Physics/ArtificialGravity.cs +++ b/Assets/Scripts/Static Physics/ArtificialGravity.cs @@ -35,7 +35,8 @@ public class ArtificialGravity : MonoBehaviour return; Vector3 direction = Ship.getDownDirection(transform.position, false); - float force = direction.magnitude * Mathf.Pow(2 * Mathf.PI / Ship.RotationPeriod, 2); + float distance = direction.magnitude; + float force = distance * Mathf.Pow(2 * Mathf.PI / Ship.RotationPeriod, 2); Debug.DrawRay(transform.position, transform.position + direction); @@ -45,7 +46,7 @@ public class ArtificialGravity : MonoBehaviour { direction = Ship.getPerpendicularDirection(transform.position); - rb.AddForce(direction * Ship.CorrelusStrength * m_correlusMultiplier * Time.fixedDeltaTime, ForceMode.Acceleration); + rb.AddForce(direction * Ship.CorrelusStrength * m_correlusMultiplier * Time.fixedDeltaTime * distance, ForceMode.Acceleration); Debug.DrawRay(transform.position, direction, Color.blue); } } diff --git a/Assets/SteamVR.meta b/Assets/SteamVR.meta new file mode 100644 index 0000000..208cae0 --- /dev/null +++ b/Assets/SteamVR.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4bc2544df28a1a942b15ec45a8ee7b14 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Editor.meta b/Assets/SteamVR/Editor.meta new file mode 100644 index 0000000..90b104c --- /dev/null +++ b/Assets/SteamVR/Editor.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: c33af0785775d7548b22541da37936fe +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/Assets/SteamVR/Editor/SteamVR_Editor.cs b/Assets/SteamVR/Editor/SteamVR_Editor.cs new file mode 100644 index 0000000..8889e49 --- /dev/null +++ b/Assets/SteamVR/Editor/SteamVR_Editor.cs @@ -0,0 +1,127 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Custom inspector display for SteamVR_Camera +// +//============================================================================= + +using UnityEngine; +using UnityEditor; +using System.IO; + +[CustomEditor(typeof(SteamVR_Camera)), CanEditMultipleObjects] +public class SteamVR_Editor : Editor +{ + int bannerHeight = 150; + Texture logo; + + SerializedProperty script, wireframe; + + string GetResourcePath() + { + var ms = MonoScript.FromScriptableObject(this); + var path = AssetDatabase.GetAssetPath(ms); + path = Path.GetDirectoryName(path); + return path.Substring(0, path.Length - "Editor".Length) + "Textures/"; + } + + void OnEnable() + { + var resourcePath = GetResourcePath(); + + logo = AssetDatabase.LoadAssetAtPath(resourcePath + "logo.png"); + + script = serializedObject.FindProperty("m_Script"); + + wireframe = serializedObject.FindProperty("wireframe"); + + foreach (SteamVR_Camera target in targets) + target.ForceLast(); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + var rect = GUILayoutUtility.GetRect(Screen.width - 38, bannerHeight, GUI.skin.box); + if (logo) + GUI.DrawTexture(rect, logo, ScaleMode.ScaleToFit); + + if (!Application.isPlaying) + { + var expand = false; + var collapse = false; + foreach (SteamVR_Camera target in targets) + { + if (AssetDatabase.Contains(target)) + continue; + if (target.isExpanded) + collapse = true; + else + expand = true; + } + + if (expand) + { + GUILayout.BeginHorizontal(); + if (GUILayout.Button("Expand")) + { + foreach (SteamVR_Camera target in targets) + { + if (AssetDatabase.Contains(target)) + continue; + if (!target.isExpanded) + { + target.Expand(); + EditorUtility.SetDirty(target); + } + } + } + GUILayout.Space(18); + GUILayout.EndHorizontal(); + } + + if (collapse) + { + GUILayout.BeginHorizontal(); + if (GUILayout.Button("Collapse")) + { + foreach (SteamVR_Camera target in targets) + { + if (AssetDatabase.Contains(target)) + continue; + if (target.isExpanded) + { + target.Collapse(); + EditorUtility.SetDirty(target); + } + } + } + GUILayout.Space(18); + GUILayout.EndHorizontal(); + } + } + + EditorGUILayout.PropertyField(script); + EditorGUILayout.PropertyField(wireframe); + + serializedObject.ApplyModifiedProperties(); + } + + public static void ExportPackage() + { + AssetDatabase.ExportPackage(new string[] { + "Assets/SteamVR", + "Assets/Plugins/openvr_api.cs", + "Assets/Plugins/openvr_api.bundle", + "Assets/Plugins/x86/openvr_api.dll", + "Assets/Plugins/x86/steam_api.dll", + "Assets/Plugins/x86/libsteam_api.so", + "Assets/Plugins/x86_64/openvr_api.dll", + "Assets/Plugins/x86_64/steam_api.dll", + "Assets/Plugins/x86_64/libsteam_api.so", + "Assets/Plugins/x86_64/libopenvr_api.so", + }, "steamvr.unitypackage", ExportPackageOptions.Recurse); + EditorApplication.Exit(0); + } +} + diff --git a/Assets/SteamVR/Editor/SteamVR_Editor.cs.meta b/Assets/SteamVR/Editor/SteamVR_Editor.cs.meta new file mode 100644 index 0000000..1b344ed --- /dev/null +++ b/Assets/SteamVR/Editor/SteamVR_Editor.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5ba22c80948c94e44a82b9fd1b3abd0d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/Assets/SteamVR/Editor/SteamVR_Preferences.cs b/Assets/SteamVR/Editor/SteamVR_Preferences.cs new file mode 100644 index 0000000..ad3e000 --- /dev/null +++ b/Assets/SteamVR/Editor/SteamVR_Preferences.cs @@ -0,0 +1,48 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Preferences pane for how SteamVR plugin behaves. +// +//============================================================================= + +using UnityEngine; +using UnityEditor; + +public class SteamVR_Preferences +{ + /// + /// Should SteamVR automatically enable VR when opening Unity or pressing play. + /// + public static bool AutoEnableVR + { + get + { + return EditorPrefs.GetBool("SteamVR_AutoEnableVR", true); + } + set + { + EditorPrefs.SetBool("SteamVR_AutoEnableVR", value); + } + } + + [PreferenceItem("SteamVR")] + static void PreferencesGUI() + { + EditorGUILayout.BeginVertical(); + EditorGUILayout.Space(); + + // Automatically Enable VR + { + string title = "Automatically Enable VR"; + string tooltip = "Should SteamVR automatically enable VR on launch and play?"; + AutoEnableVR = EditorGUILayout.Toggle(new GUIContent(title, tooltip), AutoEnableVR); + string helpMessage = "To enable VR manually:\n"; + helpMessage += "- go to Edit -> Project Settings -> Player,\n"; + helpMessage += "- tick 'Virtual Reality Supported',\n"; + helpMessage += "- make sure OpenVR is in the 'Virtual Reality SDKs' list."; + EditorGUILayout.HelpBox(helpMessage, MessageType.Info); + } + + EditorGUILayout.EndVertical(); + } +} + diff --git a/Assets/SteamVR/Editor/SteamVR_Preferences.cs.meta b/Assets/SteamVR/Editor/SteamVR_Preferences.cs.meta new file mode 100644 index 0000000..3ecb77a --- /dev/null +++ b/Assets/SteamVR/Editor/SteamVR_Preferences.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 29abf75f7265ccb45b799eac4ab0ca94 +timeCreated: 1487968203 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Editor/SteamVR_RenderModelEditor.cs b/Assets/SteamVR/Editor/SteamVR_RenderModelEditor.cs new file mode 100644 index 0000000..75611f6 --- /dev/null +++ b/Assets/SteamVR/Editor/SteamVR_RenderModelEditor.cs @@ -0,0 +1,104 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Custom inspector display for SteamVR_RenderModel +// +//============================================================================= + +using UnityEngine; +using UnityEditor; +using System.Text; +using System.Collections.Generic; + +[CustomEditor(typeof(SteamVR_RenderModel)), CanEditMultipleObjects] +public class SteamVR_RenderModelEditor : Editor +{ + SerializedProperty script, index, modelOverride, shader, verbose, createComponents, updateDynamically; + + static string[] renderModelNames; + int renderModelIndex; + + void OnEnable() + { + script = serializedObject.FindProperty("m_Script"); + index = serializedObject.FindProperty("index"); + modelOverride = serializedObject.FindProperty("modelOverride"); + shader = serializedObject.FindProperty("shader"); + verbose = serializedObject.FindProperty("verbose"); + createComponents = serializedObject.FindProperty("createComponents"); + updateDynamically = serializedObject.FindProperty("updateDynamically"); + + // Load render model names if necessary. + if (renderModelNames == null) + { + renderModelNames = LoadRenderModelNames(); + } + + // Update renderModelIndex based on current modelOverride value. + if (modelOverride.stringValue != "") + { + for (int i = 0; i < renderModelNames.Length; i++) + { + if (modelOverride.stringValue == renderModelNames[i]) + { + renderModelIndex = i; + break; + } + } + } + } + + static string[] LoadRenderModelNames() + { + var results = new List(); + results.Add("None"); + + using (var holder = new SteamVR_RenderModel.RenderModelInterfaceHolder()) + { + var renderModels = holder.instance; + if (renderModels != null) + { + uint count = renderModels.GetRenderModelCount(); + for (uint i = 0; i < count; i++) + { + var buffer = new StringBuilder(); + var requiredSize = renderModels.GetRenderModelName(i, buffer, 0); + if (requiredSize == 0) + continue; + + buffer.EnsureCapacity((int)requiredSize); + renderModels.GetRenderModelName(i, buffer, requiredSize); + results.Add(buffer.ToString()); + } + } + } + + return results.ToArray(); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.PropertyField(script); + EditorGUILayout.PropertyField(index); + //EditorGUILayout.PropertyField(modelOverride); + + GUILayout.BeginHorizontal(); + GUILayout.Label(new GUIContent("Model Override", SteamVR_RenderModel.modelOverrideWarning)); + var selected = EditorGUILayout.Popup(renderModelIndex, renderModelNames); + if (selected != renderModelIndex) + { + renderModelIndex = selected; + modelOverride.stringValue = (selected > 0) ? renderModelNames[selected] : ""; + } + GUILayout.EndHorizontal(); + + EditorGUILayout.PropertyField(shader); + EditorGUILayout.PropertyField(verbose); + EditorGUILayout.PropertyField(createComponents); + EditorGUILayout.PropertyField(updateDynamically); + + serializedObject.ApplyModifiedProperties(); + } +} + diff --git a/Assets/SteamVR/Editor/SteamVR_RenderModelEditor.cs.meta b/Assets/SteamVR/Editor/SteamVR_RenderModelEditor.cs.meta new file mode 100644 index 0000000..222f523 --- /dev/null +++ b/Assets/SteamVR/Editor/SteamVR_RenderModelEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 67867a20919f7db45a2e7034fda1c28e +timeCreated: 1433373945 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Editor/SteamVR_Settings.cs b/Assets/SteamVR/Editor/SteamVR_Settings.cs new file mode 100644 index 0000000..f6e8145 --- /dev/null +++ b/Assets/SteamVR/Editor/SteamVR_Settings.cs @@ -0,0 +1,688 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Prompt developers to use settings most compatible with SteamVR. +// +//============================================================================= + +using UnityEngine; +using UnityEditor; +using System.IO; + +[InitializeOnLoad] +public class SteamVR_Settings : EditorWindow +{ + const bool forceShow = false; // Set to true to get the dialog to show back up in the case you clicked Ignore All. + + const string ignore = "ignore."; + const string useRecommended = "Use recommended ({0})"; + const string currentValue = " (current = {0})"; + + const string buildTarget = "Build Target"; + const string showUnitySplashScreen = "Show Unity Splashscreen"; + const string defaultIsFullScreen = "Default is Fullscreen"; + const string defaultScreenSize = "Default Screen Size"; + const string runInBackground = "Run In Background"; + const string displayResolutionDialog = "Display Resolution Dialog"; + const string resizableWindow = "Resizable Window"; + const string fullscreenMode = "D3D11 Fullscreen Mode"; + const string visibleInBackground = "Visible In Background"; +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + const string renderingPath = "Rendering Path"; +#endif + const string colorSpace = "Color Space"; + const string gpuSkinning = "GPU Skinning"; +#if false // skyboxes are currently broken + const string singlePassStereoRendering = "Single-Pass Stereo Rendering"; +#endif + + const BuildTarget recommended_BuildTarget = BuildTarget.StandaloneWindows64; + const bool recommended_ShowUnitySplashScreen = false; + const bool recommended_DefaultIsFullScreen = false; + const int recommended_DefaultScreenWidth = 1024; + const int recommended_DefaultScreenHeight = 768; + const bool recommended_RunInBackground = true; + const ResolutionDialogSetting recommended_DisplayResolutionDialog = ResolutionDialogSetting.HiddenByDefault; + const bool recommended_ResizableWindow = true; + const D3D11FullscreenMode recommended_FullscreenMode = D3D11FullscreenMode.FullscreenWindow; + const bool recommended_VisibleInBackground = true; +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + const RenderingPath recommended_RenderPath = RenderingPath.Forward; +#endif + const ColorSpace recommended_ColorSpace = ColorSpace.Linear; + const bool recommended_GpuSkinning = true; +#if false + const bool recommended_SinglePassStereoRendering = true; +#endif + + static SteamVR_Settings window; + + static SteamVR_Settings() + { + EditorApplication.update += Update; + } + + static void Update() + { + bool show = + (!EditorPrefs.HasKey(ignore + buildTarget) && + EditorUserBuildSettings.activeBuildTarget != recommended_BuildTarget) || + (!EditorPrefs.HasKey(ignore + showUnitySplashScreen) && +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + PlayerSettings.showUnitySplashScreen != recommended_ShowUnitySplashScreen) || +#else + PlayerSettings.SplashScreen.show != recommended_ShowUnitySplashScreen) || +#endif + (!EditorPrefs.HasKey(ignore + defaultIsFullScreen) && + PlayerSettings.defaultIsFullScreen != recommended_DefaultIsFullScreen) || + (!EditorPrefs.HasKey(ignore + defaultScreenSize) && + (PlayerSettings.defaultScreenWidth != recommended_DefaultScreenWidth || + PlayerSettings.defaultScreenHeight != recommended_DefaultScreenHeight)) || + (!EditorPrefs.HasKey(ignore + runInBackground) && + PlayerSettings.runInBackground != recommended_RunInBackground) || + (!EditorPrefs.HasKey(ignore + displayResolutionDialog) && + PlayerSettings.displayResolutionDialog != recommended_DisplayResolutionDialog) || + (!EditorPrefs.HasKey(ignore + resizableWindow) && + PlayerSettings.resizableWindow != recommended_ResizableWindow) || + (!EditorPrefs.HasKey(ignore + fullscreenMode) && + PlayerSettings.d3d11FullscreenMode != recommended_FullscreenMode) || + (!EditorPrefs.HasKey(ignore + visibleInBackground) && + PlayerSettings.visibleInBackground != recommended_VisibleInBackground) || +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + (!EditorPrefs.HasKey(ignore + renderingPath) && + PlayerSettings.renderingPath != recommended_RenderPath) || +#endif + (!EditorPrefs.HasKey(ignore + colorSpace) && + PlayerSettings.colorSpace != recommended_ColorSpace) || + (!EditorPrefs.HasKey(ignore + gpuSkinning) && + PlayerSettings.gpuSkinning != recommended_GpuSkinning) || +#if false + (!EditorPrefs.HasKey(ignore + singlePassStereoRendering) && + PlayerSettings.singlePassStereoRendering != recommended_SinglePassStereoRendering) || +#endif + forceShow; + + if (show) + { + window = GetWindow(true); + window.minSize = new Vector2(320, 440); + //window.title = "SteamVR"; + } + + if (SteamVR_Preferences.AutoEnableVR) + { + // Switch to native OpenVR support. + var updated = false; + + if (!PlayerSettings.virtualRealitySupported) + { + PlayerSettings.virtualRealitySupported = true; + updated = true; + } + +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + var devices = UnityEditorInternal.VR.VREditor.GetVREnabledDevices(BuildTargetGroup.Standalone); +#else + var devices = UnityEditorInternal.VR.VREditor.GetVREnabledDevicesOnTargetGroup(BuildTargetGroup.Standalone); +#endif + var hasOpenVR = false; + foreach (var device in devices) + if (device.ToLower() == "openvr") + hasOpenVR = true; + + + if (!hasOpenVR) + { + string[] newDevices; + if (updated) + { + newDevices = new string[] { "OpenVR" }; + } + else + { + newDevices = new string[devices.Length + 1]; + for (int i = 0; i < devices.Length; i++) + newDevices[i] = devices[i]; + newDevices[devices.Length] = "OpenVR"; + updated = true; + } +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + UnityEditorInternal.VR.VREditor.SetVREnabledDevices(BuildTargetGroup.Standalone, newDevices); +#else + UnityEditorInternal.VR.VREditor.SetVREnabledDevicesOnTargetGroup(BuildTargetGroup.Standalone, newDevices); +#endif + } + + if (updated) + Debug.Log("Switching to native OpenVR support."); + } + + var dlls = new string[] + { + "Plugins/x86/openvr_api.dll", + "Plugins/x86_64/openvr_api.dll" + }; + + foreach (var path in dlls) + { + if (!File.Exists(Application.dataPath + "/" + path)) + continue; + + if (AssetDatabase.DeleteAsset("Assets/" + path)) + Debug.Log("Deleting " + path); + else + { + Debug.Log(path + " in use; cannot delete. Please restart Unity to complete upgrade."); + } + } + + EditorApplication.update -= Update; + } + + Vector2 scrollPosition; + + string GetResourcePath() + { + var ms = MonoScript.FromScriptableObject(this); + var path = AssetDatabase.GetAssetPath(ms); + path = Path.GetDirectoryName(path); + return path.Substring(0, path.Length - "Editor".Length) + "Textures/"; + } + + public void OnGUI() + { + var resourcePath = GetResourcePath(); + var logo = AssetDatabase.LoadAssetAtPath(resourcePath + "logo.png"); + var rect = GUILayoutUtility.GetRect(position.width, 150, GUI.skin.box); + if (logo) + GUI.DrawTexture(rect, logo, ScaleMode.ScaleToFit); + + EditorGUILayout.HelpBox("Recommended project settings for SteamVR:", MessageType.Warning); + + scrollPosition = GUILayout.BeginScrollView(scrollPosition); + + int numItems = 0; + + if (!EditorPrefs.HasKey(ignore + buildTarget) && + EditorUserBuildSettings.activeBuildTarget != recommended_BuildTarget) + { + ++numItems; + + GUILayout.Label(buildTarget + string.Format(currentValue, EditorUserBuildSettings.activeBuildTarget)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_BuildTarget))) + { +#if (UNITY_5_5 || UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + EditorUserBuildSettings.SwitchActiveBuildTarget(recommended_BuildTarget); +#else + EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, recommended_BuildTarget); +#endif + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + buildTarget, true); + } + + GUILayout.EndHorizontal(); + } + +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + if (!EditorPrefs.HasKey(ignore + showUnitySplashScreen) && + PlayerSettings.showUnitySplashScreen != recommended_ShowUnitySplashScreen) + { + ++numItems; + + GUILayout.Label(showUnitySplashScreen + string.Format(currentValue, PlayerSettings.showUnitySplashScreen)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_ShowUnitySplashScreen))) + { + PlayerSettings.showUnitySplashScreen = recommended_ShowUnitySplashScreen; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + showUnitySplashScreen, true); + } + + GUILayout.EndHorizontal(); + } +#else + if (!EditorPrefs.HasKey(ignore + showUnitySplashScreen) && + PlayerSettings.SplashScreen.show != recommended_ShowUnitySplashScreen) + { + ++numItems; + + GUILayout.Label(showUnitySplashScreen + string.Format(currentValue, PlayerSettings.SplashScreen.show)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_ShowUnitySplashScreen))) + { + PlayerSettings.SplashScreen.show = recommended_ShowUnitySplashScreen; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + showUnitySplashScreen, true); + } + + GUILayout.EndHorizontal(); + } +#endif + if (!EditorPrefs.HasKey(ignore + defaultIsFullScreen) && + PlayerSettings.defaultIsFullScreen != recommended_DefaultIsFullScreen) + { + ++numItems; + + GUILayout.Label(defaultIsFullScreen + string.Format(currentValue, PlayerSettings.defaultIsFullScreen)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_DefaultIsFullScreen))) + { + PlayerSettings.defaultIsFullScreen = recommended_DefaultIsFullScreen; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + defaultIsFullScreen, true); + } + + GUILayout.EndHorizontal(); + } + + if (!EditorPrefs.HasKey(ignore + defaultScreenSize) && + (PlayerSettings.defaultScreenWidth != recommended_DefaultScreenWidth || + PlayerSettings.defaultScreenHeight != recommended_DefaultScreenHeight)) + { + ++numItems; + + GUILayout.Label(defaultScreenSize + string.Format(" ({0}x{1})", PlayerSettings.defaultScreenWidth, PlayerSettings.defaultScreenHeight)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format("Use recommended ({0}x{1})", recommended_DefaultScreenWidth, recommended_DefaultScreenHeight))) + { + PlayerSettings.defaultScreenWidth = recommended_DefaultScreenWidth; + PlayerSettings.defaultScreenHeight = recommended_DefaultScreenHeight; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + defaultScreenSize, true); + } + + GUILayout.EndHorizontal(); + } + + if (!EditorPrefs.HasKey(ignore + runInBackground) && + PlayerSettings.runInBackground != recommended_RunInBackground) + { + ++numItems; + + GUILayout.Label(runInBackground + string.Format(currentValue, PlayerSettings.runInBackground)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_RunInBackground))) + { + PlayerSettings.runInBackground = recommended_RunInBackground; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + runInBackground, true); + } + + GUILayout.EndHorizontal(); + } + + if (!EditorPrefs.HasKey(ignore + displayResolutionDialog) && + PlayerSettings.displayResolutionDialog != recommended_DisplayResolutionDialog) + { + ++numItems; + + GUILayout.Label(displayResolutionDialog + string.Format(currentValue, PlayerSettings.displayResolutionDialog)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_DisplayResolutionDialog))) + { + PlayerSettings.displayResolutionDialog = recommended_DisplayResolutionDialog; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + displayResolutionDialog, true); + } + + GUILayout.EndHorizontal(); + } + + if (!EditorPrefs.HasKey(ignore + resizableWindow) && + PlayerSettings.resizableWindow != recommended_ResizableWindow) + { + ++numItems; + + GUILayout.Label(resizableWindow + string.Format(currentValue, PlayerSettings.resizableWindow)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_ResizableWindow))) + { + PlayerSettings.resizableWindow = recommended_ResizableWindow; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + resizableWindow, true); + } + + GUILayout.EndHorizontal(); + } + + if (!EditorPrefs.HasKey(ignore + fullscreenMode) && + PlayerSettings.d3d11FullscreenMode != recommended_FullscreenMode) + { + ++numItems; + + GUILayout.Label(fullscreenMode + string.Format(currentValue, PlayerSettings.d3d11FullscreenMode)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_FullscreenMode))) + { + PlayerSettings.d3d11FullscreenMode = recommended_FullscreenMode; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + fullscreenMode, true); + } + + GUILayout.EndHorizontal(); + } + + if (!EditorPrefs.HasKey(ignore + visibleInBackground) && + PlayerSettings.visibleInBackground != recommended_VisibleInBackground) + { + ++numItems; + + GUILayout.Label(visibleInBackground + string.Format(currentValue, PlayerSettings.visibleInBackground)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_VisibleInBackground))) + { + PlayerSettings.visibleInBackground = recommended_VisibleInBackground; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + visibleInBackground, true); + } + + GUILayout.EndHorizontal(); + } +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + if (!EditorPrefs.HasKey(ignore + renderingPath) && + PlayerSettings.renderingPath != recommended_RenderPath) + { + ++numItems; + + GUILayout.Label(renderingPath + string.Format(currentValue, PlayerSettings.renderingPath)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_RenderPath) + " - required for MSAA")) + { + PlayerSettings.renderingPath = recommended_RenderPath; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + renderingPath, true); + } + + GUILayout.EndHorizontal(); + } +#endif + if (!EditorPrefs.HasKey(ignore + colorSpace) && + PlayerSettings.colorSpace != recommended_ColorSpace) + { + ++numItems; + + GUILayout.Label(colorSpace + string.Format(currentValue, PlayerSettings.colorSpace)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_ColorSpace) + " - requires reloading scene")) + { + PlayerSettings.colorSpace = recommended_ColorSpace; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + colorSpace, true); + } + + GUILayout.EndHorizontal(); + } + + if (!EditorPrefs.HasKey(ignore + gpuSkinning) && + PlayerSettings.gpuSkinning != recommended_GpuSkinning) + { + ++numItems; + + GUILayout.Label(gpuSkinning + string.Format(currentValue, PlayerSettings.gpuSkinning)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_GpuSkinning))) + { + PlayerSettings.gpuSkinning = recommended_GpuSkinning; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + gpuSkinning, true); + } + + GUILayout.EndHorizontal(); + } + +#if false + if (!EditorPrefs.HasKey(ignore + singlePassStereoRendering) && + PlayerSettings.singlePassStereoRendering != recommended_SinglePassStereoRendering) + { + ++numItems; + + GUILayout.Label(singlePassStereoRendering + string.Format(currentValue, PlayerSettings.singlePassStereoRendering)); + + GUILayout.BeginHorizontal(); + + if (GUILayout.Button(string.Format(useRecommended, recommended_SinglePassStereoRendering))) + { + PlayerSettings.singlePassStereoRendering = recommended_SinglePassStereoRendering; + } + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Ignore")) + { + EditorPrefs.SetBool(ignore + singlePassStereoRendering, true); + } + + GUILayout.EndHorizontal(); + } +#endif + + GUILayout.BeginHorizontal(); + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Clear All Ignores")) + { + EditorPrefs.DeleteKey(ignore + buildTarget); + EditorPrefs.DeleteKey(ignore + showUnitySplashScreen); + EditorPrefs.DeleteKey(ignore + defaultIsFullScreen); + EditorPrefs.DeleteKey(ignore + defaultScreenSize); + EditorPrefs.DeleteKey(ignore + runInBackground); + EditorPrefs.DeleteKey(ignore + displayResolutionDialog); + EditorPrefs.DeleteKey(ignore + resizableWindow); + EditorPrefs.DeleteKey(ignore + fullscreenMode); + EditorPrefs.DeleteKey(ignore + visibleInBackground); +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + EditorPrefs.DeleteKey(ignore + renderingPath); +#endif + EditorPrefs.DeleteKey(ignore + colorSpace); + EditorPrefs.DeleteKey(ignore + gpuSkinning); +#if false + EditorPrefs.DeleteKey(ignore + singlePassStereoRendering); +#endif + } + + GUILayout.EndHorizontal(); + + GUILayout.EndScrollView(); + + GUILayout.FlexibleSpace(); + + GUILayout.BeginHorizontal(); + + if (numItems > 0) + { + if (GUILayout.Button("Accept All")) + { + // Only set those that have not been explicitly ignored. + if (!EditorPrefs.HasKey(ignore + buildTarget)) +#if (UNITY_5_5 || UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + EditorUserBuildSettings.SwitchActiveBuildTarget(recommended_BuildTarget); +#else + EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, recommended_BuildTarget); +#endif + if (!EditorPrefs.HasKey(ignore + showUnitySplashScreen)) +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + PlayerSettings.showUnitySplashScreen = recommended_ShowUnitySplashScreen; +#else + PlayerSettings.SplashScreen.show = recommended_ShowUnitySplashScreen; +#endif + if (!EditorPrefs.HasKey(ignore + defaultIsFullScreen)) + PlayerSettings.defaultIsFullScreen = recommended_DefaultIsFullScreen; + if (!EditorPrefs.HasKey(ignore + defaultScreenSize)) + { + PlayerSettings.defaultScreenWidth = recommended_DefaultScreenWidth; + PlayerSettings.defaultScreenHeight = recommended_DefaultScreenHeight; + } + if (!EditorPrefs.HasKey(ignore + runInBackground)) + PlayerSettings.runInBackground = recommended_RunInBackground; + if (!EditorPrefs.HasKey(ignore + displayResolutionDialog)) + PlayerSettings.displayResolutionDialog = recommended_DisplayResolutionDialog; + if (!EditorPrefs.HasKey(ignore + resizableWindow)) + PlayerSettings.resizableWindow = recommended_ResizableWindow; + if (!EditorPrefs.HasKey(ignore + fullscreenMode)) + PlayerSettings.d3d11FullscreenMode = recommended_FullscreenMode; + if (!EditorPrefs.HasKey(ignore + visibleInBackground)) + PlayerSettings.visibleInBackground = recommended_VisibleInBackground; +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + if (!EditorPrefs.HasKey(ignore + renderingPath)) + PlayerSettings.renderingPath = recommended_RenderPath; +#endif + if (!EditorPrefs.HasKey(ignore + colorSpace)) + PlayerSettings.colorSpace = recommended_ColorSpace; + if (!EditorPrefs.HasKey(ignore + gpuSkinning)) + PlayerSettings.gpuSkinning = recommended_GpuSkinning; +#if false + if (!EditorPrefs.HasKey(ignore + singlePassStereoRendering)) + PlayerSettings.singlePassStereoRendering = recommended_SinglePassStereoRendering; +#endif + + EditorUtility.DisplayDialog("Accept All", "You made the right choice!", "Ok"); + + Close(); + } + + if (GUILayout.Button("Ignore All")) + { + if (EditorUtility.DisplayDialog("Ignore All", "Are you sure?", "Yes, Ignore All", "Cancel")) + { + // Only ignore those that do not currently match our recommended settings. + if (EditorUserBuildSettings.activeBuildTarget != recommended_BuildTarget) + EditorPrefs.SetBool(ignore + buildTarget, true); +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + if (PlayerSettings.showUnitySplashScreen != recommended_ShowUnitySplashScreen) +#else + if (PlayerSettings.SplashScreen.show != recommended_ShowUnitySplashScreen) +#endif + EditorPrefs.SetBool(ignore + showUnitySplashScreen, true); + if (PlayerSettings.defaultIsFullScreen != recommended_DefaultIsFullScreen) + EditorPrefs.SetBool(ignore + defaultIsFullScreen, true); + if (PlayerSettings.defaultScreenWidth != recommended_DefaultScreenWidth || + PlayerSettings.defaultScreenHeight != recommended_DefaultScreenHeight) + EditorPrefs.SetBool(ignore + defaultScreenSize, true); + if (PlayerSettings.runInBackground != recommended_RunInBackground) + EditorPrefs.SetBool(ignore + runInBackground, true); + if (PlayerSettings.displayResolutionDialog != recommended_DisplayResolutionDialog) + EditorPrefs.SetBool(ignore + displayResolutionDialog, true); + if (PlayerSettings.resizableWindow != recommended_ResizableWindow) + EditorPrefs.SetBool(ignore + resizableWindow, true); + if (PlayerSettings.d3d11FullscreenMode != recommended_FullscreenMode) + EditorPrefs.SetBool(ignore + fullscreenMode, true); + if (PlayerSettings.visibleInBackground != recommended_VisibleInBackground) + EditorPrefs.SetBool(ignore + visibleInBackground, true); +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + if (PlayerSettings.renderingPath != recommended_RenderPath) + EditorPrefs.SetBool(ignore + renderingPath, true); +#endif + if (PlayerSettings.colorSpace != recommended_ColorSpace) + EditorPrefs.SetBool(ignore + colorSpace, true); + if (PlayerSettings.gpuSkinning != recommended_GpuSkinning) + EditorPrefs.SetBool(ignore + gpuSkinning, true); +#if false + if (PlayerSettings.singlePassStereoRendering != recommended_SinglePassStereoRendering) + EditorPrefs.SetBool(ignore + singlePassStereoRendering, true); +#endif + + Close(); + } + } + } + else if (GUILayout.Button("Close")) + { + Close(); + } + + GUILayout.EndHorizontal(); + } +} + diff --git a/Assets/SteamVR/Editor/SteamVR_Settings.cs.meta b/Assets/SteamVR/Editor/SteamVR_Settings.cs.meta new file mode 100644 index 0000000..8887628 --- /dev/null +++ b/Assets/SteamVR/Editor/SteamVR_Settings.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d2244eee8a3a4784fb40d1123ff69301 +timeCreated: 1438809573 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Editor/SteamVR_SkyboxEditor.cs b/Assets/SteamVR/Editor/SteamVR_SkyboxEditor.cs new file mode 100644 index 0000000..9fea2f7 --- /dev/null +++ b/Assets/SteamVR/Editor/SteamVR_SkyboxEditor.cs @@ -0,0 +1,381 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Custom inspector display for SteamVR_Skybox +// +//============================================================================= + +using UnityEngine; +using UnityEditor; +using System.Text; +using System.Collections.Generic; +using Valve.VR; +using System.IO; + +[CustomEditor(typeof(SteamVR_Skybox)), CanEditMultipleObjects] +public class SteamVR_SkyboxEditor : Editor +{ + private const string nameFormat = "{0}/{1}-{2}.png"; + private const string helpText = "Take snapshot will use the current " + + "position and rotation to capture six directional screenshots to use as this " + + "skybox's textures. Note: This skybox is only used to override what shows up " + + "in the compositor (e.g. when loading levels). Add a Camera component to this " + + "object to override default settings like which layers to render. Additionally, " + + "by specifying your own targetTexture, you can control the size of the textures " + + "and other properties like antialiasing. Don't forget to disable the camera.\n\n" + + "For stereo screenshots, a panorama is render for each eye using the specified " + + "ipd (in millimeters) broken up into segments cellSize pixels square to optimize " + + "generation.\n(32x32 takes about 10 seconds depending on scene complexity, 16x16 " + + "takes around a minute, while will 8x8 take several minutes.)\n\nTo test, hit " + + "play then pause - this will activate the skybox settings, and then drop you to " + + "the compositor where the skybox is rendered."; + + public override void OnInspectorGUI() + { + DrawDefaultInspector(); + + EditorGUILayout.HelpBox(helpText, MessageType.Info); + + if (GUILayout.Button("Take snapshot")) + { + var directions = new Quaternion[] { + Quaternion.LookRotation(Vector3.forward), + Quaternion.LookRotation(Vector3.back), + Quaternion.LookRotation(Vector3.left), + Quaternion.LookRotation(Vector3.right), + Quaternion.LookRotation(Vector3.up, Vector3.back), + Quaternion.LookRotation(Vector3.down, Vector3.forward) + }; + + Camera tempCamera = null; + foreach (SteamVR_Skybox target in targets) + { + var targetScene = target.gameObject.scene; + var sceneName = Path.GetFileNameWithoutExtension(targetScene.path); + var scenePath = Path.GetDirectoryName(targetScene.path); + var assetPath = scenePath + "/" + sceneName; + if (!AssetDatabase.IsValidFolder(assetPath)) + { + var guid = AssetDatabase.CreateFolder(scenePath, sceneName); + assetPath = AssetDatabase.GUIDToAssetPath(guid); + } + + var camera = target.GetComponent(); + if (camera == null) + { + if (tempCamera == null) + tempCamera = new GameObject().AddComponent(); + camera = tempCamera; + } + + var targetTexture = camera.targetTexture; + if (camera.targetTexture == null) + { + targetTexture = new RenderTexture(1024, 1024, 24); + targetTexture.antiAliasing = 8; + camera.targetTexture = targetTexture; + } + + var oldPosition = target.transform.localPosition; + var oldRotation = target.transform.localRotation; + var baseRotation = target.transform.rotation; + + var t = camera.transform; + t.position = target.transform.position; + camera.orthographic = false; + camera.fieldOfView = 90; + + for (int i = 0; i < directions.Length; i++) + { + t.rotation = baseRotation * directions[i]; + camera.Render(); + + // Copy to texture and save to disk. + RenderTexture.active = targetTexture; + var texture = new Texture2D(targetTexture.width, targetTexture.height, TextureFormat.ARGB32, false); + texture.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0); + texture.Apply(); + RenderTexture.active = null; + + var assetName = string.Format(nameFormat, assetPath, target.name, i); + System.IO.File.WriteAllBytes(assetName, texture.EncodeToPNG()); + } + + if (camera != tempCamera) + { + target.transform.localPosition = oldPosition; + target.transform.localRotation = oldRotation; + } + } + + if (tempCamera != null) + { + Object.DestroyImmediate(tempCamera.gameObject); + } + + // Now that everything has be written out, reload the associated assets and assign them. + AssetDatabase.Refresh(); + foreach (SteamVR_Skybox target in targets) + { + var targetScene = target.gameObject.scene; + var sceneName = Path.GetFileNameWithoutExtension(targetScene.path); + var scenePath = Path.GetDirectoryName(targetScene.path); + var assetPath = scenePath + "/" + sceneName; + + for (int i = 0; i < directions.Length; i++) + { + var assetName = string.Format(nameFormat, assetPath, target.name, i); + var importer = AssetImporter.GetAtPath(assetName) as TextureImporter; +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + importer.textureFormat = TextureImporterFormat.RGB24; +#else + importer.textureCompression = TextureImporterCompression.Uncompressed; +#endif + importer.wrapMode = TextureWrapMode.Clamp; + importer.mipmapEnabled = false; + importer.SaveAndReimport(); + + var texture = AssetDatabase.LoadAssetAtPath(assetName); + target.SetTextureByIndex(i, texture); + } + } + } + else if (GUILayout.Button("Take stereo snapshot")) + { + const int width = 4096; + const int height = width / 2; + const int halfHeight = height / 2; + + var textures = new Texture2D[] { + new Texture2D(width, height, TextureFormat.ARGB32, false), + new Texture2D(width, height, TextureFormat.ARGB32, false) }; + + var timer = new System.Diagnostics.Stopwatch(); + + Camera tempCamera = null; + foreach (SteamVR_Skybox target in targets) + { + timer.Start(); + + var targetScene = target.gameObject.scene; + var sceneName = Path.GetFileNameWithoutExtension(targetScene.path); + var scenePath = Path.GetDirectoryName(targetScene.path); + var assetPath = scenePath + "/" + sceneName; + if (!AssetDatabase.IsValidFolder(assetPath)) + { + var guid = AssetDatabase.CreateFolder(scenePath, sceneName); + assetPath = AssetDatabase.GUIDToAssetPath(guid); + } + + var camera = target.GetComponent(); + if (camera == null) + { + if (tempCamera == null) + tempCamera = new GameObject().AddComponent(); + camera = tempCamera; + } + + var fx = camera.gameObject.AddComponent(); + + var oldTargetTexture = camera.targetTexture; + var oldOrthographic = camera.orthographic; + var oldFieldOfView = camera.fieldOfView; + var oldAspect = camera.aspect; + + var oldPosition = target.transform.localPosition; + var oldRotation = target.transform.localRotation; + var basePosition = target.transform.position; + var baseRotation = target.transform.rotation; + + var transform = camera.transform; + + int cellSize = int.Parse(target.StereoCellSize.ToString().Substring(1)); + float ipd = target.StereoIpdMm / 1000.0f; + int vTotal = halfHeight / cellSize; + float dv = 90.0f / vTotal; // vertical degrees per segment + float dvHalf = dv / 2.0f; + + var targetTexture = new RenderTexture(cellSize, cellSize, 24); + targetTexture.wrapMode = TextureWrapMode.Clamp; + targetTexture.antiAliasing = 8; + + camera.fieldOfView = dv; + camera.orthographic = false; + camera.targetTexture = targetTexture; + + // Render sections of a sphere using a rectilinear projection + // and resample using a sphereical projection into a single panorama + // texture per eye. We break into sections in order to keep the eye + // separation similar around the sphere. Rendering alternates between + // top and bottom sections, sweeping horizontally around the sphere, + // alternating left and right eyes. + for (int v = 0; v < vTotal; v++) + { + var pitch = 90.0f - (v * dv) - dvHalf; + var uTotal = width / targetTexture.width; + var du = 360.0f / uTotal; // horizontal degrees per segment + var duHalf = du / 2.0f; + + var vTarget = v * halfHeight / vTotal; + + for (int i = 0; i < 2; i++) // top, bottom + { + if (i == 1) + { + pitch = -pitch; + vTarget = height - vTarget - cellSize; + } + + for (int u = 0; u < uTotal; u++) + { + var yaw = -180.0f + (u * du) + duHalf; + + var uTarget = u * width / uTotal; + + var xOffset = -ipd / 2 * Mathf.Cos(pitch * Mathf.Deg2Rad); + + for (int j = 0; j < 2; j++) // left, right + { + var texture = textures[j]; + + if (j == 1) + { + xOffset = -xOffset; + } + + var offset = baseRotation * Quaternion.Euler(0, yaw, 0) * new Vector3(xOffset, 0, 0); + transform.position = basePosition + offset; + + var direction = Quaternion.Euler(pitch, yaw, 0.0f); + transform.rotation = baseRotation * direction; + + // vector pointing to center of this section + var N = direction * Vector3.forward; + + // horizontal span of this section in degrees + var phi0 = yaw - (du / 2); + var phi1 = phi0 + du; + + // vertical span of this section in degrees + var theta0 = pitch + (dv / 2); + var theta1 = theta0 - dv; + + var midPhi = (phi0 + phi1) / 2; + var baseTheta = Mathf.Abs(theta0) < Mathf.Abs(theta1) ? theta0 : theta1; + + // vectors pointing to corners of image closes to the equator + var V00 = Quaternion.Euler(baseTheta, phi0, 0.0f) * Vector3.forward; + var V01 = Quaternion.Euler(baseTheta, phi1, 0.0f) * Vector3.forward; + + // vectors pointing to top and bottom midsection of image + var V0M = Quaternion.Euler(theta0, midPhi, 0.0f) * Vector3.forward; + var V1M = Quaternion.Euler(theta1, midPhi, 0.0f) * Vector3.forward; + + // intersection points for each of the above + var P00 = V00 / Vector3.Dot(V00, N); + var P01 = V01 / Vector3.Dot(V01, N); + var P0M = V0M / Vector3.Dot(V0M, N); + var P1M = V1M / Vector3.Dot(V1M, N); + + // calculate basis vectors for plane + var P00_P01 = P01 - P00; + var P0M_P1M = P1M - P0M; + + var uMag = P00_P01.magnitude; + var vMag = P0M_P1M.magnitude; + + var uScale = 1.0f / uMag; + var vScale = 1.0f / vMag; + + var uAxis = P00_P01 * uScale; + var vAxis = P0M_P1M * vScale; + + // update material constant buffer + fx.Set(N, phi0, phi1, theta0, theta1, + uAxis, P00, uScale, + vAxis, P0M, vScale); + + camera.aspect = uMag / vMag; + camera.Render(); + + RenderTexture.active = targetTexture; + texture.ReadPixels(new Rect(0, 0, targetTexture.width, targetTexture.height), uTarget, vTarget); + RenderTexture.active = null; + } + } + } + } + + // Save textures to disk. + for (int i = 0; i < 2; i++) + { + var texture = textures[i]; + + texture.Apply(); + var assetName = string.Format(nameFormat, assetPath, target.name, i); + File.WriteAllBytes(assetName, texture.EncodeToPNG()); + } + + // Cleanup. + if (camera != tempCamera) + { + camera.targetTexture = oldTargetTexture; + camera.orthographic = oldOrthographic; + camera.fieldOfView = oldFieldOfView; + camera.aspect = oldAspect; + + target.transform.localPosition = oldPosition; + target.transform.localRotation = oldRotation; + } + else + { + tempCamera.targetTexture = null; + } + + DestroyImmediate(targetTexture); + DestroyImmediate(fx); + + timer.Stop(); + Debug.Log(string.Format("Screenshot took {0} seconds.", timer.Elapsed)); + } + + if (tempCamera != null) + { + DestroyImmediate(tempCamera.gameObject); + } + + DestroyImmediate(textures[0]); + DestroyImmediate(textures[1]); + + // Now that everything has be written out, reload the associated assets and assign them. + AssetDatabase.Refresh(); + foreach (SteamVR_Skybox target in targets) + { + var targetScene = target.gameObject.scene; + var sceneName = Path.GetFileNameWithoutExtension(targetScene.path); + var scenePath = Path.GetDirectoryName(targetScene.path); + var assetPath = scenePath + "/" + sceneName; + + for (int i = 0; i < 2; i++) + { + var assetName = string.Format(nameFormat, assetPath, target.name, i); + var importer = AssetImporter.GetAtPath(assetName) as TextureImporter; + importer.mipmapEnabled = false; + importer.wrapMode = TextureWrapMode.Repeat; +#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) + importer.SetPlatformTextureSettings("Standalone", width, TextureImporterFormat.RGB24); +#else + var settings = importer.GetPlatformTextureSettings("Standalone"); + settings.textureCompression = TextureImporterCompression.Uncompressed; + settings.maxTextureSize = width; + importer.SetPlatformTextureSettings(settings); +#endif + importer.SaveAndReimport(); + + var texture = AssetDatabase.LoadAssetAtPath(assetName); + target.SetTextureByIndex(i, texture); + } + } + } + } +} + diff --git a/Assets/SteamVR/Editor/SteamVR_SkyboxEditor.cs.meta b/Assets/SteamVR/Editor/SteamVR_SkyboxEditor.cs.meta new file mode 100644 index 0000000..95230d0 --- /dev/null +++ b/Assets/SteamVR/Editor/SteamVR_SkyboxEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 80087fbbf7bf93a46bb4aea276b19568 +timeCreated: 1446765449 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Editor/SteamVR_Update.cs b/Assets/SteamVR/Editor/SteamVR_Update.cs new file mode 100644 index 0000000..51e65cf --- /dev/null +++ b/Assets/SteamVR/Editor/SteamVR_Update.cs @@ -0,0 +1,170 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Notify developers when a new version of the plugin is available. +// +//============================================================================= + +using UnityEngine; +using UnityEditor; +using System.IO; +using System.Text.RegularExpressions; + +[InitializeOnLoad] +public class SteamVR_Update : EditorWindow +{ + const string currentVersion = "1.2.3"; + const string versionUrl = "http://media.steampowered.com/apps/steamvr/unitypluginversion.txt"; + const string notesUrl = "http://media.steampowered.com/apps/steamvr/unityplugin-v{0}.txt"; + const string pluginUrl = "http://u3d.as/content/valve-corporation/steam-vr-plugin"; + const string doNotShowKey = "SteamVR.DoNotShow.v{0}"; + + static bool gotVersion = false; + static WWW wwwVersion, wwwNotes; + static string version, notes; + static SteamVR_Update window; + + static SteamVR_Update() + { + EditorApplication.update += Update; + } + + static void Update() + { + if (!gotVersion) + { + if (wwwVersion == null) + wwwVersion = new WWW(versionUrl); + + if (!wwwVersion.isDone) + return; + + if (UrlSuccess(wwwVersion)) + version = wwwVersion.text; + + wwwVersion = null; + gotVersion = true; + + if (ShouldDisplay()) + { + var url = string.Format(notesUrl, version); + wwwNotes = new WWW(url); + + window = GetWindow(true); + window.minSize = new Vector2(320, 440); + //window.title = "SteamVR"; + } + } + + if (wwwNotes != null) + { + if (!wwwNotes.isDone) + return; + + if (UrlSuccess(wwwNotes)) + notes = wwwNotes.text; + + wwwNotes = null; + + if (notes != "") + window.Repaint(); + } + + EditorApplication.update -= Update; + } + + static bool UrlSuccess(WWW www) + { + if (!string.IsNullOrEmpty(www.error)) + return false; + if (Regex.IsMatch(www.text, "404 not found", RegexOptions.IgnoreCase)) + return false; + return true; + } + + static bool ShouldDisplay() + { + if (string.IsNullOrEmpty(version)) + return false; + if (version == currentVersion) + return false; + if (EditorPrefs.HasKey(string.Format(doNotShowKey, version))) + return false; + + // parse to see if newer (e.g. 1.0.4 vs 1.0.3) + var versionSplit = version.Split('.'); + var currentVersionSplit = currentVersion.Split('.'); + for (int i = 0; i < versionSplit.Length && i < currentVersionSplit.Length; i++) + { + int versionValue, currentVersionValue; + if (int.TryParse(versionSplit[i], out versionValue) && + int.TryParse(currentVersionSplit[i], out currentVersionValue)) + { + if (versionValue > currentVersionValue) + return true; + if (versionValue < currentVersionValue) + return false; + } + } + + // same up to this point, now differentiate based on number of sub values (e.g. 1.0.4.1 vs 1.0.4) + if (versionSplit.Length <= currentVersionSplit.Length) + return false; + + return true; + } + + Vector2 scrollPosition; + bool toggleState; + + string GetResourcePath() + { + var ms = MonoScript.FromScriptableObject(this); + var path = AssetDatabase.GetAssetPath(ms); + path = Path.GetDirectoryName(path); + return path.Substring(0, path.Length - "Editor".Length) + "Textures/"; + } + + public void OnGUI() + { + EditorGUILayout.HelpBox("A new version of the SteamVR plugin is available!", MessageType.Warning); + + var resourcePath = GetResourcePath(); + var logo = AssetDatabase.LoadAssetAtPath(resourcePath + "logo.png"); + var rect = GUILayoutUtility.GetRect(position.width, 150, GUI.skin.box); + if (logo) + GUI.DrawTexture(rect, logo, ScaleMode.ScaleToFit); + + scrollPosition = GUILayout.BeginScrollView(scrollPosition); + + GUILayout.Label("Current version: " + currentVersion); + GUILayout.Label("New version: " + version); + + if (notes != "") + { + GUILayout.Label("Release notes:"); + EditorGUILayout.HelpBox(notes, MessageType.Info); + } + + GUILayout.EndScrollView(); + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Get Latest Version")) + { + Application.OpenURL(pluginUrl); + } + + EditorGUI.BeginChangeCheck(); + var doNotShow = GUILayout.Toggle(toggleState, "Do not prompt for this version again."); + if (EditorGUI.EndChangeCheck()) + { + toggleState = doNotShow; + var key = string.Format(doNotShowKey, version); + if (doNotShow) + EditorPrefs.SetBool(key, true); + else + EditorPrefs.DeleteKey(key); + } + } +} + diff --git a/Assets/SteamVR/Editor/SteamVR_Update.cs.meta b/Assets/SteamVR/Editor/SteamVR_Update.cs.meta new file mode 100644 index 0000000..de16a50 --- /dev/null +++ b/Assets/SteamVR/Editor/SteamVR_Update.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 73a0556bda803bf4e898751dcfcf21a8 +timeCreated: 1433880062 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Extras.meta b/Assets/SteamVR/Extras.meta new file mode 100644 index 0000000..5785668 --- /dev/null +++ b/Assets/SteamVR/Extras.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 61f4796ee4f00314e8d8b1ad39a78c28 +folderAsset: yes +timeCreated: 1438797390 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Extras/SteamVR_GazeTracker.cs b/Assets/SteamVR/Extras/SteamVR_GazeTracker.cs new file mode 100644 index 0000000..c35b783 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_GazeTracker.cs @@ -0,0 +1,88 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +using UnityEngine; +using System.Collections; + +public struct GazeEventArgs +{ + public float distance; +} + +public delegate void GazeEventHandler(object sender, GazeEventArgs e); + +public class SteamVR_GazeTracker : MonoBehaviour +{ + public bool isInGaze = false; + public event GazeEventHandler GazeOn; + public event GazeEventHandler GazeOff; + public float gazeInCutoff = 0.15f; + public float gazeOutCutoff = 0.4f; + + // Contains a HMD tracked object that we can use to find the user's gaze + Transform hmdTrackedObject = null; + + // Use this for initialization + void Start () + { + + } + + public virtual void OnGazeOn(GazeEventArgs e) + { + if (GazeOn != null) + GazeOn(this, e); + } + + public virtual void OnGazeOff(GazeEventArgs e) + { + if (GazeOff != null) + GazeOff(this, e); + } + + // Update is called once per frame + void Update () + { + // If we haven't set up hmdTrackedObject find what the user is looking at + if (hmdTrackedObject == null) + { + SteamVR_TrackedObject[] trackedObjects = FindObjectsOfType(); + foreach (SteamVR_TrackedObject tracked in trackedObjects) + { + if (tracked.index == SteamVR_TrackedObject.EIndex.Hmd) + { + hmdTrackedObject = tracked.transform; + break; + } + } + } + + if (hmdTrackedObject) + { + Ray r = new Ray(hmdTrackedObject.position, hmdTrackedObject.forward); + Plane p = new Plane(hmdTrackedObject.forward, transform.position); + + float enter = 0.0f; + if (p.Raycast(r, out enter)) + { + Vector3 intersect = hmdTrackedObject.position + hmdTrackedObject.forward * enter; + float dist = Vector3.Distance(intersect, transform.position); + //Debug.Log("Gaze dist = " + dist); + if (dist < gazeInCutoff && !isInGaze) + { + isInGaze = true; + GazeEventArgs e; + e.distance = dist; + OnGazeOn(e); + } + else if (dist >= gazeOutCutoff && isInGaze) + { + isInGaze = false; + GazeEventArgs e; + e.distance = dist; + OnGazeOff(e); + } + } + + } + + } +} diff --git a/Assets/SteamVR/Extras/SteamVR_GazeTracker.cs.meta b/Assets/SteamVR/Extras/SteamVR_GazeTracker.cs.meta new file mode 100644 index 0000000..9f67d12 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_GazeTracker.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 501eb8b744f73714fbe7dbdd5e3ef66e +timeCreated: 1426193800 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Extras/SteamVR_LaserPointer.cs b/Assets/SteamVR/Extras/SteamVR_LaserPointer.cs new file mode 100644 index 0000000..d35c731 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_LaserPointer.cs @@ -0,0 +1,141 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +using UnityEngine; +using System.Collections; + +public struct PointerEventArgs +{ + public uint controllerIndex; + public uint flags; + public float distance; + public Transform target; +} + +public delegate void PointerEventHandler(object sender, PointerEventArgs e); + + +public class SteamVR_LaserPointer : MonoBehaviour +{ + public bool active = true; + public Color color; + public float thickness = 0.002f; + public GameObject holder; + public GameObject pointer; + bool isActive = false; + public bool addRigidBody = false; + public Transform reference; + public event PointerEventHandler PointerIn; + public event PointerEventHandler PointerOut; + + Transform previousContact = null; + + // Use this for initialization + void Start () + { + holder = new GameObject(); + holder.transform.parent = this.transform; + holder.transform.localPosition = Vector3.zero; + holder.transform.localRotation = Quaternion.identity; + + pointer = GameObject.CreatePrimitive(PrimitiveType.Cube); + pointer.transform.parent = holder.transform; + pointer.transform.localScale = new Vector3(thickness, thickness, 100f); + pointer.transform.localPosition = new Vector3(0f, 0f, 50f); + pointer.transform.localRotation = Quaternion.identity; + BoxCollider collider = pointer.GetComponent(); + if (addRigidBody) + { + if (collider) + { + collider.isTrigger = true; + } + Rigidbody rigidBody = pointer.AddComponent(); + rigidBody.isKinematic = true; + } + else + { + if(collider) + { + Object.Destroy(collider); + } + } + Material newMaterial = new Material(Shader.Find("Unlit/Color")); + newMaterial.SetColor("_Color", color); + pointer.GetComponent().material = newMaterial; + } + + public virtual void OnPointerIn(PointerEventArgs e) + { + if (PointerIn != null) + PointerIn(this, e); + } + + public virtual void OnPointerOut(PointerEventArgs e) + { + if (PointerOut != null) + PointerOut(this, e); + } + + + // Update is called once per frame + void Update () + { + if (!isActive) + { + isActive = true; + this.transform.GetChild(0).gameObject.SetActive(true); + } + + float dist = 100f; + + SteamVR_TrackedController controller = GetComponent(); + + Ray raycast = new Ray(transform.position, transform.forward); + RaycastHit hit; + bool bHit = Physics.Raycast(raycast, out hit); + + if(previousContact && previousContact != hit.transform) + { + PointerEventArgs args = new PointerEventArgs(); + if (controller != null) + { + args.controllerIndex = controller.controllerIndex; + } + args.distance = 0f; + args.flags = 0; + args.target = previousContact; + OnPointerOut(args); + previousContact = null; + } + if(bHit && previousContact != hit.transform) + { + PointerEventArgs argsIn = new PointerEventArgs(); + if (controller != null) + { + argsIn.controllerIndex = controller.controllerIndex; + } + argsIn.distance = hit.distance; + argsIn.flags = 0; + argsIn.target = hit.transform; + OnPointerIn(argsIn); + previousContact = hit.transform; + } + if(!bHit) + { + previousContact = null; + } + if (bHit && hit.distance < 100f) + { + dist = hit.distance; + } + + if (controller != null && controller.triggerPressed) + { + pointer.transform.localScale = new Vector3(thickness * 5f, thickness * 5f, dist); + } + else + { + pointer.transform.localScale = new Vector3(thickness, thickness, dist); + } + pointer.transform.localPosition = new Vector3(0f, 0f, dist/2f); + } +} diff --git a/Assets/SteamVR/Extras/SteamVR_LaserPointer.cs.meta b/Assets/SteamVR/Extras/SteamVR_LaserPointer.cs.meta new file mode 100644 index 0000000..874f4ae --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_LaserPointer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d4e8a839a7c5b7e4580c59e305fb5f01 +timeCreated: 1430337756 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Extras/SteamVR_Teleporter.cs b/Assets/SteamVR/Extras/SteamVR_Teleporter.cs new file mode 100644 index 0000000..e04df84 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_Teleporter.cs @@ -0,0 +1,98 @@ +using UnityEngine; +using System.Collections; + +public class SteamVR_Teleporter : MonoBehaviour +{ + public enum TeleportType + { + TeleportTypeUseTerrain, + TeleportTypeUseCollider, + TeleportTypeUseZeroY + } + + public bool teleportOnClick = false; + public TeleportType teleportType = TeleportType.TeleportTypeUseZeroY; + + Transform reference + { + get + { + var top = SteamVR_Render.Top(); + return (top != null) ? top.origin : null; + } + } + + void Start() + { + var trackedController = GetComponent(); + if (trackedController == null) + { + trackedController = gameObject.AddComponent(); + } + + trackedController.TriggerClicked += new ClickedEventHandler(DoClick); + + if (teleportType == TeleportType.TeleportTypeUseTerrain) + { + // Start the player at the level of the terrain + var t = reference; + if (t != null) + t.position = new Vector3(t.position.x, Terrain.activeTerrain.SampleHeight(t.position), t.position.z); + } + } + + void DoClick(object sender, ClickedEventArgs e) + { + if (teleportOnClick) + { + // First get the current Transform of the the reference space (i.e. the Play Area, e.g. CameraRig prefab) + var t = reference; + if (t == null) + return; + + // Get the current Y position of the reference space + float refY = t.position.y; + + // Create a plane at the Y position of the Play Area + // Then create a Ray from the origin of the controller in the direction that the controller is pointing + Plane plane = new Plane(Vector3.up, -refY); + Ray ray = new Ray(this.transform.position, transform.forward); + + // Set defaults + bool hasGroundTarget = false; + float dist = 0f; + if (teleportType == TeleportType.TeleportTypeUseTerrain) // If we picked to use the terrain + { + RaycastHit hitInfo; + TerrainCollider tc = Terrain.activeTerrain.GetComponent(); + hasGroundTarget = tc.Raycast(ray, out hitInfo, 1000f); + dist = hitInfo.distance; + } + else if (teleportType == TeleportType.TeleportTypeUseCollider) // If we picked to use the collider + { + RaycastHit hitInfo; + hasGroundTarget = Physics.Raycast(ray, out hitInfo); + dist = hitInfo.distance; + } + else // If we're just staying flat on the current Y axis + { + // Intersect a ray with the plane that was created earlier + // and output the distance along the ray that it intersects + hasGroundTarget = plane.Raycast(ray, out dist); + } + + if (hasGroundTarget) + { + // Get the current Camera (head) position on the ground relative to the world + Vector3 headPosOnGround = new Vector3(SteamVR_Render.Top().head.position.x, refY, SteamVR_Render.Top().head.position.z); + + // We need to translate the reference space along the same vector + // that is between the head's position on the ground and the intersection point on the ground + // i.e. intersectionPoint - headPosOnGround = translateVector + // currentReferencePosition + translateVector = finalPosition + t.position = t.position + (ray.origin + (ray.direction * dist)) - headPosOnGround; + } + } + } +} + diff --git a/Assets/SteamVR/Extras/SteamVR_Teleporter.cs.meta b/Assets/SteamVR/Extras/SteamVR_Teleporter.cs.meta new file mode 100644 index 0000000..8aad8d9 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_Teleporter.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 24c7d7d77dd0d2a4b8e1ad129b170ee3 +timeCreated: 1430337756 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Extras/SteamVR_TestIK.unity b/Assets/SteamVR/Extras/SteamVR_TestIK.unity new file mode 100644 index 0000000..b67988f --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TestIK.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c36101ca099543026ddda58ceca38150ce27b01b0828360eecc69653796f365 +size 52553 diff --git a/Assets/SteamVR/Extras/SteamVR_TestIK.unity.meta b/Assets/SteamVR/Extras/SteamVR_TestIK.unity.meta new file mode 100644 index 0000000..a31ced7 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TestIK.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4b6669fb4e4df9c48926f02b694be9d1 +timeCreated: 1437433018 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Extras/SteamVR_TestThrow.cs b/Assets/SteamVR/Extras/SteamVR_TestThrow.cs new file mode 100644 index 0000000..0dd7a94 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TestThrow.cs @@ -0,0 +1,58 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +using UnityEngine; +using System.Collections; + +[RequireComponent(typeof(SteamVR_TrackedObject))] +public class SteamVR_TestThrow : MonoBehaviour +{ + public GameObject prefab; + public Rigidbody attachPoint; + + SteamVR_TrackedObject trackedObj; + FixedJoint joint; + + void Awake() + { + trackedObj = GetComponent(); + } + + void FixedUpdate() + { + var device = SteamVR_Controller.Input((int)trackedObj.index); + if (joint == null && device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger)) + { + var go = GameObject.Instantiate(prefab); + go.transform.position = attachPoint.transform.position; + + joint = go.AddComponent(); + joint.connectedBody = attachPoint; + } + else if (joint != null && device.GetTouchUp(SteamVR_Controller.ButtonMask.Trigger)) + { + var go = joint.gameObject; + var rigidbody = go.GetComponent(); + Object.DestroyImmediate(joint); + joint = null; + Object.Destroy(go, 15.0f); + + // We should probably apply the offset between trackedObj.transform.position + // and device.transform.pos to insert into the physics sim at the correct + // location, however, we would then want to predict ahead the visual representation + // by the same amount we are predicting our render poses. + + var origin = trackedObj.origin ? trackedObj.origin : trackedObj.transform.parent; + if (origin != null) + { + rigidbody.velocity = origin.TransformVector(device.velocity); + rigidbody.angularVelocity = origin.TransformVector(device.angularVelocity); + } + else + { + rigidbody.velocity = device.velocity; + rigidbody.angularVelocity = device.angularVelocity; + } + + rigidbody.maxAngularVelocity = rigidbody.angularVelocity.magnitude; + } + } +} diff --git a/Assets/SteamVR/Extras/SteamVR_TestThrow.cs.meta b/Assets/SteamVR/Extras/SteamVR_TestThrow.cs.meta new file mode 100644 index 0000000..86dcfb0 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TestThrow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ff4f36585e15b1942827390ff1a92502 +timeCreated: 1437513988 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Extras/SteamVR_TestThrow.unity b/Assets/SteamVR/Extras/SteamVR_TestThrow.unity new file mode 100644 index 0000000..44bd19f --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TestThrow.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5240c8d162fd86882cc699eb1b45813cae30260c1c08b7fb48343ebae5232b7d +size 73867 diff --git a/Assets/SteamVR/Extras/SteamVR_TestThrow.unity.meta b/Assets/SteamVR/Extras/SteamVR_TestThrow.unity.meta new file mode 100644 index 0000000..3cb5fc8 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TestThrow.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0d936163b5e9a5047b5e4ba5afaf5126 +timeCreated: 1437513966 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.cs b/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.cs new file mode 100644 index 0000000..0d24ae5 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.cs @@ -0,0 +1,84 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +using UnityEngine; + +public class SteamVR_TestTrackedCamera : MonoBehaviour +{ + public Material material; + public Transform target; + public bool undistorted = true; + public bool cropped = true; + + void OnEnable() + { + // The video stream must be symmetrically acquired and released in + // order to properly disable the stream once there are no consumers. + var source = SteamVR_TrackedCamera.Source(undistorted); + source.Acquire(); + + // Auto-disable if no camera is present. + if (!source.hasCamera) + enabled = false; + } + + void OnDisable() + { + // Clear the texture when no longer active. + material.mainTexture = null; + + // The video stream must be symmetrically acquired and released in + // order to properly disable the stream once there are no consumers. + var source = SteamVR_TrackedCamera.Source(undistorted); + source.Release(); + } + + void Update() + { + var source = SteamVR_TrackedCamera.Source(undistorted); + var texture = source.texture; + if (texture == null) + { + return; + } + + // Apply the latest texture to the material. This must be performed + // every frame since the underlying texture is actually part of a ring + // buffer which is updated in lock-step with its associated pose. + // (You actually really only need to call any of the accessors which + // internally call Update on the SteamVR_TrackedCamera.VideoStreamTexture). + material.mainTexture = texture; + + // Adjust the height of the quad based on the aspect to keep the texels square. + var aspect = (float)texture.width / texture.height; + + // The undistorted video feed has 'bad' areas near the edges where the original + // square texture feed is stretched to undo the fisheye from the lens. + // Therefore, you'll want to crop it to the specified frameBounds to remove this. + if (cropped) + { + var bounds = source.frameBounds; + material.mainTextureOffset = new Vector2(bounds.uMin, bounds.vMin); + + var du = bounds.uMax - bounds.uMin; + var dv = bounds.vMax - bounds.vMin; + material.mainTextureScale = new Vector2(du, dv); + + aspect *= Mathf.Abs(du / dv); + } + else + { + material.mainTextureOffset = Vector2.zero; + material.mainTextureScale = new Vector2(1, -1); + } + + target.localScale = new Vector3(1, 1.0f / aspect, 1); + + // Apply the pose that this frame was recorded at. + if (source.hasTracking) + { + var t = source.transform; + target.localPosition = t.pos; + target.localRotation = t.rot; + } + } +} + diff --git a/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.cs.meta b/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.cs.meta new file mode 100644 index 0000000..062ae1e --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8b18b36a995ecb04599f35c2741be8d5 +timeCreated: 1465946679 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.mat b/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.mat new file mode 100644 index 0000000..ac7fe86 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.mat @@ -0,0 +1,127 @@ +%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: SteamVR_TestTrackedCamera + m_Shader: {fileID: 10752, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: _EMISSION + m_LightmapFlags: 1 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _BumpMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailAlbedoMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailMask + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailNormalMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _EmissionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 0.5, y: -0.49999994} + m_Offset: {x: 0.25, y: 0.75} + - first: + name: _MetallicGlossMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _OcclusionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _ParallaxMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: _BumpScale + second: 1 + - first: + name: _Cutoff + second: 0.5 + - first: + name: _DetailNormalMapScale + second: 1 + - first: + name: _DstBlend + second: 0 + - first: + name: _GlossMapScale + second: 1 + - first: + name: _Glossiness + second: 0.5 + - first: + name: _GlossyReflections + second: 1 + - first: + name: _Metallic + second: 0 + - first: + name: _Mode + second: 0 + - first: + name: _OcclusionStrength + second: 1 + - first: + name: _Parallax + second: 0.02 + - first: + name: _SmoothnessTextureChannel + second: 0 + - first: + name: _SpecularHighlights + second: 1 + - first: + name: _SrcBlend + second: 1 + - first: + name: _UVSec + second: 0 + - first: + name: _ZWrite + second: 1 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + - first: + name: _EmissionColor + second: {r: 0, g: 0, b: 0, a: 1} diff --git a/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.mat.meta b/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.mat.meta new file mode 100644 index 0000000..f8611eb --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 99ee8d48ccf36264e9d9a72baa681249 +timeCreated: 1465950289 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.unity b/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.unity new file mode 100644 index 0000000..5667ae0 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af5fd1bc44adb26245c6f31511caee4e9d3edc7415f8d690a901ce441edeef04 +size 23886 diff --git a/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.unity.meta b/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.unity.meta new file mode 100644 index 0000000..d3eb908 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TestTrackedCamera.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7fb811b0ffe615b4dbf1d5e6ced385fd +timeCreated: 1464227836 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/Extras/SteamVR_TrackedController.cs b/Assets/SteamVR/Extras/SteamVR_TrackedController.cs new file mode 100644 index 0000000..9922d44 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TrackedController.cs @@ -0,0 +1,250 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +using UnityEngine; +using Valve.VR; + +public struct ClickedEventArgs +{ + public uint controllerIndex; + public uint flags; + public float padX, padY; +} + +public delegate void ClickedEventHandler(object sender, ClickedEventArgs e); + +public class SteamVR_TrackedController : MonoBehaviour +{ + public uint controllerIndex; + public VRControllerState_t controllerState; + public bool triggerPressed = false; + public bool steamPressed = false; + public bool menuPressed = false; + public bool padPressed = false; + public bool padTouched = false; + public bool gripped = false; + + public event ClickedEventHandler MenuButtonClicked; + public event ClickedEventHandler MenuButtonUnclicked; + public event ClickedEventHandler TriggerClicked; + public event ClickedEventHandler TriggerUnclicked; + public event ClickedEventHandler SteamClicked; + public event ClickedEventHandler PadClicked; + public event ClickedEventHandler PadUnclicked; + public event ClickedEventHandler PadTouched; + public event ClickedEventHandler PadUntouched; + public event ClickedEventHandler Gripped; + public event ClickedEventHandler Ungripped; + + // Use this for initialization + protected virtual void Start() + { + if (this.GetComponent() == null) + { + gameObject.AddComponent(); + } + + if (controllerIndex != 0) + { + this.GetComponent().index = (SteamVR_TrackedObject.EIndex)controllerIndex; + if (this.GetComponent() != null) + { + this.GetComponent().index = (SteamVR_TrackedObject.EIndex)controllerIndex; + } + } + else + { + controllerIndex = (uint)this.GetComponent().index; + } + } + + public void SetDeviceIndex(int index) + { + this.controllerIndex = (uint)index; + } + + public virtual void OnTriggerClicked(ClickedEventArgs e) + { + if (TriggerClicked != null) + TriggerClicked(this, e); + } + + public virtual void OnTriggerUnclicked(ClickedEventArgs e) + { + if (TriggerUnclicked != null) + TriggerUnclicked(this, e); + } + + public virtual void OnMenuClicked(ClickedEventArgs e) + { + if (MenuButtonClicked != null) + MenuButtonClicked(this, e); + } + + public virtual void OnMenuUnclicked(ClickedEventArgs e) + { + if (MenuButtonUnclicked != null) + MenuButtonUnclicked(this, e); + } + + public virtual void OnSteamClicked(ClickedEventArgs e) + { + if (SteamClicked != null) + SteamClicked(this, e); + } + + public virtual void OnPadClicked(ClickedEventArgs e) + { + if (PadClicked != null) + PadClicked(this, e); + } + + public virtual void OnPadUnclicked(ClickedEventArgs e) + { + if (PadUnclicked != null) + PadUnclicked(this, e); + } + + public virtual void OnPadTouched(ClickedEventArgs e) + { + if (PadTouched != null) + PadTouched(this, e); + } + + public virtual void OnPadUntouched(ClickedEventArgs e) + { + if (PadUntouched != null) + PadUntouched(this, e); + } + + public virtual void OnGripped(ClickedEventArgs e) + { + if (Gripped != null) + Gripped(this, e); + } + + public virtual void OnUngripped(ClickedEventArgs e) + { + if (Ungripped != null) + Ungripped(this, e); + } + + // Update is called once per frame + protected virtual void Update() + { + var system = OpenVR.System; + if (system != null && system.GetControllerState(controllerIndex, ref controllerState, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VRControllerState_t)))) + { + ulong trigger = controllerState.ulButtonPressed & (1UL << ((int)EVRButtonId.k_EButton_SteamVR_Trigger)); + if (trigger > 0L && !triggerPressed) + { + triggerPressed = true; + ClickedEventArgs e; + e.controllerIndex = controllerIndex; + e.flags = (uint)controllerState.ulButtonPressed; + e.padX = controllerState.rAxis0.x; + e.padY = controllerState.rAxis0.y; + OnTriggerClicked(e); + + } + else if (trigger == 0L && triggerPressed) + { + triggerPressed = false; + ClickedEventArgs e; + e.controllerIndex = controllerIndex; + e.flags = (uint)controllerState.ulButtonPressed; + e.padX = controllerState.rAxis0.x; + e.padY = controllerState.rAxis0.y; + OnTriggerUnclicked(e); + } + + ulong grip = controllerState.ulButtonPressed & (1UL << ((int)EVRButtonId.k_EButton_Grip)); + if (grip > 0L && !gripped) + { + gripped = true; + ClickedEventArgs e; + e.controllerIndex = controllerIndex; + e.flags = (uint)controllerState.ulButtonPressed; + e.padX = controllerState.rAxis0.x; + e.padY = controllerState.rAxis0.y; + OnGripped(e); + + } + else if (grip == 0L && gripped) + { + gripped = false; + ClickedEventArgs e; + e.controllerIndex = controllerIndex; + e.flags = (uint)controllerState.ulButtonPressed; + e.padX = controllerState.rAxis0.x; + e.padY = controllerState.rAxis0.y; + OnUngripped(e); + } + + ulong pad = controllerState.ulButtonPressed & (1UL << ((int)EVRButtonId.k_EButton_SteamVR_Touchpad)); + if (pad > 0L && !padPressed) + { + padPressed = true; + ClickedEventArgs e; + e.controllerIndex = controllerIndex; + e.flags = (uint)controllerState.ulButtonPressed; + e.padX = controllerState.rAxis0.x; + e.padY = controllerState.rAxis0.y; + OnPadClicked(e); + } + else if (pad == 0L && padPressed) + { + padPressed = false; + ClickedEventArgs e; + e.controllerIndex = controllerIndex; + e.flags = (uint)controllerState.ulButtonPressed; + e.padX = controllerState.rAxis0.x; + e.padY = controllerState.rAxis0.y; + OnPadUnclicked(e); + } + + ulong menu = controllerState.ulButtonPressed & (1UL << ((int)EVRButtonId.k_EButton_ApplicationMenu)); + if (menu > 0L && !menuPressed) + { + menuPressed = true; + ClickedEventArgs e; + e.controllerIndex = controllerIndex; + e.flags = (uint)controllerState.ulButtonPressed; + e.padX = controllerState.rAxis0.x; + e.padY = controllerState.rAxis0.y; + OnMenuClicked(e); + } + else if (menu == 0L && menuPressed) + { + menuPressed = false; + ClickedEventArgs e; + e.controllerIndex = controllerIndex; + e.flags = (uint)controllerState.ulButtonPressed; + e.padX = controllerState.rAxis0.x; + e.padY = controllerState.rAxis0.y; + OnMenuUnclicked(e); + } + + pad = controllerState.ulButtonTouched & (1UL << ((int)EVRButtonId.k_EButton_SteamVR_Touchpad)); + if (pad > 0L && !padTouched) + { + padTouched = true; + ClickedEventArgs e; + e.controllerIndex = controllerIndex; + e.flags = (uint)controllerState.ulButtonPressed; + e.padX = controllerState.rAxis0.x; + e.padY = controllerState.rAxis0.y; + OnPadTouched(e); + + } + else if (pad == 0L && padTouched) + { + padTouched = false; + ClickedEventArgs e; + e.controllerIndex = controllerIndex; + e.flags = (uint)controllerState.ulButtonPressed; + e.padX = controllerState.rAxis0.x; + e.padY = controllerState.rAxis0.y; + OnPadUntouched(e); + } + } + } +} diff --git a/Assets/SteamVR/Extras/SteamVR_TrackedController.cs.meta b/Assets/SteamVR/Extras/SteamVR_TrackedController.cs.meta new file mode 100644 index 0000000..7cc72d0 --- /dev/null +++ b/Assets/SteamVR/Extras/SteamVR_TrackedController.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7346a42905a29b347b1f492e8ad7b49f +timeCreated: 1430337756 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem.meta b/Assets/SteamVR/InteractionSystem.meta new file mode 100644 index 0000000..f510efd --- /dev/null +++ b/Assets/SteamVR/InteractionSystem.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c8941a9f98c35d84cb19a5e044467de9 +folderAsset: yes +timeCreated: 1479762244 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core.meta b/Assets/SteamVR/InteractionSystem/Core.meta new file mode 100644 index 0000000..7cb2055 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1ab2780fe1da2544b86a1020e5f638e2 +folderAsset: yes +timeCreated: 1479762244 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons.meta b/Assets/SteamVR/InteractionSystem/Core/Icons.meta new file mode 100644 index 0000000..5c73e6b --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1fcf8377413b60c44afff7b2e4efd8f7 +folderAsset: yes +timeCreated: 1482867667 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system.png b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system.png new file mode 100644 index 0000000..ccdc4d0 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:761f314867d1d49c8f131ca3b1c2f6da61fea23664652b39b6dfd7f8c85e3f34 +size 14839 diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system.png.meta b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system.png.meta new file mode 100644 index 0000000..b83d41e --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: b93fe5c516cf6ed4b9153ec790f856e2 +timeCreated: 1484264198 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_feet.png b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_feet.png new file mode 100644 index 0000000..4891239 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_feet.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf9e175f5700ffb6bb73cc00ddd1755742568741b9b793dc9e05453b5da6d4b2 +size 11011 diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_feet.png.meta b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_feet.png.meta new file mode 100644 index 0000000..cf03fc9 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_feet.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 032fb1710098a1d47ad34d72e90f714a +timeCreated: 1435940722 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_left_hand.png b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_left_hand.png new file mode 100644 index 0000000..1b4cc02 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_left_hand.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea2c290be7aa9df4dd4e3e13f1ec88191e43e0b24faa0a01708ee9ee9c4e8035 +size 10034 diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_left_hand.png.meta b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_left_hand.png.meta new file mode 100644 index 0000000..fd76cfa --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_left_hand.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 27f3faef5a63db84c9cbac06e94ab7b3 +timeCreated: 1435940722 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_left_hand_question.png b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_left_hand_question.png new file mode 100644 index 0000000..07c3a15 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_left_hand_question.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e76a38e8335f84e32fd90a0ecfc5b4e8c9819cfecb455ff92b23b23967160f88 +size 11809 diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_left_hand_question.png.meta b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_left_hand_question.png.meta new file mode 100644 index 0000000..551713b --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_left_hand_question.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 6789d499b24f8964c8bb06e21008e546 +timeCreated: 1435940722 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_right_hand.png b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_right_hand.png new file mode 100644 index 0000000..63b1a55 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_right_hand.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d96acf42841f71b8e63be677becd16558d8543ef8724217e2af1b10915324cf +size 10163 diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_right_hand.png.meta b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_right_hand.png.meta new file mode 100644 index 0000000..a193a69 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_right_hand.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 1acda2a2584a8fb4683ea56799b27fa0 +timeCreated: 1435940722 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_right_hand_question.png b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_right_hand_question.png new file mode 100644 index 0000000..0befe6e --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_right_hand_question.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:feb7ce26eec9d58b5e5e790b0795def7284a92479aee962260239cccc6f9b0cb +size 11971 diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_right_hand_question.png.meta b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_right_hand_question.png.meta new file mode 100644 index 0000000..9725e1d --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_right_hand_question.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 90173f9e9e795f74ca97ccc52fe410cd +timeCreated: 1435940723 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_unknown_hand.png b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_unknown_hand.png new file mode 100644 index 0000000..3e3f7ec --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_unknown_hand.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb35c9d96deddc945b1f977a0fbf40eb98111c1e0cb6ba1f2d75c2beed27ef0f +size 13315 diff --git a/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_unknown_hand.png.meta b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_unknown_hand.png.meta new file mode 100644 index 0000000..1184b07 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Icons/vr_interaction_system_unknown_hand.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 77b322b27d7d39f4d91e479d19065d50 +timeCreated: 1435940723 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Materials.meta b/Assets/SteamVR/InteractionSystem/Core/Materials.meta new file mode 100644 index 0000000..d03e9b7 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Materials.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 05a69997deb9f5944a894239434f00a9 +folderAsset: yes +timeCreated: 1479762244 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Materials/FallbackHandIndicator.mat b/Assets/SteamVR/InteractionSystem/Core/Materials/FallbackHandIndicator.mat new file mode 100644 index 0000000..c4efae1 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Materials/FallbackHandIndicator.mat @@ -0,0 +1,138 @@ +%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: FallbackHandIndicator + m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: 2000 + stringTagMap: {} + 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} + data: + first: + name: _BumpMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DetailNormalMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _MetallicGlossMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ParallaxMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _OcclusionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _EmissionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DetailMask + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DetailAlbedoMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + data: + first: + name: _SrcBlend + second: 1 + data: + first: + name: _DstBlend + second: 0 + data: + first: + name: _Cutoff + second: .5 + data: + first: + name: _ZWrite + second: 1 + data: + first: + name: _Glossiness + second: 0 + data: + first: + name: _Metallic + second: 0 + data: + first: + name: _BumpScale + second: 1 + data: + first: + name: _Parallax + second: .0199999996 + data: + first: + name: _OcclusionStrength + second: 1 + data: + first: + name: _DetailNormalMapScale + second: 1 + data: + first: + name: _UVSec + second: 0 + data: + first: + name: _Mode + second: 0 + m_Colors: + data: + first: + name: _EmissionColor + second: {r: 0, g: 0, b: 0, a: 1} + data: + first: + name: _Color + second: {r: 1, g: 0, b: 0, a: 1} diff --git a/Assets/SteamVR/InteractionSystem/Core/Materials/FallbackHandIndicator.mat.meta b/Assets/SteamVR/InteractionSystem/Core/Materials/FallbackHandIndicator.mat.meta new file mode 100644 index 0000000..82644b5 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Materials/FallbackHandIndicator.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9e995e61de69d8647ae2b2d65eceab3f +timeCreated: 1436394722 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Materials/HoverHighlight.mat b/Assets/SteamVR/InteractionSystem/Core/Materials/HoverHighlight.mat new file mode 100644 index 0000000..7b40684 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Materials/HoverHighlight.mat @@ -0,0 +1,182 @@ +%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: HoverHighlight + m_Shader: {fileID: 4800000, guid: 0c1cf10ea69e60e4f9eb8955749f88ec, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + 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} + data: + first: + name: _BumpMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DetailNormalMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _ParallaxMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _OcclusionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _EmissionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DetailMask + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _DetailAlbedoMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + data: + first: + name: _MetallicGlossMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + data: + first: + name: _SrcBlend + second: 1 + data: + first: + name: _DstBlend + second: 0 + data: + first: + name: _Cutoff + second: 0.5 + data: + first: + name: g_flOutlineWidth + second: 0.005 + data: + first: + name: _Parallax + second: 0.02 + data: + first: + name: _ZWrite + second: 1 + data: + first: + name: _Glossiness + second: 0.5 + data: + first: + name: _BumpScale + second: 1 + data: + first: + name: _OcclusionStrength + second: 1 + data: + first: + name: _DetailNormalMapScale + second: 1 + data: + first: + name: _UVSec + second: 0 + data: + first: + name: _Mode + second: 0 + data: + first: + name: _Metallic + second: 0 + data: + first: + name: _Outline + second: 0.005 + data: + first: + name: _Opacity + second: 0 + data: + first: + name: _node_6969 + second: 0 + data: + first: + name: _OutlineWidth + second: 0.00238 + m_Colors: + data: + first: + name: _EmissionColor + second: {r: 0, g: 0, b: 0, a: 1} + data: + first: + name: _Color + second: {r: 0.486632, g: 0.78411454, b: 0.8823653, a: 1} + data: + first: + name: g_vOutlineColor + second: {r: 0.9485294, g: 0.9223629, b: 0, a: 1} + data: + first: + name: _OutlineColor + second: {r: 1, g: 0.9833671, b: 0.39705884, a: 1} + data: + first: + name: _node_2507 + second: {r: 0.6421389, g: 0.7807802, b: 0.78676474, a: 0} + data: + first: + name: _OutlightColor + second: {r: 0.9446255, g: 1, b: 0.42647058, a: 0.347} + data: + first: + name: _node_8174 + second: {r: 0.5, g: 0.5, b: 0.5, a: 1} + data: + first: + name: _node_8282 + second: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/SteamVR/InteractionSystem/Core/Materials/HoverHighlight.mat.meta b/Assets/SteamVR/InteractionSystem/Core/Materials/HoverHighlight.mat.meta new file mode 100644 index 0000000..bc49d16 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Materials/HoverHighlight.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7b939e5e799d98a469f594828ebab52e +timeCreated: 1439237525 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Materials/SeeThru.mat b/Assets/SteamVR/InteractionSystem/Core/Materials/SeeThru.mat new file mode 100644 index 0000000..89e506c --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Materials/SeeThru.mat @@ -0,0 +1,213 @@ +%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: SeeThru + m_Shader: {fileID: 4800000, guid: 6337aa7e7823eee43af8ffe676935e74, type: 3} + m_ShaderKeywords: S_SPECULAR_NONE S_UNLIT _ALPHABLEND_ON + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: + OriginalShader: Unlit/Texture + RenderType: Transparent + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _BumpMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailAlbedoMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailMask + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailNormalMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _EmissionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MetallicGlossMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _OcclusionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _ParallaxMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _SpecGlossMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: g_tOverrideLightmap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: PixelSnap + second: 0 + - first: + name: _BumpScale + second: 1 + - first: + name: _ColorMask + second: 15 + - first: + name: _Cutoff + second: 0.5 + - first: + name: _DetailNormalMapScale + second: 1 + - first: + name: _DstBlend + second: 10 + - first: + name: _Glossiness + second: 0.5 + - first: + name: _InvFade + second: 0.5 + - first: + name: _Metallic + second: 0 + - first: + name: _Mode + second: 2 + - first: + name: _OcclusionStrength + second: 1 + - first: + name: _OcclusionStrengthDirectDiffuse + second: 1 + - first: + name: _OcclusionStrengthDirectSpecular + second: 1 + - first: + name: _OcclusionStrengthIndirectDiffuse + second: 1 + - first: + name: _OcclusionStrengthIndirectSpecular + second: 1 + - first: + name: _Parallax + second: 0.02 + - first: + name: _SpecularMode + second: 1 + - first: + name: _SrcBlend + second: 5 + - first: + name: _Stencil + second: 0 + - first: + name: _StencilComp + second: 8 + - first: + name: _StencilOp + second: 0 + - first: + name: _StencilReadMask + second: 255 + - first: + name: _StencilWriteMask + second: 255 + - first: + name: _UVSec + second: 0 + - first: + name: _ZWrite + second: 0 + - first: + name: g_bReceiveShadows + second: 1 + - first: + name: g_bUnlit + second: 1 + - first: + name: g_bWorldAlignedTexture + second: 0 + - first: + name: g_flCubeMapScalar + second: 1 + - first: + name: g_flReflectanceBias + second: 0 + - first: + name: g_flReflectanceMax + second: 1 + - first: + name: g_flReflectanceMin + second: 0 + - first: + name: g_flReflectanceScale + second: 1 + m_Colors: + - first: + name: _Color + second: {r: 0.24999985, g: 0.24999985, b: 0.24999985, a: 0.1254902} + - first: + name: _EmissionColor + second: {r: 0, g: 0, b: 0, a: 1} + - first: + name: _SpecColor + second: {r: 0.2, g: 0.2, b: 0.2, a: 1} + - first: + name: _TintColor + second: {r: 0.5, g: 0.5, b: 0.5, a: 0.5} + - first: + name: g_vWorldAlignedNormalTangentU + second: {r: -1, g: 0, b: 0, a: 0} + - first: + name: g_vWorldAlignedNormalTangentV + second: {r: 0, g: 0, b: 1, a: 0} + - first: + name: g_vWorldAlignedTextureNormal + second: {r: 0, g: 1, b: 0, a: 0} + - first: + name: g_vWorldAlignedTexturePosition + second: {r: 0, g: 0, b: 0, a: 0} + - first: + name: g_vWorldAlignedTextureSize + second: {r: 1, g: 1, b: 1, a: 0} diff --git a/Assets/SteamVR/InteractionSystem/Core/Materials/SeeThru.mat.meta b/Assets/SteamVR/InteractionSystem/Core/Materials/SeeThru.mat.meta new file mode 100644 index 0000000..5630e46 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Materials/SeeThru.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3bbb445147c574240a8b87a1193788b5 +timeCreated: 1456708947 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Materials/SteamVRControllerModel.mat b/Assets/SteamVR/InteractionSystem/Core/Materials/SteamVRControllerModel.mat new file mode 100644 index 0000000..c320786 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Materials/SteamVRControllerModel.mat @@ -0,0 +1,197 @@ +%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: SteamVRControllerModel + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: S_RECEIVE_SHADOWS S_SPECULAR_METALLIC _EMISSION + m_LightmapFlags: 1 + m_CustomRenderQueue: -1 + stringTagMap: + OriginalShader: Standard + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _BumpMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailAlbedoMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailMask + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailNormalMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _EmissionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MetallicGlossMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _OcclusionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _ParallaxMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _SpecGlossMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: g_tOverrideLightmap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: _BumpScale + second: 1 + - first: + name: _Cutoff + second: 0.5 + - first: + name: _DetailNormalMapScale + second: 1 + - first: + name: _DstBlend + second: 0 + - first: + name: _GlossMapScale + second: 1 + - first: + name: _Glossiness + second: 0.405 + - first: + name: _GlossyReflections + second: 1 + - first: + name: _Metallic + second: 0 + - first: + name: _Mode + second: 0 + - first: + name: _OcclusionStrength + second: 1 + - first: + name: _OcclusionStrengthDirectDiffuse + second: 1 + - first: + name: _OcclusionStrengthDirectSpecular + second: 1 + - first: + name: _OcclusionStrengthIndirectDiffuse + second: 1 + - first: + name: _OcclusionStrengthIndirectSpecular + second: 1 + - first: + name: _Parallax + second: 0.02 + - first: + name: _SmoothnessTextureChannel + second: 0 + - first: + name: _SpecularHighlights + second: 1 + - first: + name: _SpecularMode + second: 2 + - first: + name: _SrcBlend + second: 1 + - first: + name: _UVSec + second: 0 + - first: + name: _ZWrite + second: 1 + - first: + name: g_bReceiveShadows + second: 1 + - first: + name: g_bUnlit + second: 0 + - first: + name: g_bWorldAlignedTexture + second: 0 + - first: + name: g_flCubeMapScalar + second: 1 + - first: + name: g_flReflectanceBias + second: 0 + - first: + name: g_flReflectanceMax + second: 1 + - first: + name: g_flReflectanceMin + second: 0 + - first: + name: g_flReflectanceScale + second: 1 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + - first: + name: _EmissionColor + second: {r: 0, g: 0, b: 0, a: 1} + - first: + name: _SpecColor + second: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + - first: + name: g_vWorldAlignedNormalTangentU + second: {r: -1, g: 0, b: 0, a: 0} + - first: + name: g_vWorldAlignedNormalTangentV + second: {r: 0, g: 0, b: 1, a: 0} + - first: + name: g_vWorldAlignedTextureNormal + second: {r: 0, g: 1, b: 0, a: 0} + - first: + name: g_vWorldAlignedTexturePosition + second: {r: 0, g: 0, b: 0, a: 0} + - first: + name: g_vWorldAlignedTextureSize + second: {r: 1, g: 1, b: 1, a: 0} diff --git a/Assets/SteamVR/InteractionSystem/Core/Materials/SteamVRControllerModel.mat.meta b/Assets/SteamVR/InteractionSystem/Core/Materials/SteamVRControllerModel.mat.meta new file mode 100644 index 0000000..4085b7e --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Materials/SteamVRControllerModel.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3c433e134e4719444b65bf064a77e22e +timeCreated: 1455877211 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Prefabs.meta b/Assets/SteamVR/InteractionSystem/Core/Prefabs.meta new file mode 100644 index 0000000..a505e51 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Prefabs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6d60d25020af6fb4f8d436244db7cc4b +folderAsset: yes +timeCreated: 1479762244 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Prefabs/BlankController.prefab b/Assets/SteamVR/InteractionSystem/Core/Prefabs/BlankController.prefab new file mode 100644 index 0000000..ef51cba --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Prefabs/BlankController.prefab @@ -0,0 +1,111 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &168468 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 421934} + - 114: {fileID: 11485822} + - 114: {fileID: 11450892} + - 114: {fileID: 11435852} + - 114: {fileID: 11467152} + m_Layer: 0 + m_Name: BlankController + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &421934 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 168468} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 +--- !u!114 &11435852 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 168468} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9fb3fe54664b917489646492ee8c4993, type: 3} + m_Name: + m_EditorClassIdentifier: + materials: + - {fileID: 2100000, guid: 3c433e134e4719444b65bf064a77e22e, type: 2} + - {fileID: 2100000, guid: 3bbb445147c574240a8b87a1193788b5, type: 2} +--- !u!114 &11450892 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 168468} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: eb6d6653511aff5409d0827d4e3b79ea, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &11467152 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 168468} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b8d4cc6cf300b3e4bb1411c4e041030c, type: 3} + m_Name: + m_EditorClassIdentifier: + teleportAllowed: 1 + overrideHoverLock: 1 +--- !u!114 &11485822 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 168468} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b93b6a877adcbf94c89a9d6e0c0e844d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 0} + propertyPath: itemPackage + value: + objectReference: {fileID: 11472598, guid: 0fe7b7f42b84b844e9eab51a98276389, + type: 2} + - target: {fileID: 0} + propertyPath: modelOverride + value: + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: controllerMaterial + value: + objectReference: {fileID: 2100000, guid: 3c433e134e4719444b65bf064a77e22e, type: 2} + - target: {fileID: 0} + propertyPath: m_Enabled + value: 1 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 168468} + m_IsPrefabParent: 1 diff --git a/Assets/SteamVR/InteractionSystem/Core/Prefabs/BlankController.prefab.meta b/Assets/SteamVR/InteractionSystem/Core/Prefabs/BlankController.prefab.meta new file mode 100644 index 0000000..efbd368 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Prefabs/BlankController.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3f39fc63a93686e4a8e9168ee73f24d9 +timeCreated: 1439253462 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Prefabs/Player.prefab b/Assets/SteamVR/InteractionSystem/Core/Prefabs/Player.prefab new file mode 100644 index 0000000..bab362c --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Prefabs/Player.prefab @@ -0,0 +1,1446 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &100470 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 490018} + m_Layer: 26 + m_Name: Attach_ControllerTip + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &101548 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 471722} + - 81: {fileID: 8194540} + m_Layer: 0 + m_Name: FollowHead + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &105336 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 402768} + m_Layer: 0 + m_Name: NoSteamVRFallbackObjects + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!1 &107460 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 409054} + - 23: {fileID: 2326430} + - 33: {fileID: 3390842} + - 114: {fileID: 11451472} + m_Layer: 0 + m_Name: PlayVolume + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!1 &107946 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 447954} + - 114: {fileID: 11465950} + m_Layer: 0 + m_Name: Player + m_TagString: Untagged + m_Icon: {fileID: 3936346786652291628, guid: 0000000000000000d000000000000000, type: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &109154 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 422332} + - 33: {fileID: 3368578} + - 23: {fileID: 2353626} + m_Layer: 26 + m_Name: Indicator + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &110716 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 496744} + - 20: {fileID: 2083460} + - 114: {fileID: 11476190} + m_Layer: 0 + m_Name: FallbackObjects + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &114188 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 494198} + m_Layer: 0 + m_Name: SteamVRObjects + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &121078 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 453574} + - 135: {fileID: 13533284} + - 54: {fileID: 5452286} + m_Layer: 26 + m_Name: HeadCollider + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &125964 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 429506} + - 20: {fileID: 2014920} + - 114: {fileID: 11450526} + - 92: {fileID: 9215702} + - 124: {fileID: 12440092} + - 114: {fileID: 114000012530188460} + m_Layer: 0 + m_Name: VRCamera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &129006 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 495400} + - 114: {fileID: 11405908} + m_Layer: 0 + m_Name: ControllerHoverHighlight + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &133480 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 471232} + - 114: {fileID: 11461462} + - 114: {fileID: 11464692} + - 114: {fileID: 114000013786455312} + m_Layer: 0 + m_Name: InputModule + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &135526 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 458882} + - 114: {fileID: 11497470} + - 54: {fileID: 5492098} + m_Layer: 26 + m_Name: FallbackHand + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &144230 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 476540} + - 114: {fileID: 11450312} + m_Layer: 26 + m_Name: Hand1 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &160596 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 485514} + - 114: {fileID: 11401046} + m_Layer: 26 + m_Name: Hand2 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &165334 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 480432} + m_Layer: 26 + m_Name: Attach_ControllerTip + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &167242 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 451882} + - 114: {fileID: 11461284} + m_Layer: 0 + m_Name: ControllerHoverHighlight + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &168724 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 472612} + - 114: {fileID: 11479638} + m_Layer: 0 + m_Name: '[SteamVR]' + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &171246 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 446772} + - 114: {fileID: 11489144} + m_Layer: 26 + m_Name: ControllerButtonHints + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &177230 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 413580} + - 114: {fileID: 11494192} + m_Layer: 26 + m_Name: ControllerButtonHints + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &191996 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 476076} + - 136: {fileID: 13693334} + - 114: {fileID: 11455280} + - 54: {fileID: 5475726} + m_Layer: 27 + m_Name: BodyCollider + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &402768 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 105336} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 496744} + - {fileID: 458882} + m_Father: {fileID: 447954} + m_RootOrder: 1 +--- !u!4 &409054 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 107460} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 447954} + m_RootOrder: 4 +--- !u!4 &413580 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 177230} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 476540} + m_RootOrder: 2 +--- !u!4 &422332 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 109154} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0.025, y: 0.025, z: 0.025} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 458882} + m_RootOrder: 0 +--- !u!4 &429506 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 125964} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 494198} + m_RootOrder: 4 +--- !u!4 &446772 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 171246} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 485514} + m_RootOrder: 2 +--- !u!4 &447954 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 107946} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 494198} + - {fileID: 402768} + - {fileID: 471722} + - {fileID: 471232} + - {fileID: 409054} + - {fileID: 4000012025983752} + m_Father: {fileID: 0} + m_RootOrder: 0 +--- !u!4 &451882 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 167242} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1.0100001, y: 1.01, z: 1.0100001} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 476540} + m_RootOrder: 1 +--- !u!4 &453574 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 121078} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 471722} + m_RootOrder: 0 +--- !u!4 &458882 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 135526} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 422332} + m_Father: {fileID: 402768} + m_RootOrder: 1 +--- !u!4 &471232 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 133480} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 447954} + m_RootOrder: 3 +--- !u!4 &471722 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 101548} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 453574} + m_Father: {fileID: 447954} + m_RootOrder: 2 +--- !u!4 &472612 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 168724} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 494198} + m_RootOrder: 1 +--- !u!4 &476076 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 191996} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 494198} + m_RootOrder: 0 +--- !u!4 &476540 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 144230} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -0.25, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 490018} + - {fileID: 451882} + - {fileID: 413580} + m_Father: {fileID: 494198} + m_RootOrder: 2 +--- !u!4 &480432 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 165334} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: -0.017, z: 0.0332} + m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 485514} + m_RootOrder: 0 +--- !u!4 &485514 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 160596} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0.25, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 480432} + - {fileID: 495400} + - {fileID: 446772} + m_Father: {fileID: 494198} + m_RootOrder: 3 +--- !u!4 &490018 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100470} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: -0.017, z: 0.0332} + m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 476540} + m_RootOrder: 0 +--- !u!4 &494198 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 114188} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 476076} + - {fileID: 472612} + - {fileID: 476540} + - {fileID: 485514} + - {fileID: 429506} + - {fileID: 4000011044845102} + m_Father: {fileID: 447954} + m_RootOrder: 0 +--- !u!4 &495400 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 129006} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1.0099999, y: 1.01, z: 1.0099999} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 485514} + m_RootOrder: 1 +--- !u!4 &496744 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 110716} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1.75, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 402768} + m_RootOrder: 0 +--- !u!20 &2014920 +Camera: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 125964} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.028762981, g: 0.05902014, b: 0.1397059, a: 1} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.05 + far clip plane: 300 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4160749567 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 + m_StereoMirrorMode: 0 +--- !u!20 &2083460 +Camera: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 110716} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.028762981, g: 0.05902014, b: 0.1397059, a: 1} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.05 + far clip plane: 300 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4160749567 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 0 + m_HDR: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 + m_StereoMirrorMode: 0 +--- !u!23 &2326430 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 107460} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_SubsetIndices: + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_SelectedWireframeHidden: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingOrder: 0 +--- !u!23 &2353626 +MeshRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 109154} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_Materials: + - {fileID: 2100000, guid: 9e995e61de69d8647ae2b2d65eceab3f, type: 2} + m_SubsetIndices: + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 1 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_SelectedWireframeHidden: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingOrder: 0 +--- !u!33 &3368578 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 109154} + m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} +--- !u!33 &3390842 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 107460} + m_Mesh: {fileID: 0} +--- !u!54 &5452286 +Rigidbody: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 121078} + serializedVersion: 2 + m_Mass: 1 + m_Drag: 0 + m_AngularDrag: 0 + m_UseGravity: 0 + m_IsKinematic: 1 + m_Interpolate: 0 + m_Constraints: 0 + m_CollisionDetection: 0 +--- !u!54 &5475726 +Rigidbody: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 191996} + serializedVersion: 2 + m_Mass: 1 + m_Drag: 0 + m_AngularDrag: 0 + m_UseGravity: 0 + m_IsKinematic: 1 + m_Interpolate: 0 + m_Constraints: 0 + m_CollisionDetection: 0 +--- !u!54 &5492098 +Rigidbody: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 135526} + serializedVersion: 2 + m_Mass: 1 + m_Drag: 0 + m_AngularDrag: 0 + m_UseGravity: 0 + m_IsKinematic: 1 + m_Interpolate: 0 + m_Constraints: 0 + m_CollisionDetection: 0 +--- !u!81 &8194540 +AudioListener: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 101548} + m_Enabled: 1 +--- !u!92 &9215702 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 125964} + m_Enabled: 1 +--- !u!114 &11401046 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 160596} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 29e3e4511966ba94d8ba0b98c6c62f82, type: 3} + m_Name: + m_EditorClassIdentifier: + otherHand: {fileID: 11450312} + startingHandType: 2 + hoverSphereTransform: {fileID: 0} + hoverSphereRadius: 0.05 + hoverLayerMask: + serializedVersion: 2 + m_Bits: 4294967295 + hoverUpdateInterval: 0.1 + noSteamVRFallbackCamera: {fileID: 0} + noSteamVRFallbackMaxDistanceNoItem: 10 + noSteamVRFallbackMaxDistanceWithItem: 0.5 + controllerPrefab: {fileID: 168468, guid: 3f39fc63a93686e4a8e9168ee73f24d9, type: 2} + showDebugText: 0 + spewDebugText: 0 +--- !u!114 &11405908 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 129006} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8ca2cc563cc33f542a5d9f8f661184ba, type: 3} + m_Name: + m_EditorClassIdentifier: + highLightMaterial: {fileID: 2100000, guid: 7b939e5e799d98a469f594828ebab52e, type: 2} + fireHapticsOnHightlight: 1 +--- !u!114 &11450312 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 144230} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 29e3e4511966ba94d8ba0b98c6c62f82, type: 3} + m_Name: + m_EditorClassIdentifier: + otherHand: {fileID: 11401046} + startingHandType: 2 + hoverSphereTransform: {fileID: 0} + hoverSphereRadius: 0.05 + hoverLayerMask: + serializedVersion: 2 + m_Bits: 4294967295 + hoverUpdateInterval: 0.1 + noSteamVRFallbackCamera: {fileID: 0} + noSteamVRFallbackMaxDistanceNoItem: 10 + noSteamVRFallbackMaxDistanceWithItem: 0.5 + controllerPrefab: {fileID: 168468, guid: 3f39fc63a93686e4a8e9168ee73f24d9, type: 2} + showDebugText: 0 + spewDebugText: 0 +--- !u!114 &11450526 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 125964} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2ad1e469d4e3e04489f9a36419f1a4f8, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &11451472 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 107460} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1f0522eaef74d984591c060d05a095c8, type: 3} + m_Name: + m_EditorClassIdentifier: + borderThickness: -0.07 + wireframeHeight: 2 + drawWireframeWhenSelectedOnly: 0 + drawInGame: 1 + size: 0 + color: {r: 0, g: 1, b: 1, a: 0.922} + vertices: + - {x: 1.0000002, y: 0.01, z: -1.0000002} + - {x: -1.0000002, y: 0.01, z: -1.0000002} + - {x: -1.0000002, y: 0.01, z: 1.0000002} + - {x: 1.0000002, y: 0.01, z: 1.0000002} + - {x: 0.93000025, y: 0.01, z: -0.93000025} + - {x: -0.93000025, y: 0.01, z: -0.93000025} + - {x: -0.93000025, y: 0.01, z: 0.93000025} + - {x: 0.93000025, y: 0.01, z: 0.93000025} +--- !u!114 &11455280 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 191996} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1731d642c0b250b48bb8cdfb153d9792, type: 3} + m_Name: + m_EditorClassIdentifier: + head: {fileID: 0} +--- !u!114 &11461284 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 167242} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8ca2cc563cc33f542a5d9f8f661184ba, type: 3} + m_Name: + m_EditorClassIdentifier: + highLightMaterial: {fileID: 2100000, guid: 7b939e5e799d98a469f594828ebab52e, type: 2} + fireHapticsOnHightlight: 1 +--- !u!114 &11461462 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 133480} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -619905303, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 0 + m_DragThreshold: 0 +--- !u!114 &11464692 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 133480} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c9e05292e0d62b542ac5bba92674a86d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &11465950 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 107946} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 202a6e24b48d1684398409c47161adcb, type: 3} + m_Name: + m_EditorClassIdentifier: + trackingOriginTransform: {fileID: 447954} + hmdTransforms: + - {fileID: 429506} + - {fileID: 496744} + hands: + - {fileID: 11450312} + - {fileID: 11401046} + - {fileID: 11497470} + headCollider: {fileID: 13533284} + rigSteamVR: {fileID: 114188} + rig2DFallback: {fileID: 105336} + audioListener: {fileID: 471722} + allowToggleTo2D: 1 +--- !u!114 &11476190 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 110716} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6043f3be9a21bd74281f9770463bea00, type: 3} + m_Name: + m_EditorClassIdentifier: + speed: 4 + shiftSpeed: 16 + showInstructions: 1 +--- !u!114 &11479638 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 168724} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e979227f3384fac4b8ca0b3550bf005c, type: 3} + m_Name: + m_EditorClassIdentifier: + pauseGameWhenDashboardIsVisible: 1 + lockPhysicsUpdateRateToRenderFrequency: 1 + externalCamera: {fileID: 0} + externalCameraConfigPath: externalcamera.cfg + trackingSpace: 1 +--- !u!114 &11489144 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 171246} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ea1001a6626353541ab4d4b39f4c3569, type: 3} + m_Name: + m_EditorClassIdentifier: + controllerMaterial: {fileID: 2100000, guid: 11b050e661ec0cf48a289a7266451e91, type: 2} + flashColor: {r: 1, g: 0.9170069, b: 0.453, a: 0.709} + textHintPrefab: {fileID: 140952, guid: 5fa42bb9e52706a42b8a1eaf0b54326a, type: 2} + debugHints: 0 +--- !u!114 &11494192 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 177230} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ea1001a6626353541ab4d4b39f4c3569, type: 3} + m_Name: + m_EditorClassIdentifier: + controllerMaterial: {fileID: 2100000, guid: 11b050e661ec0cf48a289a7266451e91, type: 2} + flashColor: {r: 1, g: 0.9170069, b: 0.453, a: 0.709} + textHintPrefab: {fileID: 140952, guid: 5fa42bb9e52706a42b8a1eaf0b54326a, type: 2} + debugHints: 0 +--- !u!114 &11497470 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 135526} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 29e3e4511966ba94d8ba0b98c6c62f82, type: 3} + m_Name: + m_EditorClassIdentifier: + otherHand: {fileID: 0} + startingHandType: 2 + hoverSphereTransform: {fileID: 0} + hoverSphereRadius: 0.05 + hoverLayerMask: + serializedVersion: 2 + m_Bits: 4294967295 + hoverUpdateInterval: 0.1 + noSteamVRFallbackCamera: {fileID: 2083460} + noSteamVRFallbackMaxDistanceNoItem: 10 + noSteamVRFallbackMaxDistanceWithItem: 0.5 + controllerPrefab: {fileID: 0} + showDebugText: 0 + spewDebugText: 0 +--- !u!124 &12440092 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 125964} + m_Enabled: 1 +--- !u!135 &13533284 +SphereCollider: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 121078} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Radius: 0.12 + m_Center: {x: 0, y: 0, z: 0} +--- !u!136 &13693334 +CapsuleCollider: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 191996} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 0 + m_Radius: 0.25 + m_Height: 1.5 + m_Direction: 1 + m_Center: {x: 0, y: 0.75, z: 0} +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 0} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 0} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 107946} + m_IsPrefabParent: 1 +--- !u!1 &1000011019469502 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 4000011044845102} + m_Layer: 8 + m_Name: '[Status]' + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1000011498581176 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 4000012025983752} + - 114: {fileID: 114000013709408034} + m_Layer: 0 + m_Name: DebugUI + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1000012100580070 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 4000013797098244} + - 20: {fileID: 20000012311191358} + - 92: {fileID: 92000014103672220} + - 132: {fileID: 132000010923692124} + - 114: {fileID: 114000011983135080} + - 114: {fileID: 114000013017895756} + m_Layer: 8 + m_Name: _Stats + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1000013281422588 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 4000011699137176} + - 114: {fileID: 114000010777378212} + m_Layer: 8 + m_Name: Overlay + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4000011044845102 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000011019469502} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 4000013797098244} + - {fileID: 4000011699137176} + m_Father: {fileID: 494198} + m_RootOrder: 5 +--- !u!4 &4000011699137176 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000013281422588} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 4000011044845102} + m_RootOrder: 1 +--- !u!4 &4000012025983752 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000011498581176} + 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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 447954} + m_RootOrder: 5 +--- !u!4 &4000013797098244 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000012100580070} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0.1, y: 0.75, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_Children: [] + m_Father: {fileID: 4000011044845102} + m_RootOrder: 0 +--- !u!20 &20000012311191358 +Camera: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000012100580070} + 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: 256 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 8400000, guid: 005ed5a6df2f5ff468efd6497d37fefa, type: 2} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_OcclusionCulling: 0 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 + m_StereoMirrorMode: 0 +--- !u!92 &92000014103672220 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000012100580070} + m_Enabled: 1 +--- !u!114 &114000010777378212 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000013281422588} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 46fe9e0b23166454c8cb73040321d78c, type: 3} + m_Name: + m_EditorClassIdentifier: + texture: {fileID: 8400000, guid: 005ed5a6df2f5ff468efd6497d37fefa, type: 2} + curved: 1 + antialias: 1 + highquality: 1 + scale: 3 + distance: 1.25 + alpha: 1 + uvOffset: {x: 0, y: 0, z: 1, w: 1} + mouseScale: {x: 1, y: 1} + curvedRange: {x: 1, y: 2} + inputMethod: 0 +--- !u!114 &114000011983135080 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000012100580070} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8c3faa610c019764a81eb8497109e2d4, type: 3} + m_Name: + m_EditorClassIdentifier: + text: {fileID: 0} + fadeColor: {r: 0, g: 0, b: 0, a: 1} + fadeDuration: 1 +--- !u!114 &114000012530188460 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 125964} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6bca9ccf900ccc84c887d783321d27e2, type: 3} + m_Name: + m_EditorClassIdentifier: + _head: {fileID: 429506} + _ears: {fileID: 0} + wireframe: 0 +--- !u!114 &114000013017895756 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000012100580070} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e7afc8c74d1f73b458705e0b946292a0, type: 3} + m_Name: + m_EditorClassIdentifier: + cursor: {fileID: 2800000, guid: 2db89a771043d7b4eb9d26622f6b97c7, type: 3} + background: {fileID: 2800000, guid: bb00cc87e146a414fbf2c4d3c0d31151, type: 3} + logo: {fileID: 2800000, guid: 09db43b3b77bf744287ba587fea02f8b, type: 3} + logoHeight: 340 + menuOffset: 40 + scaleLimits: {x: 0.1, y: 5} + scaleRate: 0.5 +--- !u!114 &114000013709408034 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000011498581176} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6f3bba2c36dd79242b3157dbcd876bf2, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114000013786455312 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 133480} + 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!132 &132000010923692124 +GUIText: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1000012100580070} + m_Enabled: 1 + serializedVersion: 3 + m_Text: + m_Anchor: 0 + m_Alignment: 0 + m_PixelOffset: {x: 0, y: 0} + m_LineSpacing: 1 + m_TabSize: 4 + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_Material: {fileID: 0} + m_FontSize: 32 + m_FontStyle: 1 + m_Color: + serializedVersion: 2 + rgba: 4278221311 + m_PixelCorrect: 1 + m_RichText: 1 diff --git a/Assets/SteamVR/InteractionSystem/Core/Prefabs/Player.prefab.meta b/Assets/SteamVR/InteractionSystem/Core/Prefabs/Player.prefab.meta new file mode 100644 index 0000000..2e49488 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Prefabs/Player.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dc06161b6d97feb419f45f03b62e14b9 +timeCreated: 1430240738 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts.meta new file mode 100644 index 0000000..50c9058 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 77a23888f82e2ab4c8bc825f20235e1e +folderAsset: yes +timeCreated: 1479762244 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/BodyCollider.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/BodyCollider.cs new file mode 100644 index 0000000..e03cf4e --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/BodyCollider.cs @@ -0,0 +1,35 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Collider dangling from the player's head +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( CapsuleCollider ) )] + public class BodyCollider : MonoBehaviour + { + public Transform head; + + private CapsuleCollider capsuleCollider; + + //------------------------------------------------- + void Awake() + { + capsuleCollider = GetComponent(); + } + + + //------------------------------------------------- + void FixedUpdate() + { + float distanceFromFloor = Vector3.Dot( head.localPosition, Vector3.up ); + capsuleCollider.height = Mathf.Max( capsuleCollider.radius, distanceFromFloor ); + transform.localPosition = head.localPosition - 0.5f * distanceFromFloor * Vector3.up; + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/BodyCollider.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/BodyCollider.cs.meta new file mode 100644 index 0000000..280704a --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/BodyCollider.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1731d642c0b250b48bb8cdfb153d9792 +timeCreated: 1434649753 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/CircularDrive.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/CircularDrive.cs new file mode 100644 index 0000000..b24d944 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/CircularDrive.cs @@ -0,0 +1,529 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Interactable that can be used to move in a circular motion +// +//============================================================================= + +using UnityEngine; +using UnityEngine.Events; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + + //------------------------------------------------------------------------- + [RequireComponent( typeof( Interactable ) )] + public class CircularDrive : MonoBehaviour + { + public enum Axis_t + { + XAxis, + YAxis, + ZAxis + }; + + [Tooltip( "The axis around which the circular drive will rotate in local space" )] + public Axis_t axisOfRotation = Axis_t.XAxis; + + [Tooltip( "Child GameObject which has the Collider component to initiate interaction, only needs to be set if there is more than one Collider child" )] + public Collider childCollider = null; + + [Tooltip( "A LinearMapping component to drive, if not specified one will be dynamically added to this GameObject" )] + public LinearMapping linearMapping; + + [Tooltip( "If true, the drive will stay manipulating as long as the button is held down, if false, it will stop if the controller moves out of the collider" )] + public bool hoverLock = false; + + [HeaderAttribute( "Limited Rotation" )] + [Tooltip( "If true, the rotation will be limited to [minAngle, maxAngle], if false, the rotation is unlimited" )] + public bool limited = false; + public Vector2 frozenDistanceMinMaxThreshold = new Vector2( 0.1f, 0.2f ); + public UnityEvent onFrozenDistanceThreshold; + + [HeaderAttribute( "Limited Rotation Min" )] + [Tooltip( "If limited is true, the specifies the lower limit, otherwise value is unused" )] + public float minAngle = -45.0f; + [Tooltip( "If limited, set whether drive will freeze its angle when the min angle is reached" )] + public bool freezeOnMin = false; + [Tooltip( "If limited, event invoked when minAngle is reached" )] + public UnityEvent onMinAngle; + + [HeaderAttribute( "Limited Rotation Max" )] + [Tooltip( "If limited is true, the specifies the upper limit, otherwise value is unused" )] + public float maxAngle = 45.0f; + [Tooltip( "If limited, set whether drive will freeze its angle when the max angle is reached" )] + public bool freezeOnMax = false; + [Tooltip( "If limited, event invoked when maxAngle is reached" )] + public UnityEvent onMaxAngle; + + [Tooltip( "If limited is true, this forces the starting angle to be startAngle, clamped to [minAngle, maxAngle]" )] + public bool forceStart = false; + [Tooltip( "If limited is true and forceStart is true, the starting angle will be this, clamped to [minAngle, maxAngle]" )] + public float startAngle = 0.0f; + + [Tooltip( "If true, the transform of the GameObject this component is on will be rotated accordingly" )] + public bool rotateGameObject = true; + + [Tooltip( "If true, the path of the Hand (red) and the projected value (green) will be drawn" )] + public bool debugPath = false; + [Tooltip( "If debugPath is true, this is the maximum number of GameObjects to create to draw the path" )] + public int dbgPathLimit = 50; + + [Tooltip( "If not null, the TextMesh will display the linear value and the angular value of this circular drive" )] + public TextMesh debugText = null; + + [Tooltip( "The output angle value of the drive in degrees, unlimited will increase or decrease without bound, take the 360 modulus to find number of rotations" )] + public float outAngle; + + private Quaternion start; + + private Vector3 worldPlaneNormal = new Vector3( 1.0f, 0.0f, 0.0f ); + private Vector3 localPlaneNormal = new Vector3( 1.0f, 0.0f, 0.0f ); + + private Vector3 lastHandProjected; + + private Color red = new Color( 1.0f, 0.0f, 0.0f ); + private Color green = new Color( 0.0f, 1.0f, 0.0f ); + + private GameObject[] dbgHandObjects; + private GameObject[] dbgProjObjects; + private GameObject dbgObjectsParent; + private int dbgObjectCount = 0; + private int dbgObjectIndex = 0; + + private bool driving = false; + + // If the drive is limited as is at min/max, angles greater than this are ignored + private float minMaxAngularThreshold = 1.0f; + + private bool frozen = false; + private float frozenAngle = 0.0f; + private Vector3 frozenHandWorldPos = new Vector3( 0.0f, 0.0f, 0.0f ); + private Vector2 frozenSqDistanceMinMaxThreshold = new Vector2( 0.0f, 0.0f ); + + Hand handHoverLocked = null; + + //------------------------------------------------- + private void Freeze( Hand hand ) + { + frozen = true; + frozenAngle = outAngle; + frozenHandWorldPos = hand.hoverSphereTransform.position; + frozenSqDistanceMinMaxThreshold.x = frozenDistanceMinMaxThreshold.x * frozenDistanceMinMaxThreshold.x; + frozenSqDistanceMinMaxThreshold.y = frozenDistanceMinMaxThreshold.y * frozenDistanceMinMaxThreshold.y; + } + + + //------------------------------------------------- + private void UnFreeze() + { + frozen = false; + frozenHandWorldPos.Set( 0.0f, 0.0f, 0.0f ); + } + + + //------------------------------------------------- + void Start() + { + if ( childCollider == null ) + { + childCollider = GetComponentInChildren(); + } + + if ( linearMapping == null ) + { + linearMapping = GetComponent(); + } + + if ( linearMapping == null ) + { + linearMapping = gameObject.AddComponent(); + } + + worldPlaneNormal = new Vector3( 0.0f, 0.0f, 0.0f ); + worldPlaneNormal[(int)axisOfRotation] = 1.0f; + + localPlaneNormal = worldPlaneNormal; + + if ( transform.parent ) + { + worldPlaneNormal = transform.parent.localToWorldMatrix.MultiplyVector( worldPlaneNormal ).normalized; + } + + if ( limited ) + { + start = Quaternion.identity; + outAngle = transform.localEulerAngles[(int)axisOfRotation]; + + if ( forceStart ) + { + outAngle = Mathf.Clamp( startAngle, minAngle, maxAngle ); + } + } + else + { + start = Quaternion.AngleAxis( transform.localEulerAngles[(int)axisOfRotation], localPlaneNormal ); + outAngle = 0.0f; + } + + if ( debugText ) + { + debugText.alignment = TextAlignment.Left; + debugText.anchor = TextAnchor.UpperLeft; + } + + UpdateAll(); + } + + + //------------------------------------------------- + void OnDisable() + { + if ( handHoverLocked ) + { + ControllerButtonHints.HideButtonHint( handHoverLocked, Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger ); + handHoverLocked.HoverUnlock( GetComponent() ); + handHoverLocked = null; + } + } + + + //------------------------------------------------- + private IEnumerator HapticPulses( SteamVR_Controller.Device controller, float flMagnitude, int nCount ) + { + if ( controller != null ) + { + int nRangeMax = (int)Util.RemapNumberClamped( flMagnitude, 0.0f, 1.0f, 100.0f, 900.0f ); + nCount = Mathf.Clamp( nCount, 1, 10 ); + + for ( ushort i = 0; i < nCount; ++i ) + { + ushort duration = (ushort)Random.Range( 100, nRangeMax ); + controller.TriggerHapticPulse( duration ); + yield return new WaitForSeconds( .01f ); + } + } + } + + + //------------------------------------------------- + private void OnHandHoverBegin( Hand hand ) + { + ControllerButtonHints.ShowButtonHint( hand, Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger ); + } + + + //------------------------------------------------- + private void OnHandHoverEnd( Hand hand ) + { + ControllerButtonHints.HideButtonHint( hand, Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger ); + + if ( driving && hand.GetStandardInteractionButton() ) + { + StartCoroutine( HapticPulses( hand.controller, 1.0f, 10 ) ); + } + + driving = false; + handHoverLocked = null; + } + + + //------------------------------------------------- + private void HandHoverUpdate( Hand hand ) + { + if ( hand.GetStandardInteractionButtonDown() ) + { + // Trigger was just pressed + lastHandProjected = ComputeToTransformProjected( hand.hoverSphereTransform ); + + if ( hoverLock ) + { + hand.HoverLock( GetComponent() ); + handHoverLocked = hand; + } + + driving = true; + + ComputeAngle( hand ); + UpdateAll(); + + ControllerButtonHints.HideButtonHint( hand, Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger ); + } + else if ( hand.GetStandardInteractionButtonUp() ) + { + // Trigger was just released + if ( hoverLock ) + { + hand.HoverUnlock( GetComponent() ); + handHoverLocked = null; + } + } + else if ( driving && hand.GetStandardInteractionButton() && hand.hoveringInteractable == GetComponent() ) + { + ComputeAngle( hand ); + UpdateAll(); + } + } + + + //------------------------------------------------- + private Vector3 ComputeToTransformProjected( Transform xForm ) + { + Vector3 toTransform = ( xForm.position - transform.position ).normalized; + Vector3 toTransformProjected = new Vector3( 0.0f, 0.0f, 0.0f ); + + // Need a non-zero distance from the hand to the center of the CircularDrive + if ( toTransform.sqrMagnitude > 0.0f ) + { + toTransformProjected = Vector3.ProjectOnPlane( toTransform, worldPlaneNormal ).normalized; + } + else + { + Debug.LogFormat( "The collider needs to be a minimum distance away from the CircularDrive GameObject {0}", gameObject.ToString() ); + Debug.Assert( false, string.Format( "The collider needs to be a minimum distance away from the CircularDrive GameObject {0}", gameObject.ToString() ) ); + } + + if ( debugPath && dbgPathLimit > 0 ) + { + DrawDebugPath( xForm, toTransformProjected ); + } + + return toTransformProjected; + } + + + //------------------------------------------------- + private void DrawDebugPath( Transform xForm, Vector3 toTransformProjected ) + { + if ( dbgObjectCount == 0 ) + { + dbgObjectsParent = new GameObject( "Circular Drive Debug" ); + dbgHandObjects = new GameObject[dbgPathLimit]; + dbgProjObjects = new GameObject[dbgPathLimit]; + dbgObjectCount = dbgPathLimit; + dbgObjectIndex = 0; + } + + //Actual path + GameObject gSphere = null; + + if ( dbgHandObjects[dbgObjectIndex] ) + { + gSphere = dbgHandObjects[dbgObjectIndex]; + } + else + { + gSphere = GameObject.CreatePrimitive( PrimitiveType.Sphere ); + gSphere.transform.SetParent( dbgObjectsParent.transform ); + dbgHandObjects[dbgObjectIndex] = gSphere; + } + + gSphere.name = string.Format( "actual_{0}", (int)( ( 1.0f - red.r ) * 10.0f ) ); + gSphere.transform.position = xForm.position; + gSphere.transform.rotation = Quaternion.Euler( 0.0f, 0.0f, 0.0f ); + gSphere.transform.localScale = new Vector3( 0.004f, 0.004f, 0.004f ); + gSphere.gameObject.GetComponent().material.color = red; + + if ( red.r > 0.1f ) + { + red.r -= 0.1f; + } + else + { + red.r = 1.0f; + } + + //Projected path + gSphere = null; + + if ( dbgProjObjects[dbgObjectIndex] ) + { + gSphere = dbgProjObjects[dbgObjectIndex]; + } + else + { + gSphere = GameObject.CreatePrimitive( PrimitiveType.Sphere ); + gSphere.transform.SetParent( dbgObjectsParent.transform ); + dbgProjObjects[dbgObjectIndex] = gSphere; + } + + gSphere.name = string.Format( "projed_{0}", (int)( ( 1.0f - green.g ) * 10.0f ) ); + gSphere.transform.position = transform.position + toTransformProjected * 0.25f; + gSphere.transform.rotation = Quaternion.Euler( 0.0f, 0.0f, 0.0f ); + gSphere.transform.localScale = new Vector3( 0.004f, 0.004f, 0.004f ); + gSphere.gameObject.GetComponent().material.color = green; + + if ( green.g > 0.1f ) + { + green.g -= 0.1f; + } + else + { + green.g = 1.0f; + } + + dbgObjectIndex = ( dbgObjectIndex + 1 ) % dbgObjectCount; + } + + + //------------------------------------------------- + // Updates the LinearMapping value from the angle + //------------------------------------------------- + private void UpdateLinearMapping() + { + if ( limited ) + { + // Map it to a [0, 1] value + linearMapping.value = ( outAngle - minAngle ) / ( maxAngle - minAngle ); + } + else + { + // Normalize to [0, 1] based on 360 degree windings + float flTmp = outAngle / 360.0f; + linearMapping.value = flTmp - Mathf.Floor( flTmp ); + } + + UpdateDebugText(); + } + + + //------------------------------------------------- + // Updates the LinearMapping value from the angle + //------------------------------------------------- + private void UpdateGameObject() + { + if ( rotateGameObject ) + { + transform.localRotation = start * Quaternion.AngleAxis( outAngle, localPlaneNormal ); + } + } + + + //------------------------------------------------- + // Updates the Debug TextMesh with the linear mapping value and the angle + //------------------------------------------------- + private void UpdateDebugText() + { + if ( debugText ) + { + debugText.text = string.Format( "Linear: {0}\nAngle: {1}\n", linearMapping.value, outAngle ); + } + } + + + //------------------------------------------------- + // Updates the Debug TextMesh with the linear mapping value and the angle + //------------------------------------------------- + private void UpdateAll() + { + UpdateLinearMapping(); + UpdateGameObject(); + UpdateDebugText(); + } + + + //------------------------------------------------- + // Computes the angle to rotate the game object based on the change in the transform + //------------------------------------------------- + private void ComputeAngle( Hand hand ) + { + Vector3 toHandProjected = ComputeToTransformProjected( hand.hoverSphereTransform ); + + if ( !toHandProjected.Equals( lastHandProjected ) ) + { + float absAngleDelta = Vector3.Angle( lastHandProjected, toHandProjected ); + + if ( absAngleDelta > 0.0f ) + { + if ( frozen ) + { + float frozenSqDist = ( hand.hoverSphereTransform.position - frozenHandWorldPos ).sqrMagnitude; + if ( frozenSqDist > frozenSqDistanceMinMaxThreshold.x ) + { + outAngle = frozenAngle + Random.Range( -1.0f, 1.0f ); + + float magnitude = Util.RemapNumberClamped( frozenSqDist, frozenSqDistanceMinMaxThreshold.x, frozenSqDistanceMinMaxThreshold.y, 0.0f, 1.0f ); + if ( magnitude > 0 ) + { + StartCoroutine( HapticPulses( hand.controller, magnitude, 10 ) ); + } + else + { + StartCoroutine( HapticPulses( hand.controller, 0.5f, 10 ) ); + } + + if ( frozenSqDist >= frozenSqDistanceMinMaxThreshold.y ) + { + onFrozenDistanceThreshold.Invoke(); + } + } + } + else + { + Vector3 cross = Vector3.Cross( lastHandProjected, toHandProjected ).normalized; + float dot = Vector3.Dot( worldPlaneNormal, cross ); + + float signedAngleDelta = absAngleDelta; + + if ( dot < 0.0f ) + { + signedAngleDelta = -signedAngleDelta; + } + + if ( limited ) + { + float angleTmp = Mathf.Clamp( outAngle + signedAngleDelta, minAngle, maxAngle ); + + if ( outAngle == minAngle ) + { + if ( angleTmp > minAngle && absAngleDelta < minMaxAngularThreshold ) + { + outAngle = angleTmp; + lastHandProjected = toHandProjected; + } + } + else if ( outAngle == maxAngle ) + { + if ( angleTmp < maxAngle && absAngleDelta < minMaxAngularThreshold ) + { + outAngle = angleTmp; + lastHandProjected = toHandProjected; + } + } + else if ( angleTmp == minAngle ) + { + outAngle = angleTmp; + lastHandProjected = toHandProjected; + onMinAngle.Invoke(); + if ( freezeOnMin ) + { + Freeze( hand ); + } + } + else if ( angleTmp == maxAngle ) + { + outAngle = angleTmp; + lastHandProjected = toHandProjected; + onMaxAngle.Invoke(); + if ( freezeOnMax ) + { + Freeze( hand ); + } + } + else + { + outAngle = angleTmp; + lastHandProjected = toHandProjected; + } + } + else + { + outAngle += signedAngleDelta; + lastHandProjected = toHandProjected; + } + } + } + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/CircularDrive.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/CircularDrive.cs.meta new file mode 100644 index 0000000..3895f2f --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/CircularDrive.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1f32883eed859804dbb0c5fedac91496 +timeCreated: 1440531244 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/ComplexThrowable.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/ComplexThrowable.cs new file mode 100644 index 0000000..4c367fc --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/ComplexThrowable.cs @@ -0,0 +1,190 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Throwable that uses physics joints to attach instead of just +// parenting +// +//============================================================================= + +using UnityEngine; +using System.Collections.Generic; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( Interactable ) )] + public class ComplexThrowable : MonoBehaviour + { + public enum AttachMode + { + FixedJoint, + Force, + } + + public float attachForce = 800.0f; + public float attachForceDamper = 25.0f; + + public AttachMode attachMode = AttachMode.FixedJoint; + + [EnumFlags] + public Hand.AttachmentFlags attachmentFlags = 0; + + private List holdingHands = new List(); + private List holdingBodies = new List(); + private List holdingPoints = new List(); + + private List rigidBodies = new List(); + + //------------------------------------------------- + void Awake() + { + GetComponentsInChildren( rigidBodies ); + } + + + //------------------------------------------------- + void Update() + { + for ( int i = 0; i < holdingHands.Count; i++ ) + { + if ( !holdingHands[i].GetStandardInteractionButton() ) + { + PhysicsDetach( holdingHands[i] ); + } + } + } + + + //------------------------------------------------- + private void OnHandHoverBegin( Hand hand ) + { + if ( holdingHands.IndexOf( hand ) == -1 ) + { + if ( hand.controller != null ) + { + hand.controller.TriggerHapticPulse( 800 ); + } + } + } + + + //------------------------------------------------- + private void OnHandHoverEnd( Hand hand ) + { + if ( holdingHands.IndexOf( hand ) == -1 ) + { + if ( hand.controller != null ) + { + hand.controller.TriggerHapticPulse( 500 ); + } + } + } + + + //------------------------------------------------- + private void HandHoverUpdate( Hand hand ) + { + if ( hand.GetStandardInteractionButtonDown() ) + { + PhysicsAttach( hand ); + } + } + + + //------------------------------------------------- + private void PhysicsAttach( Hand hand ) + { + PhysicsDetach( hand ); + + Rigidbody holdingBody = null; + Vector3 holdingPoint = Vector3.zero; + + // The hand should grab onto the nearest rigid body + float closestDistance = float.MaxValue; + for ( int i = 0; i < rigidBodies.Count; i++ ) + { + float distance = Vector3.Distance( rigidBodies[i].worldCenterOfMass, hand.transform.position ); + if ( distance < closestDistance ) + { + holdingBody = rigidBodies[i]; + closestDistance = distance; + } + } + + // Couldn't grab onto a body + if ( holdingBody == null ) + return; + + // Create a fixed joint from the hand to the holding body + if ( attachMode == AttachMode.FixedJoint ) + { + Rigidbody handRigidbody = Util.FindOrAddComponent( hand.gameObject ); + handRigidbody.isKinematic = true; + + FixedJoint handJoint = hand.gameObject.AddComponent(); + handJoint.connectedBody = holdingBody; + } + + // Don't let the hand interact with other things while it's holding us + hand.HoverLock( null ); + + // Affix this point + Vector3 offset = hand.transform.position - holdingBody.worldCenterOfMass; + offset = Mathf.Min( offset.magnitude, 1.0f ) * offset.normalized; + holdingPoint = holdingBody.transform.InverseTransformPoint( holdingBody.worldCenterOfMass + offset ); + + hand.AttachObject( this.gameObject, attachmentFlags ); + + // Update holding list + holdingHands.Add( hand ); + holdingBodies.Add( holdingBody ); + holdingPoints.Add( holdingPoint ); + } + + + //------------------------------------------------- + private bool PhysicsDetach( Hand hand ) + { + int i = holdingHands.IndexOf( hand ); + + if ( i != -1 ) + { + // Detach this object from the hand + holdingHands[i].DetachObject( this.gameObject, false ); + + // Allow the hand to do other things + holdingHands[i].HoverUnlock( null ); + + // Delete any existing joints from the hand + if ( attachMode == AttachMode.FixedJoint ) + { + Destroy( holdingHands[i].GetComponent() ); + } + + Util.FastRemove( holdingHands, i ); + Util.FastRemove( holdingBodies, i ); + Util.FastRemove( holdingPoints, i ); + + return true; + } + + return false; + } + + + //------------------------------------------------- + void FixedUpdate() + { + if ( attachMode == AttachMode.Force ) + { + for ( int i = 0; i < holdingHands.Count; i++ ) + { + Vector3 targetPoint = holdingBodies[i].transform.TransformPoint( holdingPoints[i] ); + Vector3 vdisplacement = holdingHands[i].transform.position - targetPoint; + + holdingBodies[i].AddForceAtPosition( attachForce * vdisplacement, targetPoint, ForceMode.Acceleration ); + holdingBodies[i].AddForceAtPosition( -attachForceDamper * holdingBodies[i].GetPointVelocity( targetPoint ), targetPoint, ForceMode.Acceleration ); + } + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/ComplexThrowable.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/ComplexThrowable.cs.meta new file mode 100644 index 0000000..d9e69cc --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/ComplexThrowable.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ad77666522338cf49ba83b80b25e6476 +timeCreated: 1440023090 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/ControllerHoverHighlight.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/ControllerHoverHighlight.cs new file mode 100644 index 0000000..fc53bfe --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/ControllerHoverHighlight.cs @@ -0,0 +1,197 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Highlights the controller when hovering over interactables +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class ControllerHoverHighlight : MonoBehaviour + { + public Material highLightMaterial; + public bool fireHapticsOnHightlight = true; + + private Hand hand; + + private MeshRenderer bodyMeshRenderer; + private MeshRenderer trackingHatMeshRenderer; + private SteamVR_RenderModel renderModel; + private bool renderModelLoaded = false; + + SteamVR_Events.Action renderModelLoadedAction; + + //------------------------------------------------- + void Start() + { + hand = GetComponentInParent(); + } + + + //------------------------------------------------- + void Awake() + { + renderModelLoadedAction = SteamVR_Events.RenderModelLoadedAction( OnRenderModelLoaded ); + } + + + //------------------------------------------------- + void OnEnable() + { + renderModelLoadedAction.enabled = true; + } + + + //------------------------------------------------- + void OnDisable() + { + renderModelLoadedAction.enabled = false; + } + + + //------------------------------------------------- + private void OnHandInitialized( int deviceIndex ) + { + renderModel = gameObject.AddComponent(); + renderModel.SetDeviceIndex( deviceIndex ); + renderModel.updateDynamically = false; + } + + + //------------------------------------------------- + private void OnRenderModelLoaded( SteamVR_RenderModel renderModel, bool success ) + { + if ( renderModel != this.renderModel ) + { + return; + } + + Transform bodyTransform = transform.Find( "body" ); + if ( bodyTransform != null ) + { + bodyTransform.gameObject.layer = gameObject.layer; + bodyTransform.gameObject.tag = gameObject.tag; + bodyMeshRenderer = bodyTransform.GetComponent(); + bodyMeshRenderer.material = highLightMaterial; + bodyMeshRenderer.enabled = false; + } + + Transform trackingHatTransform = transform.Find( "trackhat" ); + if ( trackingHatTransform != null ) + { + trackingHatTransform.gameObject.layer = gameObject.layer; + trackingHatTransform.gameObject.tag = gameObject.tag; + trackingHatMeshRenderer = trackingHatTransform.GetComponent(); + trackingHatMeshRenderer.material = highLightMaterial; + trackingHatMeshRenderer.enabled = false; + } + + foreach ( Transform child in transform ) + { + if ( ( child.name != "body" ) && ( child.name != "trackhat" ) ) + { + Destroy( child.gameObject ); + } + } + + renderModelLoaded = true; + } + + + //------------------------------------------------- + private void OnParentHandHoverBegin( Interactable other ) + { + if ( !this.isActiveAndEnabled ) + { + return; + } + + if ( other.transform.parent != transform.parent ) + { + ShowHighlight(); + } + } + + + //------------------------------------------------- + private void OnParentHandHoverEnd( Interactable other ) + { + HideHighlight(); + } + + + //------------------------------------------------- + private void OnParentHandInputFocusAcquired() + { + if ( !this.isActiveAndEnabled ) + { + return; + } + + if ( hand.hoveringInteractable && hand.hoveringInteractable.transform.parent != transform.parent ) + { + ShowHighlight(); + } + } + + + //------------------------------------------------- + private void OnParentHandInputFocusLost() + { + HideHighlight(); + } + + + //------------------------------------------------- + public void ShowHighlight() + { + if ( renderModelLoaded == false ) + { + return; + } + + if ( fireHapticsOnHightlight ) + { + hand.controller.TriggerHapticPulse( 500 ); + } + + if ( bodyMeshRenderer != null ) + { + bodyMeshRenderer.enabled = true; + } + + if ( trackingHatMeshRenderer != null ) + { + trackingHatMeshRenderer.enabled = true; + } + } + + + //------------------------------------------------- + public void HideHighlight() + { + if ( renderModelLoaded == false ) + { + return; + } + + if ( fireHapticsOnHightlight ) + { + hand.controller.TriggerHapticPulse( 300 ); + } + + if ( bodyMeshRenderer != null ) + { + bodyMeshRenderer.enabled = false; + } + + if ( trackingHatMeshRenderer != null ) + { + trackingHatMeshRenderer.enabled = false; + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/ControllerHoverHighlight.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/ControllerHoverHighlight.cs.meta new file mode 100644 index 0000000..34e581c --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/ControllerHoverHighlight.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8ca2cc563cc33f542a5d9f8f661184ba +timeCreated: 1441139979 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/CustomEvents.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/CustomEvents.cs new file mode 100644 index 0000000..ae37001 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/CustomEvents.cs @@ -0,0 +1,28 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Custom Unity Events that take in additional parameters +// +//============================================================================= + +using UnityEngine.Events; +using System; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public static class CustomEvents + { + //------------------------------------------------- + [System.Serializable] + public class UnityEventSingleFloat : UnityEvent + { + } + + + //------------------------------------------------- + [System.Serializable] + public class UnityEventHand : UnityEvent + { + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/CustomEvents.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/CustomEvents.cs.meta new file mode 100644 index 0000000..aee0603 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/CustomEvents.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5f3294e06115d0047a2ac7659a11b168 +timeCreated: 1437076614 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/DebugUI.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/DebugUI.cs new file mode 100644 index 0000000..079b373 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/DebugUI.cs @@ -0,0 +1,48 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Debug UI shown for the player +// +//============================================================================= + +using UnityEngine; +using UnityEngine.UI; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class DebugUI : MonoBehaviour + { + private Player player; + + //------------------------------------------------- + static private DebugUI _instance; + static public DebugUI instance + { + get + { + if ( _instance == null ) + { + _instance = GameObject.FindObjectOfType(); + } + return _instance; + } + } + + + //------------------------------------------------- + void Start() + { + player = Player.instance; + } + + + //------------------------------------------------- + private void OnGUI() + { +#if !HIDE_DEBUG_UI + player.Draw2DDebug(); +#endif + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/DebugUI.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/DebugUI.cs.meta new file mode 100644 index 0000000..a2da5e7 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/DebugUI.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6f3bba2c36dd79242b3157dbcd876bf2 +timeCreated: 1458703500 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnDetachedFromHand.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnDetachedFromHand.cs new file mode 100644 index 0000000..5cf17d1 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnDetachedFromHand.cs @@ -0,0 +1,22 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Destroys this object when it is detached from the hand +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( Interactable ) )] + public class DestroyOnDetachedFromHand : MonoBehaviour + { + //------------------------------------------------- + private void OnDetachedFromHand( Hand hand ) + { + Destroy( gameObject ); + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnDetachedFromHand.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnDetachedFromHand.cs.meta new file mode 100644 index 0000000..a660260 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnDetachedFromHand.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5240357a2468cdc4291b266bee3cb9b9 +timeCreated: 1442359285 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnParticleSystemDeath.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnParticleSystemDeath.cs new file mode 100644 index 0000000..ac37223 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnParticleSystemDeath.cs @@ -0,0 +1,36 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Destroys this object when its particle system dies +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( ParticleSystem ) )] + public class DestroyOnParticleSystemDeath : MonoBehaviour + { + private ParticleSystem particles; + + //------------------------------------------------- + void Awake() + { + particles = GetComponent(); + + InvokeRepeating( "CheckParticleSystem", 0.1f, 0.1f ); + } + + + //------------------------------------------------- + private void CheckParticleSystem() + { + if ( !particles.IsAlive() ) + { + Destroy( this.gameObject ); + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnParticleSystemDeath.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnParticleSystemDeath.cs.meta new file mode 100644 index 0000000..75455d2 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnParticleSystemDeath.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 69cad530c565c714491a326c21accb90 +timeCreated: 1478655595 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnTriggerEnter.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnTriggerEnter.cs new file mode 100644 index 0000000..2537d9a --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnTriggerEnter.cs @@ -0,0 +1,38 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Destroys this object when it enters a trigger +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class DestroyOnTriggerEnter : MonoBehaviour + { + public string tagFilter; + + private bool useTag; + + //------------------------------------------------- + void Start() + { + if ( !string.IsNullOrEmpty( tagFilter ) ) + { + useTag = true; + } + } + + + //------------------------------------------------- + void OnTriggerEnter( Collider collider ) + { + if ( !useTag || ( useTag && collider.gameObject.tag == tagFilter ) ) + { + Destroy( collider.gameObject.transform.root.gameObject ); + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnTriggerEnter.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnTriggerEnter.cs.meta new file mode 100644 index 0000000..f5a3152 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/DestroyOnTriggerEnter.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7ba84888c9d4c504cb752a3904551a6c +timeCreated: 1438101498 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/DistanceHaptics.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/DistanceHaptics.cs new file mode 100644 index 0000000..3225ac4 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/DistanceHaptics.cs @@ -0,0 +1,42 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Triggers haptic pulses based on distance between 2 positions +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class DistanceHaptics : MonoBehaviour + { + public Transform firstTransform; + public Transform secondTransform; + + public AnimationCurve distanceIntensityCurve = AnimationCurve.Linear( 0.0f, 800.0f, 1.0f, 800.0f ); + public AnimationCurve pulseIntervalCurve = AnimationCurve.Linear( 0.0f, 0.01f, 1.0f, 0.0f ); + + //------------------------------------------------- + IEnumerator Start() + { + while ( true ) + { + float distance = Vector3.Distance( firstTransform.position, secondTransform.position ); + + SteamVR_TrackedObject trackedObject = GetComponentInParent(); + if ( trackedObject ) + { + float pulse = distanceIntensityCurve.Evaluate( distance ); + SteamVR_Controller.Input( (int)trackedObject.index ).TriggerHapticPulse( (ushort)pulse ); + } + + float nextPulse = pulseIntervalCurve.Evaluate( distance ); + + yield return new WaitForSeconds( nextPulse ); + } + + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/DistanceHaptics.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/DistanceHaptics.cs.meta new file mode 100644 index 0000000..628f9e9 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/DistanceHaptics.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 65ef702aaa09d3f46a75659678b1a711 +timeCreated: 1430871385 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/DontDestroyOnLoad.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/DontDestroyOnLoad.cs new file mode 100644 index 0000000..d266111 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/DontDestroyOnLoad.cs @@ -0,0 +1,21 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: This object won't be destroyed when a new scene is loaded +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class DontDestroyOnLoad : MonoBehaviour + { + //------------------------------------------------- + void Awake() + { + DontDestroyOnLoad( this ); + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/DontDestroyOnLoad.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/DontDestroyOnLoad.cs.meta new file mode 100644 index 0000000..5a196e5 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/DontDestroyOnLoad.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4d1c07a6449b0ca439ee6fac5f6f7d83 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/EnumFlags.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/EnumFlags.cs new file mode 100644 index 0000000..30464aa --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/EnumFlags.cs @@ -0,0 +1,32 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Allows Enums to be shown in the inspector as flags +// +//============================================================================= + +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class EnumFlags : PropertyAttribute + { + public EnumFlags() { } + } + + +#if UNITY_EDITOR + //------------------------------------------------------------------------- + [CustomPropertyDrawer( typeof( EnumFlags ) )] + public class EnumFlagsPropertyDrawer : PropertyDrawer + { + public override void OnGUI( Rect position, SerializedProperty property, GUIContent label ) + { + property.intValue = EditorGUI.MaskField( position, label, property.intValue, property.enumNames ); + } + } +#endif +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/EnumFlags.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/EnumFlags.cs.meta new file mode 100644 index 0000000..756265d --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/EnumFlags.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 88a2ccbdad9948c45b28f5e63902705b +timeCreated: 1440536338 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/FallbackCameraController.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/FallbackCameraController.cs new file mode 100644 index 0000000..73ec74a --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/FallbackCameraController.cs @@ -0,0 +1,96 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Controls for the non-VR debug camera +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( Camera ) )] + public class FallbackCameraController : MonoBehaviour + { + public float speed = 4.0f; + public float shiftSpeed = 16.0f; + public bool showInstructions = true; + + private Vector3 startEulerAngles; + private Vector3 startMousePosition; + private float realTime; + + //------------------------------------------------- + void OnEnable() + { + realTime = Time.realtimeSinceStartup; + } + + + //------------------------------------------------- + void Update() + { + float forward = 0.0f; + if ( Input.GetKey( KeyCode.W ) || Input.GetKey( KeyCode.UpArrow ) ) + { + forward += 1.0f; + } + if ( Input.GetKey( KeyCode.S ) || Input.GetKey( KeyCode.DownArrow ) ) + { + forward -= 1.0f; + } + + float right = 0.0f; + if ( Input.GetKey( KeyCode.D ) || Input.GetKey( KeyCode.RightArrow ) ) + { + right += 1.0f; + } + if ( Input.GetKey( KeyCode.A ) || Input.GetKey( KeyCode.LeftArrow ) ) + { + right -= 1.0f; + } + + float currentSpeed = speed; + if ( Input.GetKey( KeyCode.LeftShift ) || Input.GetKey( KeyCode.RightShift ) ) + { + currentSpeed = shiftSpeed; + } + + float realTimeNow = Time.realtimeSinceStartup; + float deltaRealTime = realTimeNow - realTime; + realTime = realTimeNow; + + Vector3 delta = new Vector3( right, 0.0f, forward ) * currentSpeed * deltaRealTime; + + transform.position += transform.TransformDirection( delta ); + + Vector3 mousePosition = Input.mousePosition; + + if ( Input.GetMouseButtonDown( 1 ) /* right mouse */) + { + startMousePosition = mousePosition; + startEulerAngles = transform.localEulerAngles; + } + + if ( Input.GetMouseButton( 1 ) /* right mouse */) + { + Vector3 offset = mousePosition - startMousePosition; + transform.localEulerAngles = startEulerAngles + new Vector3( -offset.y * 360.0f / Screen.height, offset.x * 360.0f / Screen.width, 0.0f ); + } + } + + + //------------------------------------------------- + void OnGUI() + { + if ( showInstructions ) + { + GUI.Label( new Rect( 10.0f, 10.0f, 600.0f, 400.0f ), + "WASD/Arrow Keys to translate the camera\n" + + "Right mouse click to rotate the camera\n" + + "Left mouse click for standard interactions.\n" ); + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/FallbackCameraController.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/FallbackCameraController.cs.meta new file mode 100644 index 0000000..2748ff8 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/FallbackCameraController.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6043f3be9a21bd74281f9770463bea00 +timeCreated: 1436190027 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/Hand.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/Hand.cs new file mode 100644 index 0000000..024279d --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/Hand.cs @@ -0,0 +1,917 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: The hands used by the player in the vr interaction system +// +//============================================================================= + +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + // Links with an appropriate SteamVR controller and facilitates + // interactions with objects in the virtual world. + //------------------------------------------------------------------------- + public class Hand : MonoBehaviour + { + public enum HandType + { + Left, + Right, + Any + }; + + // The flags used to determine how an object is attached to the hand. + [Flags] + public enum AttachmentFlags + { + SnapOnAttach = 1 << 0, // The object should snap to the position of the specified attachment point on the hand. + DetachOthers = 1 << 1, // Other objects attached to this hand will be detached. + DetachFromOtherHand = 1 << 2, // This object will be detached from the other hand. + ParentToHand = 1 << 3, // The object will be parented to the hand. + }; + + public const AttachmentFlags defaultAttachmentFlags = AttachmentFlags.ParentToHand | + AttachmentFlags.DetachOthers | + AttachmentFlags.DetachFromOtherHand | + AttachmentFlags.SnapOnAttach; + + public Hand otherHand; + public HandType startingHandType; + + public Transform hoverSphereTransform; + public float hoverSphereRadius = 0.05f; + public LayerMask hoverLayerMask = -1; + public float hoverUpdateInterval = 0.1f; + + public Camera noSteamVRFallbackCamera; + public float noSteamVRFallbackMaxDistanceNoItem = 10.0f; + public float noSteamVRFallbackMaxDistanceWithItem = 0.5f; + private float noSteamVRFallbackInteractorDistance = -1.0f; + + public SteamVR_Controller.Device controller; + + public GameObject controllerPrefab; + private GameObject controllerObject = null; + + public bool showDebugText = false; + public bool spewDebugText = false; + + public struct AttachedObject + { + public GameObject attachedObject; + public GameObject originalParent; + public bool isParentedToHand; + } + + private List attachedObjects = new List(); + + public ReadOnlyCollection AttachedObjects + { + get { return attachedObjects.AsReadOnly(); } + } + + public bool hoverLocked { get; private set; } + + private Interactable _hoveringInteractable; + + private TextMesh debugText; + private int prevOverlappingColliders = 0; + + private const int ColliderArraySize = 16; + private Collider[] overlappingColliders; + + private Player playerInstance; + + private GameObject applicationLostFocusObject; + + SteamVR_Events.Action inputFocusAction; + + + //------------------------------------------------- + // The Interactable object this Hand is currently hovering over + //------------------------------------------------- + public Interactable hoveringInteractable + { + get { return _hoveringInteractable; } + set + { + if ( _hoveringInteractable != value ) + { + if ( _hoveringInteractable != null ) + { + HandDebugLog( "HoverEnd " + _hoveringInteractable.gameObject ); + _hoveringInteractable.SendMessage( "OnHandHoverEnd", this, SendMessageOptions.DontRequireReceiver ); + + //Note: The _hoveringInteractable can change after sending the OnHandHoverEnd message so we need to check it again before broadcasting this message + if ( _hoveringInteractable != null ) + { + this.BroadcastMessage( "OnParentHandHoverEnd", _hoveringInteractable, SendMessageOptions.DontRequireReceiver ); // let objects attached to the hand know that a hover has ended + } + } + + _hoveringInteractable = value; + + if ( _hoveringInteractable != null ) + { + HandDebugLog( "HoverBegin " + _hoveringInteractable.gameObject ); + _hoveringInteractable.SendMessage( "OnHandHoverBegin", this, SendMessageOptions.DontRequireReceiver ); + + //Note: The _hoveringInteractable can change after sending the OnHandHoverBegin message so we need to check it again before broadcasting this message + if ( _hoveringInteractable != null ) + { + this.BroadcastMessage( "OnParentHandHoverBegin", _hoveringInteractable, SendMessageOptions.DontRequireReceiver ); // let objects attached to the hand know that a hover has begun + } + } + } + } + } + + + //------------------------------------------------- + // Active GameObject attached to this Hand + //------------------------------------------------- + public GameObject currentAttachedObject + { + get + { + CleanUpAttachedObjectStack(); + + if ( attachedObjects.Count > 0 ) + { + return attachedObjects[attachedObjects.Count - 1].attachedObject; + } + + return null; + } + } + + + //------------------------------------------------- + public Transform GetAttachmentTransform( string attachmentPoint = "" ) + { + Transform attachmentTransform = null; + + if ( !string.IsNullOrEmpty( attachmentPoint ) ) + { + attachmentTransform = transform.Find( attachmentPoint ); + } + + if ( !attachmentTransform ) + { + attachmentTransform = this.transform; + } + + return attachmentTransform; + } + + + //------------------------------------------------- + // Guess the type of this Hand + // + // If startingHandType is Hand.Left or Hand.Right, returns startingHandType. + // If otherHand is non-null and both Hands are linked to controllers, returns + // Hand.Left if this Hand is leftmost relative to the HMD, otherwise Hand.Right. + // Otherwise, returns Hand.Any + //------------------------------------------------- + public HandType GuessCurrentHandType() + { + if ( startingHandType == HandType.Left || startingHandType == HandType.Right ) + { + return startingHandType; + } + + if ( startingHandType == HandType.Any && otherHand != null && otherHand.controller == null ) + { + return HandType.Right; + } + + if ( controller == null || otherHand == null || otherHand.controller == null ) + { + return startingHandType; + } + + if ( controller.index == SteamVR_Controller.GetDeviceIndex( SteamVR_Controller.DeviceRelation.Leftmost ) ) + { + return HandType.Left; + } + + return HandType.Right; + } + + + //------------------------------------------------- + // Attach a GameObject to this GameObject + // + // objectToAttach - The GameObject to attach + // flags - The flags to use for attaching the object + // attachmentPoint - Name of the GameObject in the hierarchy of this Hand which should act as the attachment point for this GameObject + //------------------------------------------------- + public void AttachObject( GameObject objectToAttach, AttachmentFlags flags = defaultAttachmentFlags, string attachmentPoint = "" ) + { + if ( flags == 0 ) + { + flags = defaultAttachmentFlags; + } + + //Make sure top object on stack is non-null + CleanUpAttachedObjectStack(); + + //Detach the object if it is already attached so that it can get re-attached at the top of the stack + DetachObject( objectToAttach ); + + //Detach from the other hand if requested + if ( ( ( flags & AttachmentFlags.DetachFromOtherHand ) == AttachmentFlags.DetachFromOtherHand ) && otherHand ) + { + otherHand.DetachObject( objectToAttach ); + } + + if ( ( flags & AttachmentFlags.DetachOthers ) == AttachmentFlags.DetachOthers ) + { + //Detach all the objects from the stack + while ( attachedObjects.Count > 0 ) + { + DetachObject( attachedObjects[0].attachedObject ); + } + } + + if ( currentAttachedObject ) + { + currentAttachedObject.SendMessage( "OnHandFocusLost", this, SendMessageOptions.DontRequireReceiver ); + } + + AttachedObject attachedObject = new AttachedObject(); + attachedObject.attachedObject = objectToAttach; + attachedObject.originalParent = objectToAttach.transform.parent != null ? objectToAttach.transform.parent.gameObject : null; + if ( ( flags & AttachmentFlags.ParentToHand ) == AttachmentFlags.ParentToHand ) + { + //Parent the object to the hand + objectToAttach.transform.parent = GetAttachmentTransform( attachmentPoint ); + attachedObject.isParentedToHand = true; + } + else + { + attachedObject.isParentedToHand = false; + } + attachedObjects.Add( attachedObject ); + + if ( ( flags & AttachmentFlags.SnapOnAttach ) == AttachmentFlags.SnapOnAttach ) + { + objectToAttach.transform.localPosition = Vector3.zero; + objectToAttach.transform.localRotation = Quaternion.identity; + } + + HandDebugLog( "AttachObject " + objectToAttach ); + objectToAttach.SendMessage( "OnAttachedToHand", this, SendMessageOptions.DontRequireReceiver ); + + UpdateHovering(); + } + + + //------------------------------------------------- + // Detach this GameObject from the attached object stack of this Hand + // + // objectToDetach - The GameObject to detach from this Hand + //------------------------------------------------- + public void DetachObject( GameObject objectToDetach, bool restoreOriginalParent = true ) + { + int index = attachedObjects.FindIndex( l => l.attachedObject == objectToDetach ); + if ( index != -1 ) + { + HandDebugLog( "DetachObject " + objectToDetach ); + + GameObject prevTopObject = currentAttachedObject; + + Transform parentTransform = null; + if ( attachedObjects[index].isParentedToHand ) + { + if ( restoreOriginalParent && ( attachedObjects[index].originalParent != null ) ) + { + parentTransform = attachedObjects[index].originalParent.transform; + } + attachedObjects[index].attachedObject.transform.parent = parentTransform; + } + + attachedObjects[index].attachedObject.SetActive( true ); + attachedObjects[index].attachedObject.SendMessage( "OnDetachedFromHand", this, SendMessageOptions.DontRequireReceiver ); + attachedObjects.RemoveAt( index ); + + GameObject newTopObject = currentAttachedObject; + + //Give focus to the top most object on the stack if it changed + if ( newTopObject != null && newTopObject != prevTopObject ) + { + newTopObject.SetActive( true ); + newTopObject.SendMessage( "OnHandFocusAcquired", this, SendMessageOptions.DontRequireReceiver ); + } + } + + CleanUpAttachedObjectStack(); + } + + + //------------------------------------------------- + // Get the world velocity of the VR Hand. + // Note: controller velocity value only updates on controller events (Button but and down) so good for throwing + //------------------------------------------------- + public Vector3 GetTrackedObjectVelocity() + { + if ( controller != null ) + { + return transform.parent.TransformVector( controller.velocity ); + } + + return Vector3.zero; + } + + + //------------------------------------------------- + // Get the world angular velocity of the VR Hand. + // Note: controller velocity value only updates on controller events (Button but and down) so good for throwing + //------------------------------------------------- + public Vector3 GetTrackedObjectAngularVelocity() + { + if ( controller != null ) + { + return transform.parent.TransformVector( controller.angularVelocity ); + } + + return Vector3.zero; + } + + + //------------------------------------------------- + private void CleanUpAttachedObjectStack() + { + attachedObjects.RemoveAll( l => l.attachedObject == null ); + } + + + //------------------------------------------------- + void Awake() + { + inputFocusAction = SteamVR_Events.InputFocusAction( OnInputFocus ); + + if ( hoverSphereTransform == null ) + { + hoverSphereTransform = this.transform; + } + + applicationLostFocusObject = new GameObject( "_application_lost_focus" ); + applicationLostFocusObject.transform.parent = transform; + applicationLostFocusObject.SetActive( false ); + } + + + //------------------------------------------------- + IEnumerator Start() + { + // save off player instance + playerInstance = Player.instance; + if ( !playerInstance ) + { + Debug.LogError( "No player instance found in Hand Start()" ); + } + + // allocate array for colliders + overlappingColliders = new Collider[ColliderArraySize]; + + // We are a "no SteamVR fallback hand" if we have this camera set + // we'll use the right mouse to look around and left mouse to interact + // - don't need to find the device + if ( noSteamVRFallbackCamera ) + { + yield break; + } + + //Debug.Log( "Hand - initializing connection routine" ); + + // Acquire the correct device index for the hand we want to be + // Also for the other hand if we get there first + while ( true ) + { + // Don't need to run this every frame + yield return new WaitForSeconds( 1.0f ); + + // We have a controller now, break out of the loop! + if ( controller != null ) + break; + + //Debug.Log( "Hand - checking controllers..." ); + + // Initialize both hands simultaneously + if ( startingHandType == HandType.Left || startingHandType == HandType.Right ) + { + // Left/right relationship. + // Wait until we have a clear unique left-right relationship to initialize. + int leftIndex = SteamVR_Controller.GetDeviceIndex( SteamVR_Controller.DeviceRelation.Leftmost ); + int rightIndex = SteamVR_Controller.GetDeviceIndex( SteamVR_Controller.DeviceRelation.Rightmost ); + if ( leftIndex == -1 || rightIndex == -1 || leftIndex == rightIndex ) + { + //Debug.Log( string.Format( "...Left/right hand relationship not yet established: leftIndex={0}, rightIndex={1}", leftIndex, rightIndex ) ); + continue; + } + + int myIndex = ( startingHandType == HandType.Right ) ? rightIndex : leftIndex; + int otherIndex = ( startingHandType == HandType.Right ) ? leftIndex : rightIndex; + + InitController( myIndex ); + if ( otherHand ) + { + otherHand.InitController( otherIndex ); + } + } + else + { + // No left/right relationship. Just wait for a connection + + var vr = SteamVR.instance; + for ( int i = 0; i < Valve.VR.OpenVR.k_unMaxTrackedDeviceCount; i++ ) + { + if ( vr.hmd.GetTrackedDeviceClass( (uint)i ) != Valve.VR.ETrackedDeviceClass.Controller ) + { + //Debug.Log( string.Format( "Hand - device {0} is not a controller", i ) ); + continue; + } + + var device = SteamVR_Controller.Input( i ); + if ( !device.valid ) + { + //Debug.Log( string.Format( "Hand - device {0} is not valid", i ) ); + continue; + } + + if ( ( otherHand != null ) && ( otherHand.controller != null ) ) + { + // Other hand is using this index, so we cannot use it. + if ( i == (int)otherHand.controller.index ) + { + //Debug.Log( string.Format( "Hand - device {0} is owned by the other hand", i ) ); + continue; + } + } + + InitController( i ); + } + } + } + } + + + //------------------------------------------------- + private void UpdateHovering() + { + if ( ( noSteamVRFallbackCamera == null ) && ( controller == null ) ) + { + return; + } + + if ( hoverLocked ) + return; + + if ( applicationLostFocusObject.activeSelf ) + return; + + float closestDistance = float.MaxValue; + Interactable closestInteractable = null; + + // Pick the closest hovering + float flHoverRadiusScale = playerInstance.transform.lossyScale.x; + float flScaledSphereRadius = hoverSphereRadius * flHoverRadiusScale; + + // if we're close to the floor, increase the radius to make things easier to pick up + float handDiff = Mathf.Abs( transform.position.y - playerInstance.trackingOriginTransform.position.y ); + float boxMult = Util.RemapNumberClamped( handDiff, 0.0f, 0.5f * flHoverRadiusScale, 5.0f, 1.0f ) * flHoverRadiusScale; + + // null out old vals + for ( int i = 0; i < overlappingColliders.Length; ++i ) + { + overlappingColliders[i] = null; + } + + Physics.OverlapBoxNonAlloc( + hoverSphereTransform.position - new Vector3( 0, flScaledSphereRadius * boxMult - flScaledSphereRadius, 0 ), + new Vector3( flScaledSphereRadius, flScaledSphereRadius * boxMult * 2.0f, flScaledSphereRadius ), + overlappingColliders, + Quaternion.identity, + hoverLayerMask.value + ); + + // DebugVar + int iActualColliderCount = 0; + + foreach ( Collider collider in overlappingColliders ) + { + if ( collider == null ) + continue; + + Interactable contacting = collider.GetComponentInParent(); + + // Yeah, it's null, skip + if ( contacting == null ) + continue; + + // Ignore this collider for hovering + IgnoreHovering ignore = collider.GetComponent(); + if ( ignore != null ) + { + if ( ignore.onlyIgnoreHand == null || ignore.onlyIgnoreHand == this ) + { + continue; + } + } + + // Can't hover over the object if it's attached + if ( attachedObjects.FindIndex( l => l.attachedObject == contacting.gameObject ) != -1 ) + continue; + + // Occupied by another hand, so we can't touch it + if ( otherHand && otherHand.hoveringInteractable == contacting ) + continue; + + // Best candidate so far... + float distance = Vector3.Distance( contacting.transform.position, hoverSphereTransform.position ); + if ( distance < closestDistance ) + { + closestDistance = distance; + closestInteractable = contacting; + } + iActualColliderCount++; + } + + // Hover on this one + hoveringInteractable = closestInteractable; + + if ( iActualColliderCount > 0 && iActualColliderCount != prevOverlappingColliders ) + { + prevOverlappingColliders = iActualColliderCount; + HandDebugLog( "Found " + iActualColliderCount + " overlapping colliders." ); + } + } + + + //------------------------------------------------- + private void UpdateNoSteamVRFallback() + { + if ( noSteamVRFallbackCamera ) + { + Ray ray = noSteamVRFallbackCamera.ScreenPointToRay( Input.mousePosition ); + + if ( attachedObjects.Count > 0 ) + { + // Holding down the mouse: + // move around a fixed distance from the camera + transform.position = ray.origin + noSteamVRFallbackInteractorDistance * ray.direction; + } + else + { + // Not holding down the mouse: + // cast out a ray to see what we should mouse over + + // Don't want to hit the hand and anything underneath it + // So move it back behind the camera when we do the raycast + Vector3 oldPosition = transform.position; + transform.position = noSteamVRFallbackCamera.transform.forward * ( -1000.0f ); + + RaycastHit raycastHit; + if ( Physics.Raycast( ray, out raycastHit, noSteamVRFallbackMaxDistanceNoItem ) ) + { + transform.position = raycastHit.point; + + // Remember this distance in case we click and drag the mouse + noSteamVRFallbackInteractorDistance = Mathf.Min( noSteamVRFallbackMaxDistanceNoItem, raycastHit.distance ); + } + else if ( noSteamVRFallbackInteractorDistance > 0.0f ) + { + // Move it around at the distance we last had a hit + transform.position = ray.origin + Mathf.Min( noSteamVRFallbackMaxDistanceNoItem, noSteamVRFallbackInteractorDistance ) * ray.direction; + } + else + { + // Didn't hit, just leave it where it was + transform.position = oldPosition; + } + } + } + } + + + //------------------------------------------------- + private void UpdateDebugText() + { + if ( showDebugText ) + { + if ( debugText == null ) + { + debugText = new GameObject( "_debug_text" ).AddComponent(); + debugText.fontSize = 120; + debugText.characterSize = 0.001f; + debugText.transform.parent = transform; + + debugText.transform.localRotation = Quaternion.Euler( 90.0f, 0.0f, 0.0f ); + } + + if ( GuessCurrentHandType() == HandType.Right ) + { + debugText.transform.localPosition = new Vector3( -0.05f, 0.0f, 0.0f ); + debugText.alignment = TextAlignment.Right; + debugText.anchor = TextAnchor.UpperRight; + } + else + { + debugText.transform.localPosition = new Vector3( 0.05f, 0.0f, 0.0f ); + debugText.alignment = TextAlignment.Left; + debugText.anchor = TextAnchor.UpperLeft; + } + + debugText.text = string.Format( + "Hovering: {0}\n" + + "Hover Lock: {1}\n" + + "Attached: {2}\n" + + "Total Attached: {3}\n" + + "Type: {4}\n", + ( hoveringInteractable ? hoveringInteractable.gameObject.name : "null" ), + hoverLocked, + ( currentAttachedObject ? currentAttachedObject.name : "null" ), + attachedObjects.Count, + GuessCurrentHandType().ToString() ); + } + else + { + if ( debugText != null ) + { + Destroy( debugText.gameObject ); + } + } + } + + + //------------------------------------------------- + void OnEnable() + { + inputFocusAction.enabled = true; + + // Stagger updates between hands + float hoverUpdateBegin = ( ( otherHand != null ) && ( otherHand.GetInstanceID() < GetInstanceID() ) ) ? ( 0.5f * hoverUpdateInterval ) : ( 0.0f ); + InvokeRepeating( "UpdateHovering", hoverUpdateBegin, hoverUpdateInterval ); + InvokeRepeating( "UpdateDebugText", hoverUpdateBegin, hoverUpdateInterval ); + } + + + //------------------------------------------------- + void OnDisable() + { + inputFocusAction.enabled = false; + + CancelInvoke(); + } + + + //------------------------------------------------- + void Update() + { + UpdateNoSteamVRFallback(); + + GameObject attached = currentAttachedObject; + if ( attached ) + { + attached.SendMessage( "HandAttachedUpdate", this, SendMessageOptions.DontRequireReceiver ); + } + + if ( hoveringInteractable ) + { + hoveringInteractable.SendMessage( "HandHoverUpdate", this, SendMessageOptions.DontRequireReceiver ); + } + } + + + //------------------------------------------------- + void LateUpdate() + { + //Re-attach the controller if nothing else is attached to the hand + if ( controllerObject != null && attachedObjects.Count == 0 ) + { + AttachObject( controllerObject ); + } + } + + + //------------------------------------------------- + private void OnInputFocus( bool hasFocus ) + { + if ( hasFocus ) + { + DetachObject( applicationLostFocusObject, true ); + applicationLostFocusObject.SetActive( false ); + UpdateHandPoses(); + UpdateHovering(); + BroadcastMessage( "OnParentHandInputFocusAcquired", SendMessageOptions.DontRequireReceiver ); + } + else + { + applicationLostFocusObject.SetActive( true ); + AttachObject( applicationLostFocusObject, AttachmentFlags.ParentToHand ); + BroadcastMessage( "OnParentHandInputFocusLost", SendMessageOptions.DontRequireReceiver ); + } + } + + + //------------------------------------------------- + void FixedUpdate() + { + UpdateHandPoses(); + } + + + //------------------------------------------------- + void OnDrawGizmos() + { + Gizmos.color = new Color( 0.5f, 1.0f, 0.5f, 0.9f ); + Transform sphereTransform = hoverSphereTransform ? hoverSphereTransform : this.transform; + Gizmos.DrawWireSphere( sphereTransform.position, hoverSphereRadius ); + } + + + //------------------------------------------------- + private void HandDebugLog( string msg ) + { + if ( spewDebugText ) + { + Debug.Log( "Hand (" + this.name + "): " + msg ); + } + } + + + //------------------------------------------------- + private void UpdateHandPoses() + { + if ( controller != null ) + { + SteamVR vr = SteamVR.instance; + if ( vr != null ) + { + var pose = new Valve.VR.TrackedDevicePose_t(); + var gamePose = new Valve.VR.TrackedDevicePose_t(); + var err = vr.compositor.GetLastPoseForTrackedDeviceIndex( controller.index, ref pose, ref gamePose ); + if ( err == Valve.VR.EVRCompositorError.None ) + { + var t = new SteamVR_Utils.RigidTransform( gamePose.mDeviceToAbsoluteTracking ); + transform.localPosition = t.pos; + transform.localRotation = t.rot; + } + } + } + } + + + //------------------------------------------------- + // Continue to hover over this object indefinitely, whether or not the Hand moves out of its interaction trigger volume. + // + // interactable - The Interactable to hover over indefinitely. + //------------------------------------------------- + public void HoverLock( Interactable interactable ) + { + HandDebugLog( "HoverLock " + interactable ); + hoverLocked = true; + hoveringInteractable = interactable; + } + + + //------------------------------------------------- + // Stop hovering over this object indefinitely. + // + // interactable - The hover-locked Interactable to stop hovering over indefinitely. + //------------------------------------------------- + public void HoverUnlock( Interactable interactable ) + { + HandDebugLog( "HoverUnlock " + interactable ); + if ( hoveringInteractable == interactable ) + { + hoverLocked = false; + } + } + + //------------------------------------------------- + // Was the standard interaction button just pressed? In VR, this is a trigger press. In 2D fallback, this is a mouse left-click. + //------------------------------------------------- + public bool GetStandardInteractionButtonDown() + { + if ( noSteamVRFallbackCamera ) + { + return Input.GetMouseButtonDown( 0 ); + } + else if ( controller != null ) + { + return controller.GetHairTriggerDown(); + } + + return false; + } + + + //------------------------------------------------- + // Was the standard interaction button just released? In VR, this is a trigger press. In 2D fallback, this is a mouse left-click. + //------------------------------------------------- + public bool GetStandardInteractionButtonUp() + { + if ( noSteamVRFallbackCamera ) + { + return Input.GetMouseButtonUp( 0 ); + } + else if ( controller != null ) + { + return controller.GetHairTriggerUp(); + } + + return false; + } + + + //------------------------------------------------- + // Is the standard interaction button being pressed? In VR, this is a trigger press. In 2D fallback, this is a mouse left-click. + //------------------------------------------------- + public bool GetStandardInteractionButton() + { + if ( noSteamVRFallbackCamera ) + { + return Input.GetMouseButton( 0 ); + } + else if ( controller != null ) + { + return controller.GetHairTrigger(); + } + + return false; + } + + + //------------------------------------------------- + private void InitController( int index ) + { + if ( controller == null ) + { + controller = SteamVR_Controller.Input( index ); + + HandDebugLog( "Hand " + name + " connected with device index " + controller.index ); + + controllerObject = GameObject.Instantiate( controllerPrefab ); + controllerObject.SetActive( true ); + controllerObject.name = controllerPrefab.name + "_" + this.name; + controllerObject.layer = gameObject.layer; + controllerObject.tag = gameObject.tag; + AttachObject( controllerObject ); + controller.TriggerHapticPulse( 800 ); + + // If the player's scale has been changed the object to attach will be the wrong size. + // To fix this we change the object's scale back to its original, pre-attach scale. + controllerObject.transform.localScale = controllerPrefab.transform.localScale; + + this.BroadcastMessage( "OnHandInitialized", index, SendMessageOptions.DontRequireReceiver ); // let child objects know we've initialized + } + } + } + +#if UNITY_EDITOR + //------------------------------------------------------------------------- + [UnityEditor.CustomEditor( typeof( Hand ) )] + public class HandEditor : UnityEditor.Editor + { + //------------------------------------------------- + // Custom Inspector GUI allows us to click from within the UI + //------------------------------------------------- + public override void OnInspectorGUI() + { + DrawDefaultInspector(); + + Hand hand = (Hand)target; + + if ( hand.otherHand ) + { + if ( hand.otherHand.otherHand != hand ) + { + UnityEditor.EditorGUILayout.HelpBox( "The otherHand of this Hand's otherHand is not this Hand.", UnityEditor.MessageType.Warning ); + } + + if ( hand.startingHandType == Hand.HandType.Left && hand.otherHand.startingHandType != Hand.HandType.Right ) + { + UnityEditor.EditorGUILayout.HelpBox( "This is a left Hand but otherHand is not a right Hand.", UnityEditor.MessageType.Warning ); + } + + if ( hand.startingHandType == Hand.HandType.Right && hand.otherHand.startingHandType != Hand.HandType.Left ) + { + UnityEditor.EditorGUILayout.HelpBox( "This is a right Hand but otherHand is not a left Hand.", UnityEditor.MessageType.Warning ); + } + + if ( hand.startingHandType == Hand.HandType.Any && hand.otherHand.startingHandType != Hand.HandType.Any ) + { + UnityEditor.EditorGUILayout.HelpBox( "This is an any-handed Hand but otherHand is not an any-handed Hand.", UnityEditor.MessageType.Warning ); + } + } + } + } +#endif +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/Hand.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/Hand.cs.meta new file mode 100644 index 0000000..ab2575c --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/Hand.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 29e3e4511966ba94d8ba0b98c6c62f82 +timeCreated: 1484266511 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/HapticRack.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/HapticRack.cs new file mode 100644 index 0000000..7f32725 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/HapticRack.cs @@ -0,0 +1,83 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Triggers haptic pulses based on a linear mapping +// +//============================================================================= + +using UnityEngine; +using UnityEngine.Events; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( Interactable ) )] + public class HapticRack : MonoBehaviour + { + [Tooltip( "The linear mapping driving the haptic rack" )] + public LinearMapping linearMapping; + + [Tooltip( "The number of haptic pulses evenly distributed along the mapping" )] + public int teethCount = 128; + + [Tooltip( "Minimum duration of the haptic pulse" )] + public int minimumPulseDuration = 500; + + [Tooltip( "Maximum duration of the haptic pulse" )] + public int maximumPulseDuration = 900; + + [Tooltip( "This event is triggered every time a haptic pulse is made" )] + public UnityEvent onPulse; + + private Hand hand; + private int previousToothIndex = -1; + + //------------------------------------------------- + void Awake() + { + if ( linearMapping == null ) + { + linearMapping = GetComponent(); + } + } + + + //------------------------------------------------- + private void OnHandHoverBegin( Hand hand ) + { + this.hand = hand; + } + + + //------------------------------------------------- + private void OnHandHoverEnd( Hand hand ) + { + this.hand = null; + } + + + //------------------------------------------------- + void Update() + { + int currentToothIndex = Mathf.RoundToInt( linearMapping.value * teethCount - 0.5f ); + if ( currentToothIndex != previousToothIndex ) + { + Pulse(); + previousToothIndex = currentToothIndex; + } + } + + + //------------------------------------------------- + private void Pulse() + { + if ( hand && ( hand.controller != null ) && ( hand.GetStandardInteractionButton() ) ) + { + ushort duration = (ushort)Random.Range( minimumPulseDuration, maximumPulseDuration + 1 ); + hand.controller.TriggerHapticPulse( duration ); + + onPulse.Invoke(); + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/HapticRack.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/HapticRack.cs.meta new file mode 100644 index 0000000..a1b9456 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/HapticRack.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 817521c5973e4ee45905ee97df3c38ad +timeCreated: 1433796170 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/HideOnHandFocusLost.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/HideOnHandFocusLost.cs new file mode 100644 index 0000000..9d3b138 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/HideOnHandFocusLost.cs @@ -0,0 +1,21 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Sets this GameObject as inactive when it loses focus from the hand +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class HideOnHandFocusLost : MonoBehaviour + { + //------------------------------------------------- + private void OnHandFocusLost( Hand hand ) + { + gameObject.SetActive( false ); + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/HideOnHandFocusLost.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/HideOnHandFocusLost.cs.meta new file mode 100644 index 0000000..9987d49 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/HideOnHandFocusLost.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: eb6d6653511aff5409d0827d4e3b79ea +timeCreated: 1439254899 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/IgnoreHovering.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/IgnoreHovering.cs new file mode 100644 index 0000000..7daa798 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/IgnoreHovering.cs @@ -0,0 +1,17 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Makes this object ignore any hovering by the hands +// +//============================================================================= + +using UnityEngine; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class IgnoreHovering : MonoBehaviour + { + [Tooltip( "If Hand is not null, only ignore the specified hand" )] + public Hand onlyIgnoreHand = null; + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/IgnoreHovering.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/IgnoreHovering.cs.meta new file mode 100644 index 0000000..9ce1636 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/IgnoreHovering.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f5a1be5da1c87864582d778e52de4e9b +timeCreated: 1444166650 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/InputModule.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/InputModule.cs new file mode 100644 index 0000000..ce97a31 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/InputModule.cs @@ -0,0 +1,79 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Makes the hand act as an input module for Unity's event system +// +//============================================================================= + +using UnityEngine; +using System.Collections; +using UnityEngine.EventSystems; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class InputModule : BaseInputModule + { + private GameObject submitObject; + + //------------------------------------------------- + private static InputModule _instance; + public static InputModule instance + { + get + { + if ( _instance == null ) + _instance = GameObject.FindObjectOfType(); + + return _instance; + } + } + + + //------------------------------------------------- + public override bool ShouldActivateModule() + { + if ( !base.ShouldActivateModule() ) + return false; + + return submitObject != null; + } + + + //------------------------------------------------- + public void HoverBegin( GameObject gameObject ) + { + PointerEventData pointerEventData = new PointerEventData( eventSystem ); + ExecuteEvents.Execute( gameObject, pointerEventData, ExecuteEvents.pointerEnterHandler ); + } + + + //------------------------------------------------- + public void HoverEnd( GameObject gameObject ) + { + PointerEventData pointerEventData = new PointerEventData( eventSystem ); + pointerEventData.selectedObject = null; + ExecuteEvents.Execute( gameObject, pointerEventData, ExecuteEvents.pointerExitHandler ); + } + + + //------------------------------------------------- + public void Submit( GameObject gameObject ) + { + submitObject = gameObject; + } + + + //------------------------------------------------- + public override void Process() + { + if ( submitObject ) + { + BaseEventData data = GetBaseEventData(); + data.selectedObject = submitObject; + ExecuteEvents.Execute( submitObject, data, ExecuteEvents.submitHandler ); + + submitObject = null; + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/InputModule.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/InputModule.cs.meta new file mode 100644 index 0000000..b8bc916 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/InputModule.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c9e05292e0d62b542ac5bba92674a86d +timeCreated: 1429055028 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/Interactable.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/Interactable.cs new file mode 100644 index 0000000..b355011 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/Interactable.cs @@ -0,0 +1,43 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: This object will get hover events and can be attached to the hands +// +//============================================================================= + +using UnityEngine; +using UnityEngine.Events; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class Interactable : MonoBehaviour + { + public delegate void OnAttachedToHandDelegate( Hand hand ); + public delegate void OnDetachedFromHandDelegate( Hand hand ); + + [HideInInspector] + public event OnAttachedToHandDelegate onAttachedToHand; + [HideInInspector] + public event OnDetachedFromHandDelegate onDetachedFromHand; + + //------------------------------------------------- + private void OnAttachedToHand( Hand hand ) + { + if ( onAttachedToHand != null ) + { + onAttachedToHand.Invoke( hand ); + } + } + + + //------------------------------------------------- + private void OnDetachedFromHand( Hand hand ) + { + if ( onDetachedFromHand != null ) + { + onDetachedFromHand.Invoke( hand ); + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/Interactable.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/Interactable.cs.meta new file mode 100644 index 0000000..ea4b7d4 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/Interactable.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b93b6a877adcbf94c89a9d6e0c0e844d +timeCreated: 1430943024 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/InteractableButtonEvents.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/InteractableButtonEvents.cs new file mode 100644 index 0000000..67a3719 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/InteractableButtonEvents.cs @@ -0,0 +1,78 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Sends simple controller button events to UnityEvents +// +//============================================================================= + +using UnityEngine; +using UnityEngine.Events; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( Interactable ) )] + public class InteractableButtonEvents : MonoBehaviour + { + public UnityEvent onTriggerDown; + public UnityEvent onTriggerUp; + public UnityEvent onGripDown; + public UnityEvent onGripUp; + public UnityEvent onTouchpadDown; + public UnityEvent onTouchpadUp; + public UnityEvent onTouchpadTouch; + public UnityEvent onTouchpadRelease; + + //------------------------------------------------- + void Update() + { + for ( int i = 0; i < Player.instance.handCount; i++ ) + { + Hand hand = Player.instance.GetHand( i ); + + if ( hand.controller != null ) + { + if ( hand.controller.GetPressDown( Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger ) ) + { + onTriggerDown.Invoke(); + } + + if ( hand.controller.GetPressUp( Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger ) ) + { + onTriggerUp.Invoke(); + } + + if ( hand.controller.GetPressDown( Valve.VR.EVRButtonId.k_EButton_Grip ) ) + { + onGripDown.Invoke(); + } + + if ( hand.controller.GetPressUp( Valve.VR.EVRButtonId.k_EButton_Grip ) ) + { + onGripUp.Invoke(); + } + + if ( hand.controller.GetPressDown( Valve.VR.EVRButtonId.k_EButton_SteamVR_Touchpad ) ) + { + onTouchpadDown.Invoke(); + } + + if ( hand.controller.GetPressUp( Valve.VR.EVRButtonId.k_EButton_SteamVR_Touchpad ) ) + { + onTouchpadUp.Invoke(); + } + + if ( hand.controller.GetTouchDown( Valve.VR.EVRButtonId.k_EButton_SteamVR_Touchpad ) ) + { + onTouchpadTouch.Invoke(); + } + + if ( hand.controller.GetTouchUp( Valve.VR.EVRButtonId.k_EButton_SteamVR_Touchpad ) ) + { + onTouchpadRelease.Invoke(); + } + } + } + + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/InteractableButtonEvents.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/InteractableButtonEvents.cs.meta new file mode 100644 index 0000000..2b9c6a0 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/InteractableButtonEvents.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6948c755e9613734dbac166d770c8e3e +timeCreated: 1435876320 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/InteractableHoverEvents.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/InteractableHoverEvents.cs new file mode 100644 index 0000000..4102d07 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/InteractableHoverEvents.cs @@ -0,0 +1,49 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Sends UnityEvents for basic hand interactions +// +//============================================================================= + +using UnityEngine; +using UnityEngine.Events; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( Interactable ) )] + public class InteractableHoverEvents : MonoBehaviour + { + public UnityEvent onHandHoverBegin; + public UnityEvent onHandHoverEnd; + public UnityEvent onAttachedToHand; + public UnityEvent onDetachedFromHand; + + //------------------------------------------------- + private void OnHandHoverBegin() + { + onHandHoverBegin.Invoke(); + } + + + //------------------------------------------------- + private void OnHandHoverEnd() + { + onHandHoverEnd.Invoke(); + } + + + //------------------------------------------------- + private void OnAttachedToHand( Hand hand ) + { + onAttachedToHand.Invoke(); + } + + + //------------------------------------------------- + private void OnDetachedFromHand( Hand hand ) + { + onDetachedFromHand.Invoke(); + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/InteractableHoverEvents.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/InteractableHoverEvents.cs.meta new file mode 100644 index 0000000..ee592eb --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/InteractableHoverEvents.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c4153b26428ccf041950b92c057812a3 +timeCreated: 1432689386 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackage.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackage.cs new file mode 100644 index 0000000..cbf28fe --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackage.cs @@ -0,0 +1,24 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: A package of items that can interact with the hands and be returned +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class ItemPackage : MonoBehaviour + { + public enum ItemPackageType { Unrestricted, OneHanded, TwoHanded } + + public new string name; + public ItemPackageType packageType = ItemPackageType.Unrestricted; + public GameObject itemPrefab; // object to be spawned on tracked controller + public GameObject otherHandItemPrefab; // object to be spawned in Other Hand + public GameObject previewPrefab; // used to preview inputObject + public GameObject fadedPreviewPrefab; // used to preview insubstantial inputObject + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackage.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackage.cs.meta new file mode 100644 index 0000000..edda282 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackage.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c9f83db71b9a6764abf964ab7679f035 +timeCreated: 1436836633 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackageReference.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackageReference.cs new file mode 100644 index 0000000..ed4cdd2 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackageReference.cs @@ -0,0 +1,17 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Keeps track of the ItemPackage this object is a part of +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class ItemPackageReference : MonoBehaviour + { + public ItemPackage itemPackage; + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackageReference.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackageReference.cs.meta new file mode 100644 index 0000000..7141b1d --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackageReference.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 57468e6cbae21894fa42c90413c294ff +timeCreated: 1436997098 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackageSpawner.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackageSpawner.cs new file mode 100644 index 0000000..bf81192 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackageSpawner.cs @@ -0,0 +1,361 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Handles the spawning and returning of the ItemPackage +// +//============================================================================= + +using UnityEngine; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using UnityEngine.Events; +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( Interactable ) )] + public class ItemPackageSpawner : MonoBehaviour + { + public ItemPackage itemPackage + { + get + { + return _itemPackage; + } + set + { + CreatePreviewObject(); + } + } + + public ItemPackage _itemPackage; + + private bool useItemPackagePreview = true; + private bool useFadedPreview = false; + private GameObject previewObject; + + public bool requireTriggerPressToTake = false; + public bool requireTriggerPressToReturn = false; + public bool showTriggerHint = false; + + [EnumFlags] + public Hand.AttachmentFlags attachmentFlags = Hand.defaultAttachmentFlags; + public string attachmentPoint; + + public bool takeBackItem = false; // if a hand enters this trigger and has the item this spawner dispenses at the top of the stack, remove it from the stack + + public bool acceptDifferentItems = false; + + private GameObject spawnedItem; + private bool itemIsSpawned = false; + + public UnityEvent pickupEvent; + public UnityEvent dropEvent; + + public bool justPickedUpItem = false; + + + //------------------------------------------------- + private void CreatePreviewObject() + { + if ( !useItemPackagePreview ) + { + return; + } + + ClearPreview(); + + if ( useItemPackagePreview ) + { + if ( itemPackage == null ) + { + return; + } + + if ( useFadedPreview == false ) // if we don't have a spawned item out there, use the regular preview + { + if ( itemPackage.previewPrefab != null ) + { + previewObject = Instantiate( itemPackage.previewPrefab, transform.position, Quaternion.identity ) as GameObject; + previewObject.transform.parent = transform; + previewObject.transform.localRotation = Quaternion.identity; + } + } + else // there's a spawned item out there. Use the faded preview + { + if ( itemPackage.fadedPreviewPrefab != null ) + { + previewObject = Instantiate( itemPackage.fadedPreviewPrefab, transform.position, Quaternion.identity ) as GameObject; + previewObject.transform.parent = transform; + previewObject.transform.localRotation = Quaternion.identity; + } + } + } + } + + + //------------------------------------------------- + void Start() + { + VerifyItemPackage(); + } + + + //------------------------------------------------- + private void VerifyItemPackage() + { + if ( itemPackage == null ) + { + ItemPackageNotValid(); + } + + if ( itemPackage.itemPrefab == null ) + { + ItemPackageNotValid(); + } + } + + + //------------------------------------------------- + private void ItemPackageNotValid() + { + Debug.LogError( "ItemPackage assigned to " + gameObject.name + " is not valid. Destroying this game object." ); + Destroy( gameObject ); + } + + + //------------------------------------------------- + private void ClearPreview() + { + foreach ( Transform child in transform ) + { + if ( Time.time > 0 ) + { + GameObject.Destroy( child.gameObject ); + } + else + { + GameObject.DestroyImmediate( child.gameObject ); + } + } + } + + + //------------------------------------------------- + void Update() + { + if ( ( itemIsSpawned == true ) && ( spawnedItem == null ) ) + { + itemIsSpawned = false; + useFadedPreview = false; + dropEvent.Invoke(); + CreatePreviewObject(); + } + } + + + //------------------------------------------------- + private void OnHandHoverBegin( Hand hand ) + { + ItemPackage currentAttachedItemPackage = GetAttachedItemPackage( hand ); + + if ( currentAttachedItemPackage == itemPackage ) // the item at the top of the hand's stack has an associated ItemPackage + { + if ( takeBackItem && !requireTriggerPressToReturn ) // if we want to take back matching items and aren't waiting for a trigger press + { + TakeBackItem( hand ); + } + } + + if ( !requireTriggerPressToTake ) // we don't require trigger press for pickup. Spawn and attach object. + { + SpawnAndAttachObject( hand ); + } + + if ( requireTriggerPressToTake && showTriggerHint ) + { + ControllerButtonHints.ShowTextHint( hand, Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger, "PickUp" ); + } + } + + + //------------------------------------------------- + private void TakeBackItem( Hand hand ) + { + RemoveMatchingItemsFromHandStack( itemPackage, hand ); + + if ( itemPackage.packageType == ItemPackage.ItemPackageType.TwoHanded ) + { + RemoveMatchingItemsFromHandStack( itemPackage, hand.otherHand ); + } + } + + + //------------------------------------------------- + private ItemPackage GetAttachedItemPackage( Hand hand ) + { + GameObject currentAttachedObject = hand.currentAttachedObject; + + if ( currentAttachedObject == null ) // verify the hand is holding something + { + return null; + } + + ItemPackageReference packageReference = hand.currentAttachedObject.GetComponent(); + if ( packageReference == null ) // verify the item in the hand is matchable + { + return null; + } + + ItemPackage attachedItemPackage = packageReference.itemPackage; // return the ItemPackage reference we find. + + return attachedItemPackage; + } + + + //------------------------------------------------- + private void HandHoverUpdate( Hand hand ) + { + if ( takeBackItem && requireTriggerPressToReturn ) + { + if ( hand.controller != null && hand.controller.GetHairTriggerDown() ) + { + ItemPackage currentAttachedItemPackage = GetAttachedItemPackage( hand ); + if ( currentAttachedItemPackage == itemPackage ) + { + TakeBackItem( hand ); + return; // So that we don't pick up an ItemPackage the same frame that we return it + } + } + } + + if ( requireTriggerPressToTake ) + { + if ( hand.controller != null && hand.controller.GetHairTriggerDown() ) + { + SpawnAndAttachObject( hand ); + } + } + } + + + //------------------------------------------------- + private void OnHandHoverEnd( Hand hand ) + { + if ( !justPickedUpItem && requireTriggerPressToTake && showTriggerHint ) + { + ControllerButtonHints.HideTextHint( hand, Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger ); + } + + justPickedUpItem = false; + } + + + //------------------------------------------------- + private void RemoveMatchingItemsFromHandStack( ItemPackage package, Hand hand ) + { + for ( int i = 0; i < hand.AttachedObjects.Count; i++ ) + { + ItemPackageReference packageReference = hand.AttachedObjects[i].attachedObject.GetComponent(); + if ( packageReference != null ) + { + ItemPackage attachedObjectItemPackage = packageReference.itemPackage; + if ( ( attachedObjectItemPackage != null ) && ( attachedObjectItemPackage == package ) ) + { + GameObject detachedItem = hand.AttachedObjects[i].attachedObject; + hand.DetachObject( detachedItem ); + } + } + } + } + + + //------------------------------------------------- + private void RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType packageType, Hand hand ) + { + for ( int i = 0; i < hand.AttachedObjects.Count; i++ ) + { + ItemPackageReference packageReference = hand.AttachedObjects[i].attachedObject.GetComponent(); + if ( packageReference != null ) + { + if ( packageReference.itemPackage.packageType == packageType ) + { + GameObject detachedItem = hand.AttachedObjects[i].attachedObject; + hand.DetachObject( detachedItem ); + } + } + } + } + + + //------------------------------------------------- + private void SpawnAndAttachObject( Hand hand ) + { + if ( hand.otherHand != null ) + { + //If the other hand has this item package, take it back from the other hand + ItemPackage otherHandItemPackage = GetAttachedItemPackage( hand.otherHand ); + if ( otherHandItemPackage == itemPackage ) + { + TakeBackItem( hand.otherHand ); + } + } + + if ( showTriggerHint ) + { + ControllerButtonHints.HideTextHint( hand, Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger ); + } + + if ( itemPackage.otherHandItemPrefab != null ) + { + if ( hand.otherHand.hoverLocked ) + { + //Debug.Log( "Not attaching objects because other hand is hoverlocked and we can't deliver both items." ); + return; + } + } + + // if we're trying to spawn a one-handed item, remove one and two-handed items from this hand and two-handed items from both hands + if ( itemPackage.packageType == ItemPackage.ItemPackageType.OneHanded ) + { + RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.OneHanded, hand ); + RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.TwoHanded, hand ); + RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.TwoHanded, hand.otherHand ); + } + + // if we're trying to spawn a two-handed item, remove one and two-handed items from both hands + if ( itemPackage.packageType == ItemPackage.ItemPackageType.TwoHanded ) + { + RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.OneHanded, hand ); + RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.OneHanded, hand.otherHand ); + RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.TwoHanded, hand ); + RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.TwoHanded, hand.otherHand ); + } + + spawnedItem = GameObject.Instantiate( itemPackage.itemPrefab ); + spawnedItem.SetActive( true ); + hand.AttachObject( spawnedItem, attachmentFlags, attachmentPoint ); + + if ( ( itemPackage.otherHandItemPrefab != null ) && ( hand.otherHand.controller != null ) ) + { + GameObject otherHandObjectToAttach = GameObject.Instantiate( itemPackage.otherHandItemPrefab ); + otherHandObjectToAttach.SetActive( true ); + hand.otherHand.AttachObject( otherHandObjectToAttach, attachmentFlags ); + } + + itemIsSpawned = true; + + justPickedUpItem = true; + + if ( takeBackItem ) + { + useFadedPreview = true; + pickupEvent.Invoke(); + CreatePreviewObject(); + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackageSpawner.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackageSpawner.cs.meta new file mode 100644 index 0000000..ad61425 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/ItemPackageSpawner.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 43e53a985809f0949b9a42cc2a6888c9 +timeCreated: 1436915041 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAnimation.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAnimation.cs new file mode 100644 index 0000000..6c11379 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAnimation.cs @@ -0,0 +1,64 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Animation that moves based on a linear mapping +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class LinearAnimation : MonoBehaviour + { + public LinearMapping linearMapping; + public new Animation animation; + + private AnimationState animState; + private float animLength; + private float lastValue; + + + //------------------------------------------------- + void Awake() + { + if ( animation == null ) + { + animation = GetComponent(); + } + + if ( linearMapping == null ) + { + linearMapping = GetComponent(); + } + + //We're assuming the animation has a single clip, and that's the one we're + //going to scrub with the linear mapping. + animation.playAutomatically = true; + animState = animation[animation.clip.name]; + + //If the anim state's (i.e. clip's) wrap mode is Once (the default) or ClampForever, + //Unity will automatically stop playing the anim, regardless of subsequent changes + //to animState.time. Thus, we set the wrap mode to PingPong. + animState.wrapMode = WrapMode.PingPong; + animState.speed = 0; + animLength = animState.length; + } + + + //------------------------------------------------- + void Update() + { + float value = linearMapping.value; + + //No need to set the anim if our value hasn't changed. + if ( value != lastValue ) + { + animState.time = value / animLength; + } + + lastValue = value; + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAnimation.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAnimation.cs.meta new file mode 100644 index 0000000..2f6ba37 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAnimation.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 49a60120b932b59409171f5ff611b639 +timeCreated: 1433799038 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAnimator.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAnimator.cs new file mode 100644 index 0000000..15b84ae --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAnimator.cs @@ -0,0 +1,59 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Animator whose speed is set based on a linear mapping +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class LinearAnimator : MonoBehaviour + { + public LinearMapping linearMapping; + public Animator animator; + + private float currentLinearMapping = float.NaN; + private int framesUnchanged = 0; + + + //------------------------------------------------- + void Awake() + { + if ( animator == null ) + { + animator = GetComponent(); + } + + animator.speed = 0.0f; + + if ( linearMapping == null ) + { + linearMapping = GetComponent(); + } + } + + + //------------------------------------------------- + void Update() + { + if ( currentLinearMapping != linearMapping.value ) + { + currentLinearMapping = linearMapping.value; + animator.enabled = true; + animator.Play( 0, 0, currentLinearMapping ); + framesUnchanged = 0; + } + else + { + framesUnchanged++; + if ( framesUnchanged > 2 ) + { + animator.enabled = false; + } + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAnimator.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAnimator.cs.meta new file mode 100644 index 0000000..36c5620 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAnimator.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 634b98c3ef8bc6d4f834f80a4613a4a4 +timeCreated: 1435864149 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAudioPitch.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAudioPitch.cs new file mode 100644 index 0000000..ec17c04 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAudioPitch.cs @@ -0,0 +1,58 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Changes the pitch of this audio source based on a linear mapping +// and a curve +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class LinearAudioPitch : MonoBehaviour + { + public LinearMapping linearMapping; + public AnimationCurve pitchCurve; + public float minPitch; + public float maxPitch; + public bool applyContinuously = true; + + private AudioSource audioSource; + + + //------------------------------------------------- + void Awake() + { + if ( audioSource == null ) + { + audioSource = GetComponent(); + } + + if ( linearMapping == null ) + { + linearMapping = GetComponent(); + } + } + + + //------------------------------------------------- + void Update() + { + if ( applyContinuously ) + { + Apply(); + } + } + + + //------------------------------------------------- + private void Apply() + { + float y = pitchCurve.Evaluate( linearMapping.value ); + + audioSource.pitch = Mathf.Lerp( minPitch, maxPitch, y ); + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAudioPitch.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAudioPitch.cs.meta new file mode 100644 index 0000000..da2964e --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearAudioPitch.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bb07dbf09f9933e49b22c82d8428c53b +timeCreated: 1436834777 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearBlendshape.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearBlendshape.cs new file mode 100644 index 0000000..af1740b --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearBlendshape.cs @@ -0,0 +1,51 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Set the blend shape weight based on a linear mapping +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class LinearBlendshape : MonoBehaviour + { + public LinearMapping linearMapping; + public SkinnedMeshRenderer skinnedMesh; + + private float lastValue; + + + //------------------------------------------------- + void Awake() + { + if ( skinnedMesh == null ) + { + skinnedMesh = GetComponent(); + } + + if ( linearMapping == null ) + { + linearMapping = GetComponent(); + } + } + + + //------------------------------------------------- + void Update() + { + float value = linearMapping.value; + + //No need to set the blend if our value hasn't changed. + if ( value != lastValue ) + { + float blendValue = Util.RemapNumberClamped( value, 0f, 1f, 1f, 100f ); + skinnedMesh.SetBlendShapeWeight( 0, blendValue ); + } + + lastValue = value; + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearBlendshape.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearBlendshape.cs.meta new file mode 100644 index 0000000..74cb2ed --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearBlendshape.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5a3622562855c9a40a14846ffdc8bfe4 +timeCreated: 1447859480 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearDisplacement.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearDisplacement.cs new file mode 100644 index 0000000..a59c9f4 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearDisplacement.cs @@ -0,0 +1,41 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Move the position of this object based on a linear mapping +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class LinearDisplacement : MonoBehaviour + { + public Vector3 displacement; + public LinearMapping linearMapping; + + private Vector3 initialPosition; + + //------------------------------------------------- + void Start() + { + initialPosition = transform.localPosition; + + if ( linearMapping == null ) + { + linearMapping = GetComponent(); + } + } + + + //------------------------------------------------- + void Update() + { + if ( linearMapping ) + { + transform.localPosition = initialPosition + linearMapping.value * displacement; + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearDisplacement.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearDisplacement.cs.meta new file mode 100644 index 0000000..66a0a13 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearDisplacement.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 13d876e5d485004448f3e7b57eece9ab +timeCreated: 1433730007 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearDrive.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearDrive.cs new file mode 100644 index 0000000..dabd09e --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearDrive.cs @@ -0,0 +1,148 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Drives a linear mapping based on position between 2 positions +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( Interactable ) )] + public class LinearDrive : MonoBehaviour + { + public Transform startPosition; + public Transform endPosition; + public LinearMapping linearMapping; + public bool repositionGameObject = true; + public bool maintainMomemntum = true; + public float momemtumDampenRate = 5.0f; + + private float initialMappingOffset; + private int numMappingChangeSamples = 5; + private float[] mappingChangeSamples; + private float prevMapping = 0.0f; + private float mappingChangeRate; + private int sampleCount = 0; + + + //------------------------------------------------- + void Awake() + { + mappingChangeSamples = new float[numMappingChangeSamples]; + } + + + //------------------------------------------------- + void Start() + { + if ( linearMapping == null ) + { + linearMapping = GetComponent(); + } + + if ( linearMapping == null ) + { + linearMapping = gameObject.AddComponent(); + } + + initialMappingOffset = linearMapping.value; + + if ( repositionGameObject ) + { + UpdateLinearMapping( transform ); + } + } + + + //------------------------------------------------- + private void HandHoverUpdate( Hand hand ) + { + if ( hand.GetStandardInteractionButtonDown() ) + { + hand.HoverLock( GetComponent() ); + + initialMappingOffset = linearMapping.value - CalculateLinearMapping( hand.transform ); + sampleCount = 0; + mappingChangeRate = 0.0f; + } + + if ( hand.GetStandardInteractionButtonUp() ) + { + hand.HoverUnlock( GetComponent() ); + + CalculateMappingChangeRate(); + } + + if ( hand.GetStandardInteractionButton() ) + { + UpdateLinearMapping( hand.transform ); + } + } + + + //------------------------------------------------- + private void CalculateMappingChangeRate() + { + //Compute the mapping change rate + mappingChangeRate = 0.0f; + int mappingSamplesCount = Mathf.Min( sampleCount, mappingChangeSamples.Length ); + if ( mappingSamplesCount != 0 ) + { + for ( int i = 0; i < mappingSamplesCount; ++i ) + { + mappingChangeRate += mappingChangeSamples[i]; + } + mappingChangeRate /= mappingSamplesCount; + } + } + + + //------------------------------------------------- + private void UpdateLinearMapping( Transform tr ) + { + prevMapping = linearMapping.value; + linearMapping.value = Mathf.Clamp01( initialMappingOffset + CalculateLinearMapping( tr ) ); + + mappingChangeSamples[sampleCount % mappingChangeSamples.Length] = ( 1.0f / Time.deltaTime ) * ( linearMapping.value - prevMapping ); + sampleCount++; + + if ( repositionGameObject ) + { + transform.position = Vector3.Lerp( startPosition.position, endPosition.position, linearMapping.value ); + } + } + + + //------------------------------------------------- + private float CalculateLinearMapping( Transform tr ) + { + Vector3 direction = endPosition.position - startPosition.position; + float length = direction.magnitude; + direction.Normalize(); + + Vector3 displacement = tr.position - startPosition.position; + + return Vector3.Dot( displacement, direction ) / length; + } + + + //------------------------------------------------- + void Update() + { + if ( maintainMomemntum && mappingChangeRate != 0.0f ) + { + //Dampen the mapping change rate and apply it to the mapping + mappingChangeRate = Mathf.Lerp( mappingChangeRate, 0.0f, momemtumDampenRate * Time.deltaTime ); + linearMapping.value = Mathf.Clamp01( linearMapping.value + ( mappingChangeRate * Time.deltaTime ) ); + + if ( repositionGameObject ) + { + transform.position = Vector3.Lerp( startPosition.position, endPosition.position, linearMapping.value ); + } + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearDrive.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearDrive.cs.meta new file mode 100644 index 0000000..bbc2a5b --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearDrive.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8c81a27fd18a29444be92481fe681f4b +timeCreated: 1434650764 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearMapping.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearMapping.cs new file mode 100644 index 0000000..ec7cc43 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearMapping.cs @@ -0,0 +1,17 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: A linear mapping value that is used by other components +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class LinearMapping : MonoBehaviour + { + public float value; + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearMapping.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearMapping.cs.meta new file mode 100644 index 0000000..21c0195 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/LinearMapping.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 46f8e9e70f68ee3418ad85992778c116 +timeCreated: 1433728353 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/PlaySound.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/PlaySound.cs new file mode 100644 index 0000000..6b8771b --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/PlaySound.cs @@ -0,0 +1,216 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Plays one of many audio files with possible randomized parameters +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( AudioSource ) )] + public class PlaySound : MonoBehaviour + { + [Tooltip( "List of audio clips to play." )] + public AudioClip[] waveFile; + [Tooltip( "Stops the currently playing clip in the audioSource. Otherwise clips will overlap/mix." )] + public bool stopOnPlay; + [Tooltip( "After the audio clip finishes playing, disable the game object the sound is on." )] + public bool disableOnEnd; + [Tooltip( "Loop the sound after the wave file variation has been chosen." )] + public bool looping; + [Tooltip( "If the sound is looping and updating it's position every frame, stop the sound at the end of the wav/clip length. " )] + public bool stopOnEnd; + [Tooltip( "Start a wave file playing on awake, but after a delay." )] + public bool playOnAwakeWithDelay; + + [Header ( "Random Volume" )] + public bool useRandomVolume = true; + [Tooltip( "Minimum volume that will be used when randomly set." )] + [Range( 0.0f, 1.0f )] + public float volMin = 1.0f; + [Tooltip( "Maximum volume that will be used when randomly set." )] + [Range( 0.0f, 1.0f )] + public float volMax = 1.0f; + + [Header ( "Random Pitch" )] + [Tooltip( "Use min and max random pitch levels when playing sounds." )] + public bool useRandomPitch = true; + [Tooltip( "Minimum pitch that will be used when randomly set." )] + [Range( -3.0f, 3.0f )] + public float pitchMin = 1.0f; + [Tooltip( "Maximum pitch that will be used when randomly set." )] + [Range( -3.0f, 3.0f )] + public float pitchMax = 1.0f; + + [Header( "Random Time" )] + [Tooltip( "Use Retrigger Time to repeat the sound within a time range" )] + public bool useRetriggerTime = false; + [Tooltip( "Inital time before the first repetion starts" )] + [Range( 0.0f, 360.0f )] + public float timeInitial = 0.0f; + [Tooltip( "Minimum time that will pass before the sound is retriggered" )] + [Range( 0.0f, 360.0f )] + public float timeMin = 0.0f; + [Tooltip( "Maximum pitch that will be used when randomly set." )] + [Range( 0.0f, 360.0f )] + public float timeMax = 0.0f; + + [Header ( "Random Silence" )] + [Tooltip( "Use Retrigger Time to repeat the sound within a time range" )] + public bool useRandomSilence = false; + [Tooltip( "Percent chance that the wave file will not play" )] + [Range( 0.0f, 1.0f )] + public float percentToNotPlay = 0.0f; + + [Header( "Delay Time" )] + [Tooltip( "Time to offset playback of sound" )] + public float delayOffsetTime = 0.0f; + + + private AudioSource audioSource; + private AudioClip clip; + + //------------------------------------------------- + void Awake() + { + audioSource = GetComponent(); + clip = audioSource.clip; + + // audio source play on awake is true, just play the PlaySound immediately + if ( audioSource.playOnAwake ) + { + if ( useRetriggerTime ) + InvokeRepeating( "Play", timeInitial, Random.Range( timeMin, timeMax ) ); + else + Play(); + } + + // if playOnAwake is false, but the playOnAwakeWithDelay on the PlaySound is true, play the sound on away but with a delay + else if ( !audioSource.playOnAwake && playOnAwakeWithDelay ) + { + PlayWithDelay( delayOffsetTime ); + + if ( useRetriggerTime ) + InvokeRepeating( "Play", timeInitial, Random.Range( timeMin, timeMax ) ); + } + + // in the case where both playOnAwake and playOnAwakeWithDelay are both set to true, just to the same as above, play the sound but with a delay + else if ( audioSource.playOnAwake && playOnAwakeWithDelay ) + { + PlayWithDelay( delayOffsetTime ); + + if ( useRetriggerTime ) + InvokeRepeating( "Play", timeInitial, Random.Range( timeMin, timeMax ) ); + } + } + + + //------------------------------------------------- + // Play a random clip from those available + //------------------------------------------------- + public void Play() + { + if ( looping ) + { + PlayLooping(); + + } + + else PlayOneShotSound(); + } + + + //------------------------------------------------- + public void PlayWithDelay( float delayTime ) + { + if ( looping ) + Invoke( "PlayLooping", delayTime ); + else + Invoke( "PlayOneShotSound", delayTime ); + } + + + //------------------------------------------------- + // Play random wave clip on audiosource as a one shot + //------------------------------------------------- + public AudioClip PlayOneShotSound() + { + if ( !this.audioSource.isActiveAndEnabled ) + return null; + + SetAudioSource(); + if ( this.stopOnPlay ) + audioSource.Stop(); + if ( this.disableOnEnd ) + Invoke( "Disable", clip.length ); + this.audioSource.PlayOneShot( this.clip ); + return this.clip; + } + + + //------------------------------------------------- + public AudioClip PlayLooping() + { + // get audio source properties, and do any special randomizations + SetAudioSource(); + + // if the audio source has forgotten to be set to looping, set it to looping + if ( !audioSource.loop ) + audioSource.loop = true; + + // play the clip in the audio source, all the meanwhile updating it's location + this.audioSource.Play(); + + // if disable on end is checked, stop playing the wave file after the first loop has finished. + if ( stopOnEnd ) + Invoke( "Stop", audioSource.clip.length ); + return this.clip; + } + + + //------------------------------------------------- + public void Disable() + { + gameObject.SetActive( false ); + } + + + //------------------------------------------------- + public void Stop() + { + audioSource.Stop(); + } + + + //------------------------------------------------- + private void SetAudioSource() + { + if ( this.useRandomVolume ) + { + //randomly apply a volume between the volume min max + this.audioSource.volume = Random.Range( this.volMin, this.volMax ); + + if ( useRandomSilence && ( Random.Range( 0, 1 ) < percentToNotPlay ) ) + { + this.audioSource.volume = 0; + } + } + + if ( this.useRandomPitch ) + { + //randomly apply a pitch between the pitch min max + this.audioSource.pitch = Random.Range( this.pitchMin, this.pitchMax ); + } + + if ( this.waveFile.Length > 0 ) + { + // randomly assign a wave file from the array into the audioSource clip property + audioSource.clip = this.waveFile[Random.Range( 0, waveFile.Length )]; + clip = audioSource.clip; + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/PlaySound.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/PlaySound.cs.meta new file mode 100644 index 0000000..9c22ff9 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/PlaySound.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1a125d9df683e2a49b12babced273360 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/Player.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/Player.cs new file mode 100644 index 0000000..3634415 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/Player.cs @@ -0,0 +1,406 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Player interface used to query HMD transforms and VR hands +// +//============================================================================= + +using UnityEngine; +using System.Collections; +using System.Collections.Generic; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + // Singleton representing the local VR player/user, with methods for getting + // the player's hands, head, tracking origin, and guesses for various properties. + //------------------------------------------------------------------------- + public class Player : MonoBehaviour + { + [Tooltip( "Virtual transform corresponding to the meatspace tracking origin. Devices are tracked relative to this." )] + public Transform trackingOriginTransform; + + [Tooltip( "List of possible transforms for the head/HMD, including the no-SteamVR fallback camera." )] + public Transform[] hmdTransforms; + + [Tooltip( "List of possible Hands, including no-SteamVR fallback Hands." )] + public Hand[] hands; + + [Tooltip( "Reference to the physics collider that follows the player's HMD position." )] + public Collider headCollider; + + [Tooltip( "These objects are enabled when SteamVR is available" )] + public GameObject rigSteamVR; + + [Tooltip( "These objects are enabled when SteamVR is not available, or when the user toggles out of VR" )] + public GameObject rig2DFallback; + + [Tooltip( "The audio listener for this player" )] + public Transform audioListener; + + public bool allowToggleTo2D = true; + + + //------------------------------------------------- + // Singleton instance of the Player. Only one can exist at a time. + //------------------------------------------------- + private static Player _instance; + public static Player instance + { + get + { + if ( _instance == null ) + { + _instance = FindObjectOfType(); + } + return _instance; + } + } + + + //------------------------------------------------- + // Get the number of active Hands. + //------------------------------------------------- + public int handCount + { + get + { + int count = 0; + for ( int i = 0; i < hands.Length; i++ ) + { + if ( hands[i].gameObject.activeInHierarchy ) + { + count++; + } + } + return count; + } + } + + + //------------------------------------------------- + // Get the i-th active Hand. + // + // i - Zero-based index of the active Hand to get + //------------------------------------------------- + public Hand GetHand( int i ) + { + for ( int j = 0; j < hands.Length; j++ ) + { + if ( !hands[j].gameObject.activeInHierarchy ) + { + continue; + } + + if ( i > 0 ) + { + i--; + continue; + } + + return hands[j]; + } + + return null; + } + + + //------------------------------------------------- + public Hand leftHand + { + get + { + for ( int j = 0; j < hands.Length; j++ ) + { + if ( !hands[j].gameObject.activeInHierarchy ) + { + continue; + } + + if ( hands[j].GuessCurrentHandType() != Hand.HandType.Left ) + { + continue; + } + + return hands[j]; + } + + return null; + } + } + + + //------------------------------------------------- + public Hand rightHand + { + get + { + for ( int j = 0; j < hands.Length; j++ ) + { + if ( !hands[j].gameObject.activeInHierarchy ) + { + continue; + } + + if ( hands[j].GuessCurrentHandType() != Hand.HandType.Right ) + { + continue; + } + + return hands[j]; + } + + return null; + } + } + + + //------------------------------------------------- + public SteamVR_Controller.Device leftController + { + get + { + Hand h = leftHand; + if ( h ) + { + return h.controller; + } + return null; + } + } + + + //------------------------------------------------- + public SteamVR_Controller.Device rightController + { + get + { + Hand h = rightHand; + if ( h ) + { + return h.controller; + } + return null; + } + } + + + //------------------------------------------------- + // Get the HMD transform. This might return the fallback camera transform if SteamVR is unavailable or disabled. + //------------------------------------------------- + public Transform hmdTransform + { + get + { + for ( int i = 0; i < hmdTransforms.Length; i++ ) + { + if ( hmdTransforms[i].gameObject.activeInHierarchy ) + return hmdTransforms[i]; + } + return null; + } + } + + + //------------------------------------------------- + // Height of the eyes above the ground - useful for estimating player height. + //------------------------------------------------- + public float eyeHeight + { + get + { + Transform hmd = hmdTransform; + if ( hmd ) + { + Vector3 eyeOffset = Vector3.Project( hmd.position - trackingOriginTransform.position, trackingOriginTransform.up ); + return eyeOffset.magnitude / trackingOriginTransform.lossyScale.x; + } + return 0.0f; + } + } + + + //------------------------------------------------- + // Guess for the world-space position of the player's feet, directly beneath the HMD. + //------------------------------------------------- + public Vector3 feetPositionGuess + { + get + { + Transform hmd = hmdTransform; + if ( hmd ) + { + return trackingOriginTransform.position + Vector3.ProjectOnPlane( hmd.position - trackingOriginTransform.position, trackingOriginTransform.up ); + } + return trackingOriginTransform.position; + } + } + + + //------------------------------------------------- + // Guess for the world-space direction of the player's hips/torso. This is effectively just the gaze direction projected onto the floor plane. + //------------------------------------------------- + public Vector3 bodyDirectionGuess + { + get + { + Transform hmd = hmdTransform; + if ( hmd ) + { + Vector3 direction = Vector3.ProjectOnPlane( hmd.forward, trackingOriginTransform.up ); + if ( Vector3.Dot( hmd.up, trackingOriginTransform.up ) < 0.0f ) + { + // The HMD is upside-down. Either + // -The player is bending over backwards + // -The player is bent over looking through their legs + direction = -direction; + } + return direction; + } + return trackingOriginTransform.forward; + } + } + + + //------------------------------------------------- + void Awake() + { + if ( trackingOriginTransform == null ) + { + trackingOriginTransform = this.transform; + } + } + + + //------------------------------------------------- + void OnEnable() + { + _instance = this; + + if ( SteamVR.instance != null ) + { + ActivateRig( rigSteamVR ); + } + else + { +#if !HIDE_DEBUG_UI + ActivateRig( rig2DFallback ); +#endif + } + } + + + //------------------------------------------------- + void OnDrawGizmos() + { + if ( this != instance ) + { + return; + } + + //NOTE: These gizmo icons don't work in the plugin since the icons need to exist in a specific "Gizmos" + // folder in your Asset tree. These icons are included under Core/Icons. Moving them into a + // "Gizmos" folder should make them work again. + + Gizmos.color = Color.white; + Gizmos.DrawIcon( feetPositionGuess, "vr_interaction_system_feet.png" ); + + Gizmos.color = Color.cyan; + Gizmos.DrawLine( feetPositionGuess, feetPositionGuess + trackingOriginTransform.up * eyeHeight ); + + // Body direction arrow + Gizmos.color = Color.blue; + Vector3 bodyDirection = bodyDirectionGuess; + Vector3 bodyDirectionTangent = Vector3.Cross( trackingOriginTransform.up, bodyDirection ); + Vector3 startForward = feetPositionGuess + trackingOriginTransform.up * eyeHeight * 0.75f; + Vector3 endForward = startForward + bodyDirection * 0.33f; + Gizmos.DrawLine( startForward, endForward ); + Gizmos.DrawLine( endForward, endForward - 0.033f * ( bodyDirection + bodyDirectionTangent ) ); + Gizmos.DrawLine( endForward, endForward - 0.033f * ( bodyDirection - bodyDirectionTangent ) ); + + Gizmos.color = Color.red; + int count = handCount; + for ( int i = 0; i < count; i++ ) + { + Hand hand = GetHand( i ); + + if ( hand.startingHandType == Hand.HandType.Left ) + { + Gizmos.DrawIcon( hand.transform.position, "vr_interaction_system_left_hand.png" ); + } + else if ( hand.startingHandType == Hand.HandType.Right ) + { + Gizmos.DrawIcon( hand.transform.position, "vr_interaction_system_right_hand.png" ); + } + else + { + Hand.HandType guessHandType = hand.GuessCurrentHandType(); + + if ( guessHandType == Hand.HandType.Left ) + { + Gizmos.DrawIcon( hand.transform.position, "vr_interaction_system_left_hand_question.png" ); + } + else if ( guessHandType == Hand.HandType.Right ) + { + Gizmos.DrawIcon( hand.transform.position, "vr_interaction_system_right_hand_question.png" ); + } + else + { + Gizmos.DrawIcon( hand.transform.position, "vr_interaction_system_unknown_hand.png" ); + } + } + } + } + + + //------------------------------------------------- + public void Draw2DDebug() + { + if ( !allowToggleTo2D ) + return; + + if ( !SteamVR.active ) + return; + + int width = 100; + int height = 25; + int left = Screen.width / 2 - width / 2; + int top = Screen.height - height - 10; + + string text = ( rigSteamVR.activeSelf ) ? "2D Debug" : "VR"; + + if ( GUI.Button( new Rect( left, top, width, height ), text ) ) + { + if ( rigSteamVR.activeSelf ) + { + ActivateRig( rig2DFallback ); + } + else + { + ActivateRig( rigSteamVR ); + } + } + } + + + //------------------------------------------------- + private void ActivateRig( GameObject rig ) + { + rigSteamVR.SetActive( rig == rigSteamVR ); + rig2DFallback.SetActive( rig == rig2DFallback ); + + if ( audioListener ) + { + audioListener.transform.parent = hmdTransform; + audioListener.transform.localPosition = Vector3.zero; + audioListener.transform.localRotation = Quaternion.identity; + } + } + + + //------------------------------------------------- + public void PlayerShotSelf() + { + //Do something appropriate here + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/Player.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/Player.cs.meta new file mode 100644 index 0000000..c024748 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/Player.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 202a6e24b48d1684398409c47161adcb +timeCreated: 1435864159 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SeeThru.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/SeeThru.cs new file mode 100644 index 0000000..3d18de1 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SeeThru.cs @@ -0,0 +1,151 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Uses the see thru renderer while attached to hand +// +//============================================================================= + +using UnityEngine; +using System.Collections; +using System.Collections.Generic; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class SeeThru : MonoBehaviour + { + public Material seeThruMaterial; + + private GameObject seeThru; + private Interactable interactable; + private Renderer sourceRenderer; + private Renderer destRenderer; + + + //------------------------------------------------- + void Awake() + { + interactable = GetComponentInParent(); + + // + // Create child game object for see thru renderer + // + seeThru = new GameObject( "_see_thru" ); + seeThru.transform.parent = transform; + seeThru.transform.localPosition = Vector3.zero; + seeThru.transform.localRotation = Quaternion.identity; + seeThru.transform.localScale = Vector3.one; + + // + // Copy mesh filter + // + MeshFilter sourceMeshFilter = GetComponent(); + if ( sourceMeshFilter != null ) + { + MeshFilter destMeshFilter = seeThru.AddComponent(); + destMeshFilter.sharedMesh = sourceMeshFilter.sharedMesh; + } + + // + // Copy mesh renderer + // + MeshRenderer sourceMeshRenderer = GetComponent(); + if ( sourceMeshRenderer != null ) + { + sourceRenderer = sourceMeshRenderer; + destRenderer = seeThru.AddComponent(); + } + + // + // Copy skinned mesh renderer + // + SkinnedMeshRenderer sourceSkinnedMeshRenderer = GetComponent(); + if ( sourceSkinnedMeshRenderer != null ) + { + SkinnedMeshRenderer destSkinnedMeshRenderer = seeThru.AddComponent(); + + sourceRenderer = sourceSkinnedMeshRenderer; + destRenderer = destSkinnedMeshRenderer; + + destSkinnedMeshRenderer.sharedMesh = sourceSkinnedMeshRenderer.sharedMesh; + destSkinnedMeshRenderer.rootBone = sourceSkinnedMeshRenderer.rootBone; + destSkinnedMeshRenderer.bones = sourceSkinnedMeshRenderer.bones; + destSkinnedMeshRenderer.quality = sourceSkinnedMeshRenderer.quality; + destSkinnedMeshRenderer.updateWhenOffscreen = sourceSkinnedMeshRenderer.updateWhenOffscreen; + } + + // + // Create see thru materials + // + if ( sourceRenderer != null && destRenderer != null ) + { + int materialCount = sourceRenderer.sharedMaterials.Length; + Material[] destRendererMaterials = new Material[materialCount]; + for ( int i = 0; i < materialCount; i++ ) + { + destRendererMaterials[i] = seeThruMaterial; + } + destRenderer.sharedMaterials = destRendererMaterials; + + for ( int i = 0; i < destRenderer.materials.Length; i++ ) + { + destRenderer.materials[i].renderQueue = 2001; // Rendered after geometry + } + + for ( int i = 0; i < sourceRenderer.materials.Length; i++ ) + { + if ( sourceRenderer.materials[i].renderQueue == 2000 ) + { + sourceRenderer.materials[i].renderQueue = 2002; + } + } + } + + seeThru.gameObject.SetActive( false ); + } + + + //------------------------------------------------- + void OnEnable() + { + interactable.onAttachedToHand += AttachedToHand; + interactable.onDetachedFromHand += DetachedFromHand; + } + + + //------------------------------------------------- + void OnDisable() + { + interactable.onAttachedToHand -= AttachedToHand; + interactable.onDetachedFromHand -= DetachedFromHand; + } + + + //------------------------------------------------- + private void AttachedToHand( Hand hand ) + { + seeThru.SetActive( true ); + } + + + //------------------------------------------------- + private void DetachedFromHand( Hand hand ) + { + seeThru.SetActive( false ); + } + + + //------------------------------------------------- + void Update() + { + if ( seeThru.activeInHierarchy ) + { + int materialCount = Mathf.Min( sourceRenderer.materials.Length, destRenderer.materials.Length ); + for ( int i = 0; i < materialCount; i++ ) + { + destRenderer.materials[i].mainTexture = sourceRenderer.materials[i].mainTexture; + destRenderer.materials[i].color = destRenderer.materials[i].color * sourceRenderer.materials[i].color; + } + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SeeThru.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/SeeThru.cs.meta new file mode 100644 index 0000000..de9c81e --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SeeThru.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 7d623a50b67320940b97e93e31d0a21b +timeCreated: 1456716277 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: + - seeThruMaterial: {fileID: 2100000, guid: 3bbb445147c574240a8b87a1193788b5, type: 2} + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SleepOnAwake.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/SleepOnAwake.cs new file mode 100644 index 0000000..5948773 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SleepOnAwake.cs @@ -0,0 +1,25 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: This object's rigidbody goes to sleep when created +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class SleepOnAwake : MonoBehaviour + { + //------------------------------------------------- + void Awake() + { + Rigidbody rigidbody = GetComponent(); + if ( rigidbody ) + { + rigidbody.Sleep(); + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SleepOnAwake.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/SleepOnAwake.cs.meta new file mode 100644 index 0000000..5abaee2 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SleepOnAwake.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0584375ad2f33ef4da0b276de8507487 +timeCreated: 1430167006 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SoundDeparent.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/SoundDeparent.cs new file mode 100644 index 0000000..2dbd184 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SoundDeparent.cs @@ -0,0 +1,38 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Unparents this object and optionally destroys it after the sound +// has played +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class SoundDeparent : MonoBehaviour + { + public bool destroyAfterPlayOnce = true; + private AudioSource thisAudioSource; + + + //------------------------------------------------- + void Awake() + { + thisAudioSource = GetComponent(); + + } + + + //------------------------------------------------- + void Start() + { + // move the sound object out from under the parent + gameObject.transform.parent = null; + + if ( destroyAfterPlayOnce ) + Destroy( gameObject, thisAudioSource.clip.length ); + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SoundDeparent.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/SoundDeparent.cs.meta new file mode 100644 index 0000000..0b628d8 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SoundDeparent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f53662f45a4454944a06629fec9c941e +timeCreated: 1457503214 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SoundPlayOneshot.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/SoundPlayOneshot.cs new file mode 100644 index 0000000..d210460 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SoundPlayOneshot.cs @@ -0,0 +1,75 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Play one-shot sounds as opposed to continuos/looping ones +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class SoundPlayOneshot : MonoBehaviour + { + public AudioClip[] waveFiles; + private AudioSource thisAudioSource; + + public float volMin; + public float volMax; + + public float pitchMin; + public float pitchMax; + + public bool playOnAwake; + + + //------------------------------------------------- + void Awake() + { + thisAudioSource = GetComponent(); + + if ( playOnAwake ) + { + Play(); + } + } + + + //------------------------------------------------- + public void Play() + { + if ( thisAudioSource != null && thisAudioSource.isActiveAndEnabled && !Util.IsNullOrEmpty( waveFiles ) ) + { + //randomly apply a volume between the volume min max + thisAudioSource.volume = Random.Range( volMin, volMax ); + + //randomly apply a pitch between the pitch min max + thisAudioSource.pitch = Random.Range( pitchMin, pitchMax ); + + // play the sound + thisAudioSource.PlayOneShot( waveFiles[Random.Range( 0, waveFiles.Length )] ); + } + } + + + //------------------------------------------------- + public void Pause() + { + if ( thisAudioSource != null ) + { + thisAudioSource.Pause(); + } + } + + + //------------------------------------------------- + public void UnPause() + { + if ( thisAudioSource != null ) + { + thisAudioSource.UnPause(); + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SoundPlayOneshot.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/SoundPlayOneshot.cs.meta new file mode 100644 index 0000000..6612487 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SoundPlayOneshot.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 32c1c9a5bbab2e54280027c0ecaf42db +timeCreated: 1436566670 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnAndAttachAfterControllerIsTracking.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnAndAttachAfterControllerIsTracking.cs new file mode 100644 index 0000000..35cb476 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnAndAttachAfterControllerIsTracking.cs @@ -0,0 +1,50 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Spawns and attaches an object to the hand after the controller has +// tracking +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class SpawnAndAttachAfterControllerIsTracking : MonoBehaviour + { + private Hand hand; + public GameObject itemPrefab; + + + //------------------------------------------------- + void Start() + { + hand = GetComponentInParent(); + } + + + //------------------------------------------------- + void Update() + { + if ( itemPrefab != null ) + { + if ( hand.controller != null ) + { + if ( hand.controller.hasTracking ) + { + GameObject objectToAttach = GameObject.Instantiate( itemPrefab ); + objectToAttach.SetActive( true ); + hand.AttachObject( objectToAttach ); + hand.controller.TriggerHapticPulse( 800 ); + Destroy( gameObject ); + + // If the player's scale has been changed the object to attach will be the wrong size. + // To fix this we change the object's scale back to its original, pre-attach scale. + objectToAttach.transform.localScale = itemPrefab.transform.localScale; + } + } + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnAndAttachAfterControllerIsTracking.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnAndAttachAfterControllerIsTracking.cs.meta new file mode 100644 index 0000000..66ac9c6 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnAndAttachAfterControllerIsTracking.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6ad167161b0bf8e4d9c038db358e0a28 +timeCreated: 1441826311 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnAndAttachToHand.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnAndAttachToHand.cs new file mode 100644 index 0000000..7cac3cc --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnAndAttachToHand.cs @@ -0,0 +1,37 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Creates an object and attaches it to the hand +// +//============================================================================= + +using UnityEngine; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class SpawnAndAttachToHand : MonoBehaviour + { + public Hand hand; + public GameObject prefab; + + + //------------------------------------------------- + public void SpawnAndAttach( Hand passedInhand ) + { + Hand handToUse = passedInhand; + if ( passedInhand == null ) + { + handToUse = hand; + } + + if ( handToUse == null ) + { + return; + } + + GameObject prefabObject = Instantiate( prefab ) as GameObject; + handToUse.AttachObject( prefabObject ); + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnAndAttachToHand.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnAndAttachToHand.cs.meta new file mode 100644 index 0000000..c3134fd --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnAndAttachToHand.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f4a03a51c550b92478a559cf694ce118 +timeCreated: 1437097962 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnRenderModel.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnRenderModel.cs new file mode 100644 index 0000000..1cdaa2d --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnRenderModel.cs @@ -0,0 +1,168 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Spawns a render model for the controller from SteamVR +// +//============================================================================= + +using UnityEngine; +using System.Collections; +using System.Collections.Generic; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + public class SpawnRenderModel : MonoBehaviour + { + public Material[] materials; + + private SteamVR_RenderModel[] renderModels; + private Hand hand; + private List renderers = new List(); + + private static List spawnRenderModels = new List(); + private static int lastFrameUpdated; + private static int spawnRenderModelUpdateIndex; + + SteamVR_Events.Action renderModelLoadedAction; + + + //------------------------------------------------- + void Awake() + { + renderModels = new SteamVR_RenderModel[materials.Length]; + renderModelLoadedAction = SteamVR_Events.RenderModelLoadedAction( OnRenderModelLoaded ); + } + + + //------------------------------------------------- + void OnEnable() + { + ShowController(); + + renderModelLoadedAction.enabled = true; + + spawnRenderModels.Add( this ); + } + + + //------------------------------------------------- + void OnDisable() + { + HideController(); + + renderModelLoadedAction.enabled = false; + + spawnRenderModels.Remove( this ); + } + + + //------------------------------------------------- + private void OnAttachedToHand( Hand hand ) + { + this.hand = hand; + ShowController(); + } + + + //------------------------------------------------- + private void OnDetachedFromHand( Hand hand ) + { + this.hand = null; + HideController(); + } + + + //------------------------------------------------- + void Update() + { + // Only update one per frame + if ( lastFrameUpdated == Time.renderedFrameCount ) + { + return; + } + lastFrameUpdated = Time.renderedFrameCount; + + + // SpawnRenderModel overflow + if ( spawnRenderModelUpdateIndex >= spawnRenderModels.Count ) + { + spawnRenderModelUpdateIndex = 0; + } + + + // Perform update + if ( spawnRenderModelUpdateIndex < spawnRenderModels.Count ) + { + SteamVR_RenderModel renderModel = spawnRenderModels[spawnRenderModelUpdateIndex].renderModels[0]; + if ( renderModel != null ) + { + renderModel.UpdateComponents( OpenVR.RenderModels ); + } + } + + spawnRenderModelUpdateIndex++; + } + + + //------------------------------------------------- + private void ShowController() + { + if ( hand == null || hand.controller == null ) + { + return; + } + + for ( int i = 0; i < renderModels.Length; i++ ) + { + if ( renderModels[i] == null ) + { + renderModels[i] = new GameObject( "SteamVR_RenderModel" ).AddComponent(); + renderModels[i].updateDynamically = false; // Update one per frame (see Update() method) + renderModels[i].transform.parent = transform; + Util.ResetTransform( renderModels[i].transform ); + } + + renderModels[i].gameObject.SetActive( true ); + renderModels[i].SetDeviceIndex( (int)hand.controller.index ); + } + } + + + //------------------------------------------------- + private void HideController() + { + for ( int i = 0; i < renderModels.Length; i++ ) + { + if ( renderModels[i] != null ) + { + renderModels[i].gameObject.SetActive( false ); + } + } + } + + + //------------------------------------------------- + private void OnRenderModelLoaded( SteamVR_RenderModel renderModel, bool success ) + { + for ( int i = 0; i < renderModels.Length; i++ ) + { + if ( renderModel == renderModels[i] ) + { + if ( materials[i] != null ) + { + renderers.Clear(); + renderModels[i].GetComponentsInChildren( renderers ); + for ( int j = 0; j < renderers.Count; j++ ) + { + Texture mainTexture = renderers[j].material.mainTexture; + renderers[j].sharedMaterial = materials[i]; + renderers[j].material.mainTexture = mainTexture; + renderers[j].gameObject.layer = gameObject.layer; + renderers[j].tag = gameObject.tag; + } + } + } + } + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnRenderModel.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnRenderModel.cs.meta new file mode 100644 index 0000000..ea07185 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/SpawnRenderModel.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9fb3fe54664b917489646492ee8c4993 +timeCreated: 1441140218 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/Throwable.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/Throwable.cs new file mode 100644 index 0000000..0319e5b --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/Throwable.cs @@ -0,0 +1,258 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Basic throwable object +// +//============================================================================= + +using UnityEngine; +using UnityEngine.Events; +using System.Collections; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( Interactable ) )] + [RequireComponent( typeof( Rigidbody ) )] + [RequireComponent( typeof( VelocityEstimator ) )] + public class Throwable : MonoBehaviour + { + [EnumFlags] + [Tooltip( "The flags used to attach this object to the hand." )] + public Hand.AttachmentFlags attachmentFlags = Hand.AttachmentFlags.ParentToHand | Hand.AttachmentFlags.DetachFromOtherHand; + + [Tooltip( "Name of the attachment transform under in the hand's hierarchy which the object should should snap to." )] + public string attachmentPoint; + + [Tooltip( "How fast must this object be moving to attach due to a trigger hold instead of a trigger press?" )] + public float catchSpeedThreshold = 0.0f; + + [Tooltip( "When detaching the object, should it return to its original parent?" )] + public bool restoreOriginalParent = false; + + public bool attachEaseIn = false; + public AnimationCurve snapAttachEaseInCurve = AnimationCurve.EaseInOut( 0.0f, 0.0f, 1.0f, 1.0f ); + public float snapAttachEaseInTime = 0.15f; + public string[] attachEaseInAttachmentNames; + + private VelocityEstimator velocityEstimator; + private bool attached = false; + private float attachTime; + private Vector3 attachPosition; + private Quaternion attachRotation; + private Transform attachEaseInTransform; + + public UnityEvent onPickUp; + public UnityEvent onDetachFromHand; + + public bool snapAttachEaseInCompleted = false; + + + //------------------------------------------------- + void Awake() + { + velocityEstimator = GetComponent(); + + if ( attachEaseIn ) + { + attachmentFlags &= ~Hand.AttachmentFlags.SnapOnAttach; + } + + Rigidbody rb = GetComponent(); + rb.maxAngularVelocity = 50.0f; + } + + + //------------------------------------------------- + private void OnHandHoverBegin( Hand hand ) + { + bool showHint = false; + + // "Catch" the throwable by holding down the interaction button instead of pressing it. + // Only do this if the throwable is moving faster than the prescribed threshold speed, + // and if it isn't attached to another hand + if ( !attached ) + { + if ( hand.GetStandardInteractionButton() ) + { + Rigidbody rb = GetComponent(); + if ( rb.velocity.magnitude >= catchSpeedThreshold ) + { + hand.AttachObject( gameObject, attachmentFlags, attachmentPoint ); + showHint = false; + } + } + } + + if ( showHint ) + { + ControllerButtonHints.ShowButtonHint( hand, Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger ); + } + } + + + //------------------------------------------------- + private void OnHandHoverEnd( Hand hand ) + { + ControllerButtonHints.HideButtonHint( hand, Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger ); + } + + + //------------------------------------------------- + private void HandHoverUpdate( Hand hand ) + { + //Trigger got pressed + if ( hand.GetStandardInteractionButtonDown() ) + { + hand.AttachObject( gameObject, attachmentFlags, attachmentPoint ); + ControllerButtonHints.HideButtonHint( hand, Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger ); + } + } + + //------------------------------------------------- + private void OnAttachedToHand( Hand hand ) + { + attached = true; + + onPickUp.Invoke(); + + hand.HoverLock( null ); + + Rigidbody rb = GetComponent(); + rb.isKinematic = true; + rb.interpolation = RigidbodyInterpolation.None; + + if ( hand.controller == null ) + { + velocityEstimator.BeginEstimatingVelocity(); + } + + attachTime = Time.time; + attachPosition = transform.position; + attachRotation = transform.rotation; + + if ( attachEaseIn ) + { + attachEaseInTransform = hand.transform; + if ( !Util.IsNullOrEmpty( attachEaseInAttachmentNames ) ) + { + float smallestAngle = float.MaxValue; + for ( int i = 0; i < attachEaseInAttachmentNames.Length; i++ ) + { + Transform t = hand.GetAttachmentTransform( attachEaseInAttachmentNames[i] ); + float angle = Quaternion.Angle( t.rotation, attachRotation ); + if ( angle < smallestAngle ) + { + attachEaseInTransform = t; + smallestAngle = angle; + } + } + } + } + + snapAttachEaseInCompleted = false; + } + + + //------------------------------------------------- + private void OnDetachedFromHand( Hand hand ) + { + attached = false; + + onDetachFromHand.Invoke(); + + hand.HoverUnlock( null ); + + Rigidbody rb = GetComponent(); + rb.isKinematic = false; + rb.interpolation = RigidbodyInterpolation.Interpolate; + + Vector3 position = Vector3.zero; + Vector3 velocity = Vector3.zero; + Vector3 angularVelocity = Vector3.zero; + if ( hand.controller == null ) + { + velocityEstimator.FinishEstimatingVelocity(); + velocity = velocityEstimator.GetVelocityEstimate(); + angularVelocity = velocityEstimator.GetAngularVelocityEstimate(); + position = velocityEstimator.transform.position; + } + else + { + velocity = Player.instance.trackingOriginTransform.TransformVector( hand.controller.velocity ); + angularVelocity = Player.instance.trackingOriginTransform.TransformVector( hand.controller.angularVelocity ); + position = hand.transform.position; + } + + Vector3 r = transform.TransformPoint( rb.centerOfMass ) - position; + rb.velocity = velocity + Vector3.Cross( angularVelocity, r ); + rb.angularVelocity = angularVelocity; + + // Make the object travel at the release velocity for the amount + // of time it will take until the next fixed update, at which + // point Unity physics will take over + float timeUntilFixedUpdate = ( Time.fixedDeltaTime + Time.fixedTime ) - Time.time; + transform.position += timeUntilFixedUpdate * velocity; + float angle = Mathf.Rad2Deg * angularVelocity.magnitude; + Vector3 axis = angularVelocity.normalized; + transform.rotation *= Quaternion.AngleAxis( angle * timeUntilFixedUpdate, axis ); + } + + + //------------------------------------------------- + private void HandAttachedUpdate( Hand hand ) + { + //Trigger got released + if ( !hand.GetStandardInteractionButton() ) + { + // Detach ourselves late in the frame. + // This is so that any vehicles the player is attached to + // have a chance to finish updating themselves. + // If we detach now, our position could be behind what it + // will be at the end of the frame, and the object may appear + // to teleport behind the hand when the player releases it. + StartCoroutine( LateDetach( hand ) ); + } + + if ( attachEaseIn ) + { + float t = Util.RemapNumberClamped( Time.time, attachTime, attachTime + snapAttachEaseInTime, 0.0f, 1.0f ); + if ( t < 1.0f ) + { + t = snapAttachEaseInCurve.Evaluate( t ); + transform.position = Vector3.Lerp( attachPosition, attachEaseInTransform.position, t ); + transform.rotation = Quaternion.Lerp( attachRotation, attachEaseInTransform.rotation, t ); + } + else if ( !snapAttachEaseInCompleted ) + { + gameObject.SendMessage( "OnThrowableAttachEaseInCompleted", hand, SendMessageOptions.DontRequireReceiver ); + snapAttachEaseInCompleted = true; + } + } + } + + + //------------------------------------------------- + private IEnumerator LateDetach( Hand hand ) + { + yield return new WaitForEndOfFrame(); + + hand.DetachObject( gameObject, restoreOriginalParent ); + } + + + //------------------------------------------------- + private void OnHandFocusAcquired( Hand hand ) + { + gameObject.SetActive( true ); + velocityEstimator.BeginEstimatingVelocity(); + } + + + //------------------------------------------------- + private void OnHandFocusLost( Hand hand ) + { + gameObject.SetActive( false ); + velocityEstimator.FinishEstimatingVelocity(); + } + } +} diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/Throwable.cs.meta b/Assets/SteamVR/InteractionSystem/Core/Scripts/Throwable.cs.meta new file mode 100644 index 0000000..aa95cdf --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/Throwable.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ffefbea063cab884ca33e5a449e5c22c +timeCreated: 1432687610 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: b93fe5c516cf6ed4b9153ec790f856e2, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SteamVR/InteractionSystem/Core/Scripts/UIElement.cs b/Assets/SteamVR/InteractionSystem/Core/Scripts/UIElement.cs new file mode 100644 index 0000000..f536234 --- /dev/null +++ b/Assets/SteamVR/InteractionSystem/Core/Scripts/UIElement.cs @@ -0,0 +1,89 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: UIElement that responds to VR hands and generates UnityEvents +// +//============================================================================= + +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.UI; +using System; + +namespace Valve.VR.InteractionSystem +{ + //------------------------------------------------------------------------- + [RequireComponent( typeof( Interactable ) )] + public class UIElement : MonoBehaviour + { + public CustomEvents.UnityEventHand onHandClick; + + private Hand currentHand; + + //------------------------------------------------- + void Awake() + { + Button button = GetComponent