From 8dee20322ebefda037205d2d58646e43758d24aa Mon Sep 17 00:00:00 2001 From: "Theston E. Fox" Date: Sat, 17 Sep 2016 10:45:21 +0100 Subject: [PATCH] feat(Highlighters): add outline copy highlighter A new highlighter has been added that puts an outline around the object that it is applied to. It achieves this by making a copy of the object (or a provided mesh) and puts an outline shader on the object, which is toggled on when the highlight occurs. The highlighters have also been updated to have an `active` parameter on them which is used by scripted components to know which highlighter is the one to use when found on the component (as it may be required to put multiple highlighter components onto an object to toggle on and off). The Controller Actions script has also been updated to allow the sub elements of the controller to have a custom highlighter provided for each so it can override the main highlighter if needed. --- .../005_Controller_BasicObjectGrabbing.unity | 361 +++++++++++------- ...35_Controller_OpacityAndHighlighting.unity | 108 +++++- .../VRTK_ControllerAppearance_Example.cs | 20 +- .../VRTK/Materials/Resources/OutlineBasic.mat | 133 +++++++ .../Materials/Resources/OutlineBasic.mat.meta | 8 + Assets/VRTK/Scripts/Helper/Utilities.cs | 27 ++ .../Highlighters/VRTK_BaseHighlighter.cs | 19 + .../VRTK_MaterialColorSwapHighlighter.cs | 14 +- .../VRTK_OutlineObjectCopyHighlighter.cs | 143 +++++++ .../VRTK_OutlineObjectCopyHighlighter.cs.meta | 12 + .../Scripts/Shaders/VRTK_OutlineBasic.shader | 104 +++++ .../Shaders/VRTK_OutlineBasic.shader.meta | 9 + Assets/VRTK/Scripts/VRTK_ControllerActions.cs | 138 +++++-- Assets/VRTK/Scripts/VRTK_InteractGrab.cs | 2 + Assets/VRTK/Scripts/VRTK_InteractTouch.cs | 8 +- .../VRTK/Scripts/VRTK_InteractableObject.cs | 21 +- DOCUMENTATION.md | 139 ++++++- 17 files changed, 1065 insertions(+), 201 deletions(-) create mode 100644 Assets/VRTK/Materials/Resources/OutlineBasic.mat create mode 100644 Assets/VRTK/Materials/Resources/OutlineBasic.mat.meta create mode 100644 Assets/VRTK/Scripts/Highlighters/VRTK_OutlineObjectCopyHighlighter.cs create mode 100644 Assets/VRTK/Scripts/Highlighters/VRTK_OutlineObjectCopyHighlighter.cs.meta create mode 100644 Assets/VRTK/Scripts/Shaders/VRTK_OutlineBasic.shader create mode 100644 Assets/VRTK/Scripts/Shaders/VRTK_OutlineBasic.shader.meta diff --git a/Assets/VRTK/Examples/005_Controller_BasicObjectGrabbing.unity b/Assets/VRTK/Examples/005_Controller_BasicObjectGrabbing.unity index dab72cd6c..ae9ff75ed 100644 --- a/Assets/VRTK/Examples/005_Controller_BasicObjectGrabbing.unity +++ b/Assets/VRTK/Examples/005_Controller_BasicObjectGrabbing.unity @@ -206,12 +206,14 @@ MonoBehaviour: isDroppable: 1 isSwappable: 1 holdButtonToGrab: 1 + grabOverrideButton: 8 rumbleOnGrab: {x: 0, y: 0} allowedGrabControllers: 0 precisionSnap: 0 rightSnapHandle: {fileID: 0} leftSnapHandle: {fileID: 0} hideControllerOnGrab: 0 + stayGrabbedOnTeleport: 1 grabAttachMechanic: 0 detachThreshold: 1500 springJointStrength: 500 @@ -221,10 +223,12 @@ MonoBehaviour: isUsable: 0 useOnlyIfGrabbed: 0 holdButtonToUse: 1 + useOverrideButton: 8 pointerActivatesUseAction: 0 rumbleOnUse: {x: 0, y: 0} allowedUseControllers: 0 hideControllerOnUse: 0 + usingState: 0 --- !u!1 &365483936 GameObject: m_ObjectHideFlags: 0 @@ -238,6 +242,7 @@ GameObject: - 23: {fileID: 365483937} - 54: {fileID: 365483941} - 114: {fileID: 365483942} + - 114: {fileID: 365483943} m_Layer: 0 m_Name: Sphere_HightlightOnTouch m_TagString: Untagged @@ -341,12 +346,14 @@ MonoBehaviour: isDroppable: 1 isSwappable: 1 holdButtonToGrab: 1 + grabOverrideButton: 8 rumbleOnGrab: {x: 0, y: 0} allowedGrabControllers: 0 precisionSnap: 0 rightSnapHandle: {fileID: 0} leftSnapHandle: {fileID: 0} hideControllerOnGrab: 0 + stayGrabbedOnTeleport: 1 grabAttachMechanic: 0 detachThreshold: 1500 springJointStrength: 500 @@ -356,10 +363,27 @@ MonoBehaviour: isUsable: 0 useOnlyIfGrabbed: 0 holdButtonToUse: 1 + useOverrideButton: 8 pointerActivatesUseAction: 0 rumbleOnUse: {x: 0, y: 0} allowedUseControllers: 0 hideControllerOnUse: 0 + usingState: 0 +--- !u!114 &365483943 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 365483936} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c08517e04830d6d44a13c5ea5f574181, type: 3} + m_Name: + m_EditorClassIdentifier: + active: 1 + thickness: 0.5 + customOutlineModel: {fileID: 0} + customOutlineModelPath: --- !u!1 &394192772 GameObject: m_ObjectHideFlags: 0 @@ -481,7 +505,7 @@ Prefab: - target: {fileID: 3380982, guid: 4d293c8e162f3874b982baadd71153d2, type: 2} propertyPath: m_Mesh value: - objectReference: {fileID: 902129195} + objectReference: {fileID: 1148272791} - target: {fileID: 11489174, guid: 4d293c8e162f3874b982baadd71153d2, type: 2} propertyPath: drawInGame value: 1 @@ -554,6 +578,10 @@ Prefab: propertyPath: vertices.Array.data[7].z value: 0.9000001 objectReference: {fileID: 0} + - target: {fileID: 2348914, guid: 4d293c8e162f3874b982baadd71153d2, type: 2} + propertyPath: m_Materials.Array.data[0] + value: + objectReference: {fileID: 990790630} m_RemovedComponents: [] m_ParentPrefab: {fileID: 100100000, guid: 4d293c8e162f3874b982baadd71153d2, type: 2} m_IsPrefabParent: 0 @@ -608,6 +636,22 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d45c8d32f1d960d4498790bb3961fc52, type: 3} m_Name: m_EditorClassIdentifier: + modelElementPaths: + bodyModelPath: Model/body + triggerModelPath: Model/trigger + leftGripModelPath: Model/lgrip + rightGripModelPath: Model/rgrip + touchpadModelPath: Model/trackpad + appMenuModelPath: Model/button + systemMenuModelPath: Model/sys_button + elementHighlighterOverrides: + body: {fileID: 0} + trigger: {fileID: 0} + gripLeft: {fileID: 0} + gripRight: {fileID: 0} + touchpad: {fileID: 0} + appMenu: {fileID: 0} + systemMenu: {fileID: 0} --- !u!114 &477294388 MonoBehaviour: m_ObjectHideFlags: 0 @@ -626,6 +670,7 @@ MonoBehaviour: uiClickButton: 3 menuToggleButton: 7 axisFidelity: 1 + triggerClickThreshold: 1 triggerPressed: 0 triggerTouched: 0 triggerHairlinePressed: 0 @@ -684,6 +729,22 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d45c8d32f1d960d4498790bb3961fc52, type: 3} m_Name: m_EditorClassIdentifier: + modelElementPaths: + bodyModelPath: Model/body + triggerModelPath: Model/trigger + leftGripModelPath: Model/lgrip + rightGripModelPath: Model/rgrip + touchpadModelPath: Model/trackpad + appMenuModelPath: Model/button + systemMenuModelPath: Model/sys_button + elementHighlighterOverrides: + body: {fileID: 0} + trigger: {fileID: 0} + gripLeft: {fileID: 0} + gripRight: {fileID: 0} + touchpad: {fileID: 0} + appMenu: {fileID: 0} + systemMenu: {fileID: 0} --- !u!114 &477294392 MonoBehaviour: m_ObjectHideFlags: 0 @@ -702,6 +763,7 @@ MonoBehaviour: uiClickButton: 3 menuToggleButton: 7 axisFidelity: 1 + triggerClickThreshold: 1 triggerPressed: 0 triggerTouched: 0 triggerHairlinePressed: 0 @@ -833,12 +895,14 @@ MonoBehaviour: isDroppable: 1 isSwappable: 1 holdButtonToGrab: 1 + grabOverrideButton: 8 rumbleOnGrab: {x: 0, y: 0} allowedGrabControllers: 0 precisionSnap: 0 rightSnapHandle: {fileID: 0} leftSnapHandle: {fileID: 0} hideControllerOnGrab: 0 + stayGrabbedOnTeleport: 1 grabAttachMechanic: 0 detachThreshold: 1500 springJointStrength: 500 @@ -848,10 +912,12 @@ MonoBehaviour: isUsable: 0 useOnlyIfGrabbed: 0 holdButtonToUse: 1 + useOverrideButton: 8 pointerActivatesUseAction: 0 rumbleOnUse: {x: 0, y: 0} allowedUseControllers: 0 hideControllerOnUse: 0 + usingState: 0 --- !u!1 &597461890 GameObject: m_ObjectHideFlags: 0 @@ -1119,134 +1185,6 @@ Transform: m_Children: [] m_Father: {fileID: 743911481} m_RootOrder: 4 ---- !u!43 &902129195 -Mesh: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_Name: - serializedVersion: 8 - m_SubMeshes: - - serializedVersion: 2 - firstByte: 0 - indexCount: 24 - topology: 0 - firstVertex: 0 - vertexCount: 8 - localAABB: - m_Center: {x: 0, y: 0.01, z: 0} - m_Extent: {x: 1.2499999, y: 0, z: 0.9000001} - m_Shapes: - vertices: [] - shapes: [] - channels: [] - fullWeights: [] - m_BindPose: [] - m_BoneNameHashes: - m_RootBoneNameHash: 0 - m_MeshCompression: 0 - m_IsReadable: 1 - m_KeepVertices: 1 - m_KeepIndices: 1 - m_IndexBuffer: 000001000400010005000400010002000500020006000500020003000600030007000600030000000700000004000700 - m_Skin: [] - m_VertexData: - m_CurrentChannels: 13 - m_VertexCount: 8 - m_Channels: - - stream: 0 - offset: 0 - format: 0 - dimension: 3 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 12 - format: 0 - dimension: 4 - - stream: 0 - offset: 28 - format: 0 - dimension: 2 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - - stream: 0 - offset: 0 - format: 0 - dimension: 0 - m_DataSize: 288 - _typelessdata: cccc8c3f0ad7233c020040bf000000000000803f0000803f0000803f0000000000000000cccc8cbf0ad7233c020040bf000000000000803f0000803f0000803f0000803f00000000cccc8cbf0ad7233c0200403f000000000000803f0000803f0000803f0000000000000000cccc8c3f0ad7233c0200403f000000000000803f0000803f0000803f0000803f00000000ffff9f3f0ad7233c686666bf000000000000803f0000803f00000000000000000000803fffff9fbf0ad7233c686666bf000000000000803f0000803f000000000000803f0000803fffff9fbf0ad7233c6866663f000000000000803f0000803f00000000000000000000803fffff9f3f0ad7233c6866663f000000000000803f0000803f000000000000803f0000803f - m_CompressedMesh: - m_Vertices: - m_NumItems: 0 - m_Range: 0 - m_Start: 0 - m_Data: - m_BitSize: 0 - m_UV: - m_NumItems: 0 - m_Range: 0 - m_Start: 0 - m_Data: - m_BitSize: 0 - m_Normals: - m_NumItems: 0 - m_Range: 0 - m_Start: 0 - m_Data: - m_BitSize: 0 - m_Tangents: - m_NumItems: 0 - m_Range: 0 - m_Start: 0 - m_Data: - m_BitSize: 0 - m_Weights: - m_NumItems: 0 - m_Data: - m_BitSize: 0 - m_NormalSigns: - m_NumItems: 0 - m_Data: - m_BitSize: 0 - m_TangentSigns: - m_NumItems: 0 - m_Data: - m_BitSize: 0 - m_FloatColors: - m_NumItems: 0 - m_Range: 0 - m_Start: 0 - m_Data: - m_BitSize: 0 - m_BoneIndices: - m_NumItems: 0 - m_Data: - m_BitSize: 0 - m_Triangles: - m_NumItems: 0 - m_Data: - m_BitSize: 0 - m_UVInfo: 0 - m_LocalAABB: - m_Center: {x: 0, y: 0.01, z: 0} - m_Extent: {x: 1.2499999, y: 0, z: 0.9000001} - m_MeshUsageFlags: 0 - m_BakedConvexCollisionMesh: - m_BakedTriangleCollisionMesh: - m_MeshOptimized: 0 --- !u!1 &921052829 GameObject: m_ObjectHideFlags: 0 @@ -1405,6 +1343,35 @@ MeshFilter: m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 963637303} m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!21 &990790630 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: Sprites/Default + m_Shader: {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: PixelSnap + second: 0 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} --- !u!1 &1135670851 GameObject: m_ObjectHideFlags: 0 @@ -1484,6 +1451,134 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_RootOrder: 1 +--- !u!43 &1148272791 +Mesh: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: + serializedVersion: 8 + m_SubMeshes: + - serializedVersion: 2 + firstByte: 0 + indexCount: 24 + topology: 0 + firstVertex: 0 + vertexCount: 8 + localAABB: + m_Center: {x: 0, y: 0.01, z: 0} + m_Extent: {x: 1.2, y: 0, z: 1.0500002} + m_Shapes: + vertices: [] + shapes: [] + channels: [] + fullWeights: [] + m_BindPose: [] + m_BoneNameHashes: + m_RootBoneNameHash: 0 + m_MeshCompression: 0 + m_IsReadable: 1 + m_KeepVertices: 1 + m_KeepIndices: 1 + m_IndexBuffer: 000004000100010004000500010005000200020005000600020006000300030006000700030007000000000007000400 + m_Skin: [] + m_VertexData: + m_CurrentChannels: 13 + m_VertexCount: 8 + m_Channels: + - stream: 0 + offset: 0 + format: 0 + dimension: 3 + - stream: 0 + offset: 0 + format: 0 + dimension: 0 + - stream: 0 + offset: 12 + format: 0 + dimension: 4 + - stream: 0 + offset: 28 + format: 0 + dimension: 2 + - stream: 0 + offset: 0 + format: 0 + dimension: 0 + - stream: 0 + offset: 0 + format: 0 + dimension: 0 + - stream: 0 + offset: 0 + format: 0 + dimension: 0 + - stream: 0 + offset: 0 + format: 0 + dimension: 0 + m_DataSize: 288 + _typelessdata: 6766863f0ad7233c696666bf000000000000803f0000803f0000803f0000000000000000676686bf0ad7233c696666bf000000000000803f0000803f0000803f0000803f00000000676686bf0ad7233c6966663f000000000000803f0000803f0000803f00000000000000006766863f0ad7233c6966663f000000000000803f0000803f0000803f0000803f000000009a99993f0ad7233c686686bf000000000000803f0000803f00000000000000000000803f9a9999bf0ad7233c686686bf000000000000803f0000803f000000000000803f0000803f9a9999bf0ad7233c6866863f000000000000803f0000803f00000000000000000000803f9a99993f0ad7233c6866863f000000000000803f0000803f000000000000803f0000803f + m_CompressedMesh: + m_Vertices: + m_NumItems: 0 + m_Range: 0 + m_Start: 0 + m_Data: + m_BitSize: 0 + m_UV: + m_NumItems: 0 + m_Range: 0 + m_Start: 0 + m_Data: + m_BitSize: 0 + m_Normals: + m_NumItems: 0 + m_Range: 0 + m_Start: 0 + m_Data: + m_BitSize: 0 + m_Tangents: + m_NumItems: 0 + m_Range: 0 + m_Start: 0 + m_Data: + m_BitSize: 0 + m_Weights: + m_NumItems: 0 + m_Data: + m_BitSize: 0 + m_NormalSigns: + m_NumItems: 0 + m_Data: + m_BitSize: 0 + m_TangentSigns: + m_NumItems: 0 + m_Data: + m_BitSize: 0 + m_FloatColors: + m_NumItems: 0 + m_Range: 0 + m_Start: 0 + m_Data: + m_BitSize: 0 + m_BoneIndices: + m_NumItems: 0 + m_Data: + m_BitSize: 0 + m_Triangles: + m_NumItems: 0 + m_Data: + m_BitSize: 0 + m_UVInfo: 0 + m_LocalAABB: + m_Center: {x: 0, y: 0.01, z: 0} + m_Extent: {x: 1.2, y: 0, z: 1.0500002} + m_MeshUsageFlags: 0 + m_BakedConvexCollisionMesh: + m_BakedTriangleCollisionMesh: + m_MeshOptimized: 0 --- !u!1 &1382961361 GameObject: m_ObjectHideFlags: 0 @@ -1758,12 +1853,14 @@ MonoBehaviour: isDroppable: 1 isSwappable: 1 holdButtonToGrab: 1 + grabOverrideButton: 8 rumbleOnGrab: {x: 0, y: 0} allowedGrabControllers: 0 precisionSnap: 0 rightSnapHandle: {fileID: 0} leftSnapHandle: {fileID: 0} hideControllerOnGrab: 0 + stayGrabbedOnTeleport: 1 grabAttachMechanic: 0 detachThreshold: 1500 springJointStrength: 500 @@ -1773,10 +1870,12 @@ MonoBehaviour: isUsable: 0 useOnlyIfGrabbed: 0 holdButtonToUse: 1 + useOverrideButton: 8 pointerActivatesUseAction: 0 rumbleOnUse: {x: 0, y: 0} allowedUseControllers: 0 hideControllerOnUse: 0 + usingState: 0 --- !u!1 &1719093151 GameObject: m_ObjectHideFlags: 0 @@ -1831,12 +1930,14 @@ MonoBehaviour: isDroppable: 1 isSwappable: 1 holdButtonToGrab: 1 + grabOverrideButton: 8 rumbleOnGrab: {x: 0, y: 0} allowedGrabControllers: 0 precisionSnap: 0 rightSnapHandle: {fileID: 0} leftSnapHandle: {fileID: 0} hideControllerOnGrab: 0 + stayGrabbedOnTeleport: 1 grabAttachMechanic: 0 detachThreshold: 1500 springJointStrength: 500 @@ -1846,10 +1947,12 @@ MonoBehaviour: isUsable: 0 useOnlyIfGrabbed: 0 holdButtonToUse: 1 + useOverrideButton: 8 pointerActivatesUseAction: 0 rumbleOnUse: {x: 0, y: 0} allowedUseControllers: 0 hideControllerOnUse: 0 + usingState: 0 --- !u!54 &1719093154 Rigidbody: m_ObjectHideFlags: 0 diff --git a/Assets/VRTK/Examples/035_Controller_OpacityAndHighlighting.unity b/Assets/VRTK/Examples/035_Controller_OpacityAndHighlighting.unity index 02a2cbfeb..21a44828a 100644 --- a/Assets/VRTK/Examples/035_Controller_OpacityAndHighlighting.unity +++ b/Assets/VRTK/Examples/035_Controller_OpacityAndHighlighting.unity @@ -227,6 +227,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: dd076df6ddf5d40479de53c25f48c093, type: 3} m_Name: m_EditorClassIdentifier: + highlightBodyOnlyOnCollision: 0 --- !u!114 &217542883 MonoBehaviour: m_ObjectHideFlags: 0 @@ -245,6 +246,7 @@ MonoBehaviour: uiClickButton: 3 menuToggleButton: 7 axisFidelity: 1 + triggerClickThreshold: 1 triggerPressed: 0 triggerTouched: 0 triggerHairlinePressed: 0 @@ -271,6 +273,22 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d45c8d32f1d960d4498790bb3961fc52, type: 3} m_Name: m_EditorClassIdentifier: + modelElementPaths: + bodyModelPath: Model/body + triggerModelPath: Model/trigger + leftGripModelPath: Model/lgrip + rightGripModelPath: Model/rgrip + touchpadModelPath: Model/trackpad + appMenuModelPath: Model/button + systemMenuModelPath: Model/sys_button + elementHighlighterOverrides: + body: {fileID: 0} + trigger: {fileID: 0} + gripLeft: {fileID: 0} + gripRight: {fileID: 0} + touchpad: {fileID: 0} + appMenu: {fileID: 0} + systemMenu: {fileID: 0} --- !u!114 &217542885 MonoBehaviour: m_ObjectHideFlags: 0 @@ -326,12 +344,14 @@ MonoBehaviour: isDroppable: 1 isSwappable: 1 holdButtonToGrab: 1 + grabOverrideButton: 8 rumbleOnGrab: {x: 0, y: 0} allowedGrabControllers: 0 precisionSnap: 0 rightSnapHandle: {fileID: 0} leftSnapHandle: {fileID: 0} hideControllerOnGrab: 0 + stayGrabbedOnTeleport: 1 grabAttachMechanic: 0 detachThreshold: 1500 springJointStrength: 500 @@ -341,10 +361,12 @@ MonoBehaviour: isUsable: 0 useOnlyIfGrabbed: 0 holdButtonToUse: 1 + useOverrideButton: 8 pointerActivatesUseAction: 0 rumbleOnUse: {x: 0, y: 0} allowedUseControllers: 0 hideControllerOnUse: 0 + usingState: 0 --- !u!54 &604099642 Rigidbody: m_ObjectHideFlags: 0 @@ -783,7 +805,7 @@ Prefab: - target: {fileID: 3380982, guid: 4d293c8e162f3874b982baadd71153d2, type: 2} propertyPath: m_Mesh value: - objectReference: {fileID: 1713047491} + objectReference: {fileID: 2033724836} - target: {fileID: 11489174, guid: 4d293c8e162f3874b982baadd71153d2, type: 2} propertyPath: size value: 0 @@ -856,14 +878,51 @@ Prefab: propertyPath: drawInGame value: 1 objectReference: {fileID: 0} + - target: {fileID: 2348914, guid: 4d293c8e162f3874b982baadd71153d2, type: 2} + propertyPath: m_Materials.Array.data[0] + value: + objectReference: {fileID: 1417681013} m_RemovedComponents: [] m_ParentPrefab: {fileID: 100100000, guid: 4d293c8e162f3874b982baadd71153d2, type: 2} m_IsPrefabParent: 0 +--- !u!21 &1417681013 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: Sprites/Default + m_Shader: {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: PixelSnap + second: 0 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} --- !u!4 &1494182195 stripped Transform: m_PrefabParentObject: {fileID: 458974, guid: 4d293c8e162f3874b982baadd71153d2, type: 2} m_PrefabInternal: {fileID: 1188569437} ---- !u!43 &1713047491 +--- !u!4 &1950519925 stripped +Transform: + m_PrefabParentObject: {fileID: 402434, guid: 4d293c8e162f3874b982baadd71153d2, type: 2} + m_PrefabInternal: {fileID: 1188569437} +--- !u!43 &2033724836 Mesh: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} @@ -879,7 +938,7 @@ Mesh: vertexCount: 8 localAABB: m_Center: {x: 0, y: 0.01, z: 0} - m_Extent: {x: 1.2499999, y: 0, z: 0.9000001} + m_Extent: {x: 1.2, y: 0, z: 1.0500002} m_Shapes: vertices: [] shapes: [] @@ -892,7 +951,7 @@ Mesh: m_IsReadable: 1 m_KeepVertices: 1 m_KeepIndices: 1 - m_IndexBuffer: 000001000400010005000400010002000500020006000500020003000600030007000600030000000700000004000700 + m_IndexBuffer: 000004000100010004000500010005000200020005000600020006000300030006000700030007000000000007000400 m_Skin: [] m_VertexData: m_CurrentChannels: 13 @@ -931,7 +990,7 @@ Mesh: format: 0 dimension: 0 m_DataSize: 288 - _typelessdata: cccc8c3f0ad7233c020040bf000000000000803f0000803f0000803f0000000000000000cccc8cbf0ad7233c020040bf000000000000803f0000803f0000803f0000803f00000000cccc8cbf0ad7233c0200403f000000000000803f0000803f0000803f0000000000000000cccc8c3f0ad7233c0200403f000000000000803f0000803f0000803f0000803f00000000ffff9f3f0ad7233c686666bf000000000000803f0000803f00000000000000000000803fffff9fbf0ad7233c686666bf000000000000803f0000803f000000000000803f0000803fffff9fbf0ad7233c6866663f000000000000803f0000803f00000000000000000000803fffff9f3f0ad7233c6866663f000000000000803f0000803f000000000000803f0000803f + _typelessdata: 6766863f0ad7233c696666bf000000000000803f0000803f0000803f0000000000000000676686bf0ad7233c696666bf000000000000803f0000803f0000803f0000803f00000000676686bf0ad7233c6966663f000000000000803f0000803f0000803f00000000000000006766863f0ad7233c6966663f000000000000803f0000803f0000803f0000803f000000009a99993f0ad7233c686686bf000000000000803f0000803f00000000000000000000803f9a9999bf0ad7233c686686bf000000000000803f0000803f000000000000803f0000803f9a9999bf0ad7233c6866863f000000000000803f0000803f00000000000000000000803f9a99993f0ad7233c6866863f000000000000803f0000803f000000000000803f0000803f m_CompressedMesh: m_Vertices: m_NumItems: 0 @@ -986,15 +1045,11 @@ Mesh: m_UVInfo: 0 m_LocalAABB: m_Center: {x: 0, y: 0.01, z: 0} - m_Extent: {x: 1.2499999, y: 0, z: 0.9000001} + m_Extent: {x: 1.2, y: 0, z: 1.0500002} m_MeshUsageFlags: 0 m_BakedConvexCollisionMesh: m_BakedTriangleCollisionMesh: m_MeshOptimized: 0 ---- !u!4 &1950519925 stripped -Transform: - m_PrefabParentObject: {fileID: 402434, guid: 4d293c8e162f3874b982baadd71153d2, type: 2} - m_PrefabInternal: {fileID: 1188569437} --- !u!1 &2123877843 GameObject: m_ObjectHideFlags: 0 @@ -1080,6 +1135,7 @@ MonoBehaviour: uiClickButton: 3 menuToggleButton: 7 axisFidelity: 1 + triggerClickThreshold: 1 triggerPressed: 0 triggerTouched: 0 triggerHairlinePressed: 0 @@ -1106,6 +1162,22 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d45c8d32f1d960d4498790bb3961fc52, type: 3} m_Name: m_EditorClassIdentifier: + modelElementPaths: + bodyModelPath: Model/body + triggerModelPath: Model/trigger + leftGripModelPath: Model/lgrip + rightGripModelPath: Model/rgrip + touchpadModelPath: Model/trackpad + appMenuModelPath: Model/button + systemMenuModelPath: Model/sys_button + elementHighlighterOverrides: + body: {fileID: 2146663384} + trigger: {fileID: 0} + gripLeft: {fileID: 0} + gripRight: {fileID: 0} + touchpad: {fileID: 0} + appMenu: {fileID: 0} + systemMenu: {fileID: 0} --- !u!114 &2146663382 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1117,6 +1189,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: dd076df6ddf5d40479de53c25f48c093, type: 3} m_Name: m_EditorClassIdentifier: + highlightBodyOnlyOnCollision: 1 --- !u!114 &2146663383 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1132,3 +1205,18 @@ MonoBehaviour: hideControllerDelay: 0 globalTouchHighlightColor: {r: 0, g: 0, b: 0, a: 0} customRigidbodyObject: {fileID: 0} +--- !u!114 &2146663384 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2146663379} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c08517e04830d6d44a13c5ea5f574181, type: 3} + m_Name: + m_EditorClassIdentifier: + active: 0 + thickness: 0.2 + customOutlineModel: {fileID: 0} + customOutlineModelPath: diff --git a/Assets/VRTK/Examples/Resources/Scripts/VRTK_ControllerAppearance_Example.cs b/Assets/VRTK/Examples/Resources/Scripts/VRTK_ControllerAppearance_Example.cs index 5e1e6accd..b2b331df6 100644 --- a/Assets/VRTK/Examples/Resources/Scripts/VRTK_ControllerAppearance_Example.cs +++ b/Assets/VRTK/Examples/Resources/Scripts/VRTK_ControllerAppearance_Example.cs @@ -4,6 +4,8 @@ public class VRTK_ControllerAppearance_Example : MonoBehaviour { + public bool highlightBodyOnlyOnCollision = false; + private VRTK_ControllerTooltips tooltips; private VRTK_ControllerActions actions; private VRTK_ControllerEvents events; @@ -106,12 +108,26 @@ private void DoTouchpadReleased(object sender, ControllerInteractionEventArgs e) private void OnTriggerEnter(Collider collider) { - actions.ToggleHighlightController(true, Color.yellow, 0.4f); + if (highlightBodyOnlyOnCollision) + { + actions.ToggleHighlighBody(true, Color.yellow, 0.4f); + } + else + { + actions.ToggleHighlightController(true, Color.yellow, 0.4f); + } } private void OnTriggerExit(Collider collider) { - actions.ToggleHighlightController(false); + if (highlightBodyOnlyOnCollision) + { + actions.ToggleHighlighBody(false); + } + else + { + actions.ToggleHighlightController(false); + } } } } \ No newline at end of file diff --git a/Assets/VRTK/Materials/Resources/OutlineBasic.mat b/Assets/VRTK/Materials/Resources/OutlineBasic.mat new file mode 100644 index 000000000..909d05346 --- /dev/null +++ b/Assets/VRTK/Materials/Resources/OutlineBasic.mat @@ -0,0 +1,133 @@ +%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: OutlineBasic + m_Shader: {fileID: 4800000, guid: cbf236a56414a174fbf17d405f7da98f, type: 3} + 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: 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} + 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: _Thickness + 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} + - first: + name: _OutlineColor + second: {r: 1, g: 0, b: 0, a: 1} diff --git a/Assets/VRTK/Materials/Resources/OutlineBasic.mat.meta b/Assets/VRTK/Materials/Resources/OutlineBasic.mat.meta new file mode 100644 index 000000000..aa8fbb9b6 --- /dev/null +++ b/Assets/VRTK/Materials/Resources/OutlineBasic.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 97c9345d2c577e543b55b547a33c4858 +timeCreated: 1474104585 +licenseType: Pro +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRTK/Scripts/Helper/Utilities.cs b/Assets/VRTK/Scripts/Helper/Utilities.cs index aec95dd70..b31643130 100644 --- a/Assets/VRTK/Scripts/Helper/Utilities.cs +++ b/Assets/VRTK/Scripts/Helper/Utilities.cs @@ -1,6 +1,8 @@ namespace VRTK { using UnityEngine; + using System.Reflection; + using Highlighters; public class Utilities : MonoBehaviour { @@ -131,5 +133,30 @@ public static bool TagOrScriptCheck(GameObject obj, VRTK_TagOrScriptPolicyList t return (obj.tag == ignoreString || obj.GetComponent(ignoreString) != null); } } + + public static Component CloneComponent(Component source, GameObject destination) + { + Component tmpComponent = destination.gameObject.AddComponent(source.GetType()); + foreach (FieldInfo f in source.GetType().GetFields()) + { + f.SetValue(tmpComponent, f.GetValue(source)); + } + return tmpComponent; + } + + public static VRTK_BaseHighlighter GetActiveHighlighter(GameObject obj) + { + VRTK_BaseHighlighter objectHighlighter = null; + foreach (var tmpHighlighter in obj.GetComponents()) + { + if (tmpHighlighter.active) + { + objectHighlighter = tmpHighlighter; + break; + } + } + + return objectHighlighter; + } } } \ No newline at end of file diff --git a/Assets/VRTK/Scripts/Highlighters/VRTK_BaseHighlighter.cs b/Assets/VRTK/Scripts/Highlighters/VRTK_BaseHighlighter.cs index 5dd984256..b15709da9 100644 --- a/Assets/VRTK/Scripts/Highlighters/VRTK_BaseHighlighter.cs +++ b/Assets/VRTK/Scripts/Highlighters/VRTK_BaseHighlighter.cs @@ -12,6 +12,9 @@ namespace VRTK.Highlighters /// public abstract class VRTK_BaseHighlighter : MonoBehaviour { + [Tooltip("Determines if this highlighter is the active highlighter for the object the component is attached to. Only 1 active highlighter can be applied to a game object.")] + public bool active = true; + /// /// The Initalise method is used to set up the state of the highlighter. /// @@ -32,5 +35,21 @@ public abstract class VRTK_BaseHighlighter : MonoBehaviour /// An optional colour that could be used during the unhighlight phase. Usually will be left as null. /// An optional duration of how long before the unhighlight has occured. public abstract void Unhighlight(Color? color = null, float duration = 0f); + + /// + /// The GetOption method is used to return a value from the options array if the given key exists. + /// + /// The system type that is expected to be returned. + /// The dictionary of options to check in. + /// The identifier key to look for. + /// The value in the options at the given key returned in the provided system type. + public virtual T GetOption(Dictionary options, string key) + { + if (options != null && options.ContainsKey(key) && options[key] != null) + { + return (T)options[key]; + } + return default(T); + } } } \ No newline at end of file diff --git a/Assets/VRTK/Scripts/Highlighters/VRTK_MaterialColorSwapHighlighter.cs b/Assets/VRTK/Scripts/Highlighters/VRTK_MaterialColorSwapHighlighter.cs index 9cdfcacde..c21bdeb33 100644 --- a/Assets/VRTK/Scripts/Highlighters/VRTK_MaterialColorSwapHighlighter.cs +++ b/Assets/VRTK/Scripts/Highlighters/VRTK_MaterialColorSwapHighlighter.cs @@ -15,11 +15,14 @@ namespace VRTK.Highlighters /// /// This is the default highlighter that is applied to any script that requires a highlighting component (e.g. `VRTK_Interactable_Object` or `VRTK_ControllerActions`). /// + /// + /// `VRTK/Examples/005_Controller_BasicObjectGrabbing` demonstrates the solid highlighting on the green cube, red cube and flying saucer when the controller touches it. + /// + /// `VRTK/Examples/035_Controller_OpacityAndHighlighting` demonstrates the solid highlighting if the right controller collides with the green box or if any of the buttons are pressed. + /// public class VRTK_MaterialColorSwapHighlighter : VRTK_BaseHighlighter { - /// - /// The emission colour of the texture will be the highlight colour but this percent darker. - /// + [Tooltip("The emission colour of the texture will be the highlight colour but this percent darker.")] public float emissionDarken = 50f; private Dictionary originalSharedRendererMaterials; @@ -39,10 +42,7 @@ public override void Initialise(Color? color = null, Dictionary faderRoutines = new Dictionary(); StoreOriginalMaterials(); - if (options != null && options.ContainsKey("resetMainTexture") && options["resetMainTexture"] != null && options["resetMainTexture"] is bool) - { - resetMainTexture = (bool)options["resetMainTexture"]; - } + resetMainTexture = GetOption(options, "resetMainTexture"); } /// diff --git a/Assets/VRTK/Scripts/Highlighters/VRTK_OutlineObjectCopyHighlighter.cs b/Assets/VRTK/Scripts/Highlighters/VRTK_OutlineObjectCopyHighlighter.cs new file mode 100644 index 000000000..faa91d648 --- /dev/null +++ b/Assets/VRTK/Scripts/Highlighters/VRTK_OutlineObjectCopyHighlighter.cs @@ -0,0 +1,143 @@ +// Outline Object Copy|Highlighters|0030 +namespace VRTK.Highlighters +{ + using UnityEngine; + using System.Collections.Generic; + + /// + /// The Outline Object Copy Highlighter works by making a copy of a mesh and adding an outline shader to it and toggling the appearance of the highlighted object. + /// + /// + /// `VRTK/Examples/005_Controller_BasicObjectGrabbing` demonstrates the outline highlighting on the green sphere when the controller touches it. + /// + /// `VRTK/Examples/035_Controller_OpacityAndHighlighting` demonstrates the outline highlighting if the left controller collides with the green box. + /// + public class VRTK_OutlineObjectCopyHighlighter : VRTK_BaseHighlighter + { + [Tooltip("The thickness of the outline effect")] + public float thickness = 1f; + [Tooltip("The GameObject to use as the model to outline. If one isn't provided then the first GameObject with a valid Renderer in the current GameObject hierarchy will be used.")] + public GameObject customOutlineModel; + [Tooltip("A path to a GameObject to find at runtime, if the GameObject doesn't exist at edit time.")] + public string customOutlineModelPath = ""; + + private Material stencilOutline; + private GameObject highlightModel; + private string[] copyComponents = new string[] { "UnityEngine.MeshFilter", "UnityEngine.MeshRenderer" }; + + /// + /// The Initialise method sets up the highlighter for use. + /// + /// Not used. + /// A dictionary array containing the highlighter options:\r * `<'thickness', float>` - Same as `thickness` inspector parameter.\r * `<'customOutlineModel', GameObject>` - Same as `customOutlineModel` inspector parameter.\r * `<'customOutlineModelPath', string>` - Same as `customOutlineModelPath` inspector parameter. + public override void Initialise(Color? color = null, Dictionary options = null) + { + if (stencilOutline == null) + { + stencilOutline = Instantiate((Material)Resources.Load("OutlineBasic")); + } + SetOptions(options); + CreateHighlightModel(); + } + + /// + /// The Highlight method initiates the outline object to be enabled and display the outline colour. + /// + /// The colour to outline with. + /// Not used. + public override void Highlight(Color? color, float duration = 0f) + { + if (highlightModel) + { + stencilOutline.SetFloat("_Thickness", thickness); + stencilOutline.SetColor("_OutlineColor", (Color)color); + + highlightModel.SetActive(true); + } + } + + /// + /// The Unhighlight method hides the outline object and removes the outline colour. + /// + /// Not used. + /// Not used. + public override void Unhighlight(Color? color = null, float duration = 0f) + { + if (highlightModel) + { + highlightModel.SetActive(false); + } + } + + private void OnDestroy() + { + Destroy(highlightModel); + Destroy(stencilOutline); + } + + private void SetOptions(Dictionary options = null) + { + var tmpThickness = GetOption(options, "thickness"); + if (tmpThickness > 0f) + { + thickness = tmpThickness; + } + + var tmpCustomModel = GetOption(options, "customOutlineModel"); + if (tmpCustomModel != null) + { + customOutlineModel = tmpCustomModel; + } + + var tmpCustomModelPath = GetOption(options, "customOutlineModelPath"); + if (tmpCustomModelPath != null) + { + customOutlineModelPath = tmpCustomModelPath; + } + } + + private void CreateHighlightModel() + { + if (customOutlineModel != null) + { + customOutlineModel = (customOutlineModel.GetComponent() ? customOutlineModel : customOutlineModel.GetComponentInChildren().gameObject); + } + else if (customOutlineModelPath != "") + { + var getChildModel = transform.FindChild(customOutlineModelPath); + customOutlineModel = (getChildModel ? getChildModel.gameObject : null); + } + + GameObject copyModel = customOutlineModel; + if (copyModel == null) + { + copyModel = (GetComponent() ? gameObject : GetComponentInChildren().gameObject); + } + + if (copyModel == null) + { + Debug.LogError("No Renderer has been found on the model to add highlighting to"); + return; + } + + highlightModel = new GameObject(name + "_HighlightModel"); + highlightModel.transform.position = transform.position; + highlightModel.transform.rotation = transform.rotation; + highlightModel.transform.localScale = transform.localScale; + highlightModel.transform.SetParent(transform); + + foreach (var component in copyModel.GetComponents()) + { + if (System.Array.IndexOf(copyComponents, component.GetType().ToString()) >= 0) + { + Utilities.CloneComponent(component, highlightModel); + } + } + + var copyMesh = copyModel.GetComponent(); + highlightModel.GetComponent().mesh = copyMesh.mesh; + highlightModel.GetComponent().material = stencilOutline; + highlightModel.SetActive(false); + } + } +} \ No newline at end of file diff --git a/Assets/VRTK/Scripts/Highlighters/VRTK_OutlineObjectCopyHighlighter.cs.meta b/Assets/VRTK/Scripts/Highlighters/VRTK_OutlineObjectCopyHighlighter.cs.meta new file mode 100644 index 000000000..ce7f19f7b --- /dev/null +++ b/Assets/VRTK/Scripts/Highlighters/VRTK_OutlineObjectCopyHighlighter.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c08517e04830d6d44a13c5ea5f574181 +timeCreated: 1474101857 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRTK/Scripts/Shaders/VRTK_OutlineBasic.shader b/Assets/VRTK/Scripts/Shaders/VRTK_OutlineBasic.shader new file mode 100644 index 000000000..4a7007c81 --- /dev/null +++ b/Assets/VRTK/Scripts/Shaders/VRTK_OutlineBasic.shader @@ -0,0 +1,104 @@ +Shader "VRTK/OutlineBasic" +{ + Properties + { + _OutlineColor("Outline Color", Color) = (1, 0, 0, 1) + _Thickness("Thickness", float) = 1 + } + + SubShader + { + Tags + { + "Queue" = "Geometry" + "IgnoreProjector" = "True" + "RenderType" = "Transparent" + } + + // Fill the stencil buffer + Pass + { + Stencil + { + Ref 1 + Comp Always + Pass Replace + ZFail Replace + } + + ColorMask 0 + } + + // Draw the outline + Pass + { + Blend SrcAlpha OneMinusSrcAlpha + ZWrite Off // On (default) = Ignore lights etc. Should this be a property? + Stencil + { + Ref 0 + Comp Equal + } + + CGPROGRAM + #pragma vertex vert + #pragma geometry geom + #pragma fragment frag + + #include "UnityCG.cginc" + half4 _OutlineColor; + float _Thickness; + + struct appdata + { + float4 vertex : POSITION; + }; + + struct v2g + { + float4 pos : SV_POSITION; + }; + + v2g vert(appdata IN) + { + v2g OUT; + OUT.pos = UnityObjectToClipPos(IN.vertex); + return OUT; + } + + void geom2(v2g start, v2g end, inout TriangleStream triStream) + { + float width = _Thickness / 100; + float4 parallel = (end.pos - start.pos) * width; + float4 perpendicular = normalize(float4(parallel.y, -parallel.x, 0, 0)) * width; + float4 v1 = start.pos - parallel; + float4 v2 = end.pos + parallel; + v2g OUT; + OUT.pos = v1 - perpendicular; + triStream.Append(OUT); + OUT.pos = v1 + perpendicular; + triStream.Append(OUT); + OUT.pos = v2 - perpendicular; + triStream.Append(OUT); + OUT.pos = v2 + perpendicular; + triStream.Append(OUT); + } + + [maxvertexcount(12)] + void geom(triangle v2g IN[3], inout TriangleStream triStream) + { + geom2(IN[0], IN[1], triStream); + geom2(IN[1], IN[2], triStream); + geom2(IN[2], IN[0], triStream); + } + + half4 frag(v2g IN) : COLOR + { + _OutlineColor.a = 1; + return _OutlineColor; + } + ENDCG + } + } + FallBack "Diffuse" +} \ No newline at end of file diff --git a/Assets/VRTK/Scripts/Shaders/VRTK_OutlineBasic.shader.meta b/Assets/VRTK/Scripts/Shaders/VRTK_OutlineBasic.shader.meta new file mode 100644 index 000000000..afbfd979b --- /dev/null +++ b/Assets/VRTK/Scripts/Shaders/VRTK_OutlineBasic.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: cbf236a56414a174fbf17d405f7da98f +timeCreated: 1474101555 +licenseType: Pro +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRTK/Scripts/VRTK_ControllerActions.cs b/Assets/VRTK/Scripts/VRTK_ControllerActions.cs index ec0bda31a..5f991c17c 100644 --- a/Assets/VRTK/Scripts/VRTK_ControllerActions.cs +++ b/Assets/VRTK/Scripts/VRTK_ControllerActions.cs @@ -4,9 +4,32 @@ namespace VRTK using UnityEngine; using System.Collections; using System.Collections.Generic; - using System.Reflection; using Highlighters; + [System.Serializable] + public class VRTK_ControllerModelElementPaths + { + public string bodyModelPath = VRTK_SDK_Bridge.defaultBodyModelPath; + public string triggerModelPath = VRTK_SDK_Bridge.defaultTriggerModelPath; + public string leftGripModelPath = VRTK_SDK_Bridge.defaultGripLeftModelPath; + public string rightGripModelPath = VRTK_SDK_Bridge.defaultGripRightModelPath; + public string touchpadModelPath = VRTK_SDK_Bridge.defaultTouchpadModelPath; + public string appMenuModelPath = VRTK_SDK_Bridge.defaultApplicationMenuModelPath; + public string systemMenuModelPath = VRTK_SDK_Bridge.defaultSystemModelPath; + } + + [System.Serializable] + public struct VRTK_ControllerElementHighlighers + { + public VRTK_BaseHighlighter body; + public VRTK_BaseHighlighter trigger; + public VRTK_BaseHighlighter gripLeft; + public VRTK_BaseHighlighter gripRight; + public VRTK_BaseHighlighter touchpad; + public VRTK_BaseHighlighter appMenu; + public VRTK_BaseHighlighter systemMenu; + } + /// /// Event Payload /// @@ -32,10 +55,32 @@ public struct ControllerActionsEventArgs /// /// `VRTK/Examples/016_Controller_HapticRumble` demonstrates the ability to hide a controller model and make the controller vibrate for a given length of time at a given intensity. /// - /// `VRTK/Examples/035_Controller_OpacityAndHighlighting`demonstrates the ability to change the opacity of a controller model and to highlight specific elements of a controller such as the buttons or even the entire controller model. + /// `VRTK/Examples/035_Controller_OpacityAndHighlighting` demonstrates the ability to change the opacity of a controller model and to highlight specific elements of a controller such as the buttons or even the entire controller model. /// public class VRTK_ControllerActions : MonoBehaviour { + [Tooltip("A collection of strings that determine the path to the controller model sub elements for identifying the model parts at runtime. The paths will default to the model element paths of the selected SDK Bridge.\n\n" + + "* The available model sub elements are:\n\n" + + " * `Body Model Path`: The overall shape of the controller.\n" + + " * `Trigger Model Path`: The model that represents the trigger button.\n" + + " * `Grip Left Model Path`: The model that represents the left grip button.\n" + + " * `Grip Right Model Path`: The model that represents the right grip button.\n" + + " * `Touchpad Model Path`: The model that represents the touchpad.\n" + + " * `App Menu Model Path`: The model that represents the application menu button.\n" + + " * `System Menu Model Path`: The model that represents the system menu button.")] + public VRTK_ControllerModelElementPaths modelElementPaths; + + [Tooltip("A collection of highlighter overrides for each controller model sub element. If no highlighter override is given then highlighter on the Controller game object is used.\n\n" + + "* The available model sub elements are:\n\n" + + " * `Body`: The highlighter to use on the overall shape of the controller.\n" + + " * `Trigger`: The highlighter to use on the trigger button.\n" + + " * `Grip Left`: The highlighter to use on the left grip button.\n" + + " * `Grip Right`: The highlighter to use on the right grip button.\n" + + " * `Touchpad`: The highlighter to use on the touchpad.\n" + + " * `App Menu`: The highlighter to use on the application menu button.\n" + + " * `System Menu`: The highlighter to use on the system menu button.")] + public VRTK_ControllerElementHighlighers elementHighlighterOverrides; + /// /// Emitted when the controller model is toggled to be visible. /// @@ -233,7 +278,7 @@ public void ToggleHighlightTrigger(bool state, Color? highlight = null, float du { return; } - ToggleHighlightAlias(state, VRTK_SDK_Bridge.defaultTriggerModelPath, highlight, duration); + ToggleHighlightAlias(state, modelElementPaths.triggerModelPath, highlight, duration); } /// @@ -248,8 +293,8 @@ public void ToggleHighlightGrip(bool state, Color? highlight = null, float durat { return; } - ToggleHighlightAlias(state, VRTK_SDK_Bridge.defaultGripLeftModelPath, highlight, duration); - ToggleHighlightAlias(state, VRTK_SDK_Bridge.defaultGripRightModelPath, highlight, duration); + ToggleHighlightAlias(state, modelElementPaths.leftGripModelPath, highlight, duration); + ToggleHighlightAlias(state, modelElementPaths.rightGripModelPath, highlight, duration); } /// @@ -264,7 +309,7 @@ public void ToggleHighlightTouchpad(bool state, Color? highlight = null, float d { return; } - ToggleHighlightAlias(state, VRTK_SDK_Bridge.defaultTouchpadModelPath, highlight, duration); + ToggleHighlightAlias(state, modelElementPaths.touchpadModelPath, highlight, duration); } /// @@ -279,7 +324,22 @@ public void ToggleHighlightApplicationMenu(bool state, Color? highlight = null, { return; } - ToggleHighlightAlias(state, VRTK_SDK_Bridge.defaultApplicationMenuModelPath, highlight, duration); + ToggleHighlightAlias(state, modelElementPaths.appMenuModelPath, highlight, duration); + } + + /// + /// The ToggleHighlighBody method is a shortcut method that makes it easier to toggle the highlight state of the controller body element. + /// + /// The highlight colour state, `true` will enable the highlight on the body and `false` will remove the highlight from the body. + /// The colour to highlight the body with. + /// The duration of fade from white to the highlight colour. + public void ToggleHighlighBody(bool state, Color? highlight = null, float duration = 0f) + { + if (!state && controllerHighlighted) + { + return; + } + ToggleHighlightAlias(state, modelElementPaths.bodyModelPath, highlight, duration); } /// @@ -295,8 +355,8 @@ public void ToggleHighlightController(bool state, Color? highlight = null, float ToggleHighlightGrip(state, highlight, duration); ToggleHighlightTouchpad(state, highlight, duration); ToggleHighlightApplicationMenu(state, highlight, duration); - ToggleHighlightAlias(state, VRTK_SDK_Bridge.defaultSystemModelPath, highlight, duration); - ToggleHighlightAlias(state, VRTK_SDK_Bridge.defaultBodyModelPath, highlight, duration); + ToggleHighlightAlias(state, modelElementPaths.systemMenuModelPath, highlight, duration); + ToggleHighlightAlias(state, modelElementPaths.bodyModelPath, highlight, duration); } /// @@ -331,6 +391,31 @@ public void TriggerHapticPulse(ushort strength, float duration, float pulseInter StartCoroutine(HapticPulse(duration, hapticPulseStrength, pulseInterval)); } + /// + /// The InitaliseHighlighters method sets up the highlighters on the controller model. + /// + public void InitaliseHighlighters() + { + + highlighterOptions = new Dictionary(); + highlighterOptions.Add("resetMainTexture", true); + VRTK_BaseHighlighter objectHighlighter = Utilities.GetActiveHighlighter(gameObject); + + if (objectHighlighter == null) + { + objectHighlighter = gameObject.AddComponent(); + } + + objectHighlighter.Initialise(null, highlighterOptions); + AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultApplicationMenuModelPath), objectHighlighter, elementHighlighterOverrides.appMenu); + AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultBodyModelPath), objectHighlighter, elementHighlighterOverrides.body); + AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultGripLeftModelPath), objectHighlighter, elementHighlighterOverrides.gripLeft); + AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultGripRightModelPath), objectHighlighter, elementHighlighterOverrides.gripRight); + AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultSystemModelPath), objectHighlighter, elementHighlighterOverrides.systemMenu); + AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultTouchpadModelPath), objectHighlighter, elementHighlighterOverrides.touchpad); + AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultTriggerModelPath), objectHighlighter, elementHighlighterOverrides.trigger); + } + private void Awake() { gameObject.layer = LayerMask.NameToLayer("Ignore Raycast"); @@ -339,7 +424,7 @@ private void Awake() private void OnEnable() { - StartCoroutine(SetupHighlighter()); + StartCoroutine(WaitForModel()); } private void Update() @@ -347,42 +432,23 @@ private void Update() controllerIndex = VRTK_DeviceFinder.GetControllerIndex(gameObject); } - private IEnumerator SetupHighlighter() + private IEnumerator WaitForModel() { - highlighterOptions = new Dictionary(); - highlighterOptions.Add("resetMainTexture", true); - while (GetElementTransform(VRTK_SDK_Bridge.defaultBodyModelPath) == null) + while (GetElementTransform(modelElementPaths.bodyModelPath) == null) { yield return null; } - objectHighlighter = GetComponent(); - if (!objectHighlighter) - { - objectHighlighter = gameObject.AddComponent(); - } - - objectHighlighter.Initialise(null, highlighterOptions); - - AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultApplicationMenuModelPath), objectHighlighter); - AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultBodyModelPath), objectHighlighter); - AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultGripLeftModelPath), objectHighlighter); - AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultGripRightModelPath), objectHighlighter); - AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultSystemModelPath), objectHighlighter); - AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultTouchpadModelPath), objectHighlighter); - AddHighlighterToElement(GetElementTransform(VRTK_SDK_Bridge.defaultTriggerModelPath), objectHighlighter); + InitaliseHighlighters(); } - private void AddHighlighterToElement(Transform element, VRTK_BaseHighlighter highlighter) + private void AddHighlighterToElement(Transform element, VRTK_BaseHighlighter parentHighlighter, VRTK_BaseHighlighter overrideHighlighter) { if (element) { - VRTK_BaseHighlighter tmpComponent = (VRTK_BaseHighlighter)element.gameObject.AddComponent(highlighter.GetType()); - foreach (FieldInfo f in highlighter.GetType().GetFields()) - { - f.SetValue(tmpComponent, f.GetValue(highlighter)); - } - tmpComponent.Initialise(null, highlighterOptions); + var highlighter = (overrideHighlighter != null ? overrideHighlighter : parentHighlighter); + VRTK_BaseHighlighter clonedHighlighter = (VRTK_BaseHighlighter)Utilities.CloneComponent(highlighter, element.gameObject); + clonedHighlighter.Initialise(null, highlighterOptions); } } diff --git a/Assets/VRTK/Scripts/VRTK_InteractGrab.cs b/Assets/VRTK/Scripts/VRTK_InteractGrab.cs index efecee50b..d7bf7769c 100644 --- a/Assets/VRTK/Scripts/VRTK_InteractGrab.cs +++ b/Assets/VRTK/Scripts/VRTK_InteractGrab.cs @@ -385,6 +385,7 @@ private void InitGrabbedObject() if (!grabbedObjectScript.IsValidInteractableController(gameObject, grabbedObjectScript.allowedGrabControllers)) { grabbedObject = null; + interactTouch.ForceStopTouching(); return; } @@ -465,6 +466,7 @@ private void InitUngrabbedObject() grabEnabledState = 0; grabbedObject = null; + interactTouch.ForceStopTouching(); } private void ReleaseObject(bool withThrow) diff --git a/Assets/VRTK/Scripts/VRTK_InteractTouch.cs b/Assets/VRTK/Scripts/VRTK_InteractTouch.cs index 326b640c3..1c3a770f4 100644 --- a/Assets/VRTK/Scripts/VRTK_InteractTouch.cs +++ b/Assets/VRTK/Scripts/VRTK_InteractTouch.cs @@ -344,8 +344,12 @@ private void StopTouching(GameObject obj) } OnControllerUntouchInteractableObject(SetControllerInteractEvent(untouched.gameObject)); - untouched.GetComponent().StopTouching(gameObject); - untouched.GetComponent().ToggleHighlight(false); + var untouchedObjectScript = untouched.GetComponent(); + untouchedObjectScript.StopTouching(gameObject); + if (!untouchedObjectScript.IsTouched()) + { + untouchedObjectScript.ToggleHighlight(false); + } } if (updatedHideControllerOnTouch) diff --git a/Assets/VRTK/Scripts/VRTK_InteractableObject.cs b/Assets/VRTK/Scripts/VRTK_InteractableObject.cs index c45d60f15..2a98a15d2 100644 --- a/Assets/VRTK/Scripts/VRTK_InteractableObject.cs +++ b/Assets/VRTK/Scripts/VRTK_InteractableObject.cs @@ -177,6 +177,9 @@ public enum ControllerHideMode /// public event InteractableObjectEventHandler InteractableObjectUnused; + /// + /// The current using state of the object. `0` not being used, `1` being used. + /// [HideInInspector] public int usingState = 0; @@ -194,9 +197,8 @@ public enum ControllerHideMode protected bool previousIsGrabbable; protected bool forcedDropped; protected bool forceDisabled; - - private VRTK_BaseHighlighter objectHighlighter; - private bool autoHighlighter = false; + protected VRTK_BaseHighlighter objectHighlighter; + protected bool autoHighlighter = false; public virtual void OnInteractableObjectTouched(InteractableObjectEventArgs e) { @@ -399,11 +401,6 @@ public virtual void ToggleHighlight(bool toggle) /// The colour to use when highlighting the object. public virtual void ToggleHighlight(bool toggle, Color globalHighlightColor) { - if (IsTouched()) - { - return; - } - if (highlightOnTouch) { if (toggle && !IsGrabbed() && !IsUsing()) @@ -630,7 +627,7 @@ protected virtual void FixedUpdate() protected virtual void OnEnable() { - SetupHighlighter(); + InitialiseHighlighter(); RegisterTeleporters(); forceDisabled = false; if (forcedDropped) @@ -676,13 +673,13 @@ protected virtual void LoadPreviousState() } } - private void SetupHighlighter() + protected virtual void InitialiseHighlighter() { if (highlightOnTouch) { autoHighlighter = false; - objectHighlighter = GetComponent(); - if (!objectHighlighter) + objectHighlighter = Utilities.GetActiveHighlighter(gameObject); + if (objectHighlighter == null) { autoHighlighter = true; objectHighlighter = gameObject.AddComponent(); diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 735133823..ec06c0840 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -401,6 +401,7 @@ This directory contains scripts that are used to provide different object highli * [Base Highlighter](#base-highlighter-vrtk_basehighlighter) * [Material Colour Swap](#material-colour-swap-vrtk_materialcolorswaphighlighter) + * [Outline Object Copy](#outline-object-copy-vrtk_outlineobjectcopyhighlighter) --- @@ -412,6 +413,10 @@ The Base Highlighter is an abstract class that all other highlighters inherit an As this is an abstract class, it cannot be applied directly to a game object and performs no logic. +### Inspector Parameters + + * **Active:** Determines if this highlighter is the active highlighter for the object the component is attached to. Only 1 active highlighter can be applied to a game object. + ### Class Methods #### Initialise/2 @@ -450,6 +455,20 @@ The Highlight method is used to initiate the highlighting logic to apply to an o The Unhighlight method is used to initiate the logic that returns an object back to it's original appearance. +#### GetOption/2 + + > `public virtual T GetOption(Dictionary options, string key)` + + * Type Params + * `T` - The system type that is expected to be returned. + * Parameters + * `Dictionary options` - The dictionary of options to check in. + * `string key` - The identifier key to look for. + * Returns + * `T` - The value in the options at the given key returned in the provided system type. + +The GetOption method is used to return a value from the options array if the given key exists. + --- ## Material Colour Swap (VRTK_MaterialColorSwapHighlighter) @@ -465,9 +484,9 @@ The Draw Call Batching will resume on the original material when the item is no This is the default highlighter that is applied to any script that requires a highlighting component (e.g. `VRTK_Interactable_Object` or `VRTK_ControllerActions`). -### Class Variables +### Inspector Parameters - * `public float emissionDarken` - The emission colour of the texture will be the highlight colour but this percent darker. Default: `50f` + * **Emission Darken:** The emission colour of the texture will be the highlight colour but this percent darker. ### Class Methods @@ -508,6 +527,74 @@ The Highlight method initiates the change of colour on the object and will fade The Unhighlight method returns the object back to it's original colour. +### Example + +`VRTK/Examples/005_Controller_BasicObjectGrabbing` demonstrates the solid highlighting on the green cube, red cube and flying saucer when the controller touches it. + +`VRTK/Examples/035_Controller_OpacityAndHighlighting` demonstrates the solid highlighting if the right controller collides with the green box or if any of the buttons are pressed. + +--- + +## Outline Object Copy (VRTK_OutlineObjectCopyHighlighter) + > extends [VRTK_BaseHighlighter](#base-highlighter-vrtk_basehighlighter) + +### Overview + +The Outline Object Copy Highlighter works by making a copy of a mesh and adding an outline shader to it and toggling the appearance of the highlighted object. + +### Inspector Parameters + + * **Thickness:** The thickness of the outline effect + * **Custom Outline Model:** The GameObject to use as the model to outline. If one isn't provided then the first GameObject with a valid Renderer in the current GameObject hierarchy will be used. + * **Custom Outline Model Path:** A path to a GameObject to find at runtime, if the GameObject doesn't exist at edit time. + +### Class Methods + +#### Initialise/2 + + > `public override void Initialise(Color? color = null, Dictionary options = null)` + + * Parameters + * `Color? color` - Not used. + * `Dictionary options` - A dictionary array containing the highlighter options: + * `<'thickness', float>` - Same as `thickness` inspector parameter. + * `<'customOutlineModel', GameObject>` - Same as `customOutlineModel` inspector parameter. + * `<'customOutlineModelPath', string>` - Same as `customOutlineModelPath` inspector parameter. + * Returns + * _none_ + +The Initialise method sets up the highlighter for use. + +#### Highlight/2 + + > `public override void Highlight(Color? color, float duration = 0f)` + + * Parameters + * `Color? color` - The colour to outline with. + * `float duration` - Not used. + * Returns + * _none_ + +The Highlight method initiates the outline object to be enabled and display the outline colour. + +#### Unhighlight/2 + + > `public override void Unhighlight(Color? color = null, float duration = 0f)` + + * Parameters + * `Color? color` - Not used. + * `float duration` - Not used. + * Returns + * _none_ + +The Unhighlight method hides the outline object and removes the outline colour. + +### Example + +`VRTK/Examples/005_Controller_BasicObjectGrabbing` demonstrates the outline highlighting on the green sphere when the controller touches it. + +`VRTK/Examples/035_Controller_OpacityAndHighlighting` demonstrates the outline highlighting if the left controller collides with the green box. + --- # Scripts (VRTK/Scripts) @@ -774,6 +861,27 @@ The Controller Actions script provides helper methods to deal with common contro The highlighting of the controller is defaulted to use the `VRTK_MaterialColorSwapHighlighter` if no other highlighter is applied to the Object. +### Inspector Parameters + + * **Model Element Paths:** A collection of strings that determine the path to the controller model sub elements for identifying the model parts at runtime. The paths will default to the model element paths of the selected SDK Bridge. + * The available model sub elements are: + * `Body Model Path`: The overall shape of the controller. + * `Trigger Model Path`: The model that represents the trigger button. + * `Grip Left Model Path`: The model that represents the left grip button. + * `Grip Right Model Path`: The model that represents the right grip button. + * `Touchpad Model Path`: The model that represents the touchpad. + * `App Menu Model Path`: The model that represents the application menu button. + * `System Menu Model Path`: The model that represents the system menu button. + * **Element Highlighter Overrides:** A collection of highlighter overrides for each controller model sub element. If no highlighter override is given then highlighter on the Controller game object is used. + * The available model sub elements are: + * `Body`: The highlighter to use on the overall shape of the controller. + * `Trigger`: The highlighter to use on the trigger button. + * `Grip Left`: The highlighter to use on the left grip button. + * `Grip Right`: The highlighter to use on the right grip button. + * `Touchpad`: The highlighter to use on the touchpad. + * `App Menu`: The highlighter to use on the application menu button. + * `System Menu`: The highlighter to use on the system menu button. + ### Class Events * `ControllerModelVisible` - Emitted when the controller model is toggled to be visible. @@ -916,6 +1024,19 @@ The ToggleHighlightTouchpad method is a shortcut method that makes it easier to The ToggleHighlightApplicationMenu method is a shortcut method that makes it easier to toggle the highlight state of the controller application menu element. +#### ToggleHighlighBody/3 + + > `public void ToggleHighlighBody(bool state, Color? highlight = null, float duration = 0f)` + + * Parameters + * `bool state` - The highlight colour state, `true` will enable the highlight on the body and `false` will remove the highlight from the body. + * `Color? highlight` - The colour to highlight the body with. + * `float duration` - The duration of fade from white to the highlight colour. + * Returns + * _none_ + +The ToggleHighlighBody method is a shortcut method that makes it easier to toggle the highlight state of the controller body element. + #### ToggleHighlightController/3 > `public void ToggleHighlightController(bool state, Color? highlight = null, float duration = 0f)` @@ -953,11 +1074,22 @@ The TriggerHapticPulse/1 method calls a single haptic pulse call on the controll The TriggerHapticPulse/3 method calls a haptic pulse for a specified amount of time rather than just a single tick. Each pulse can be separated by providing a `pulseInterval` to pause between each haptic pulse. +#### InitaliseHighlighters/0 + + > `public void InitaliseHighlighters()` + + * Parameters + * _none_ + * Returns + * _none_ + +The InitaliseHighlighters method sets up the highlighters on the controller model. + ### Example `VRTK/Examples/016_Controller_HapticRumble` demonstrates the ability to hide a controller model and make the controller vibrate for a given length of time at a given intensity. -`VRTK/Examples/035_Controller_OpacityAndHighlighting`demonstrates the ability to change the opacity of a controller model and to highlight specific elements of a controller such as the buttons or even the entire controller model. +`VRTK/Examples/035_Controller_OpacityAndHighlighting` demonstrates the ability to change the opacity of a controller model and to highlight specific elements of a controller such as the buttons or even the entire controller model. --- @@ -1753,6 +1885,7 @@ The highlighting of an Interactable Object is defaulted to use the `VRTK_Materia * `Default` - Use the hide settings from the controller. * `OverrideHide` - Hide the controller when interacting, overriding controller settings. * `OverrideDontHide` - Don't hide the controller when interacting, overriding controller settings. + * `public int usingState` - The current using state of the object. `0` not being used, `1` being used. Default: `0` ### Class Events