diff --git a/Prefabs/Pointers.meta b/Prefabs/Pointers.meta
new file mode 100644
index 00000000..5729c18f
--- /dev/null
+++ b/Prefabs/Pointers.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e16b50fc4d479c3479d4bd866fc004ec
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Prefabs/Pointers/SharedResources.meta b/Prefabs/Pointers/SharedResources.meta
new file mode 100644
index 00000000..a4bd6772
--- /dev/null
+++ b/Prefabs/Pointers/SharedResources.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 19ae4898bfbf1d54aad099b8387a0556
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Prefabs/Pointers/SharedResources/Materials.meta b/Prefabs/Pointers/SharedResources/Materials.meta
new file mode 100644
index 00000000..a47a6314
--- /dev/null
+++ b/Prefabs/Pointers/SharedResources/Materials.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b2277dc64d10b534b9bc36f9b3d2c609
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Prefabs/Pointers/SharedResources/Materials/PointerDefaultInvalid.mat b/Prefabs/Pointers/SharedResources/Materials/PointerDefaultInvalid.mat
new file mode 100644
index 00000000..872bf6c6
--- /dev/null
+++ b/Prefabs/Pointers/SharedResources/Materials/PointerDefaultInvalid.mat
@@ -0,0 +1,76 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+ serializedVersion: 6
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 0}
+ m_Name: PointerDefaultInvalid
+ m_Shader: {fileID: 4800000, guid: c6488aa155d56e042b5ff808b89c7dda, type: 3}
+ m_ShaderKeywords:
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _BumpMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailAlbedoMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailMask:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailNormalMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _EmissionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MainTex:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MetallicGlossMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _OcclusionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _ParallaxMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Floats:
+ - _BumpScale: 1
+ - _Cutoff: 0.5
+ - _DetailNormalMapScale: 1
+ - _DstBlend: 0
+ - _GlossMapScale: 1
+ - _Glossiness: 0.5
+ - _GlossyReflections: 1
+ - _Metallic: 0
+ - _Mode: 0
+ - _OcclusionStrength: 1
+ - _Parallax: 0.02
+ - _SmoothnessTextureChannel: 0
+ - _SpecularHighlights: 1
+ - _SrcBlend: 1
+ - _UVSec: 0
+ - _ZWrite: 1
+ m_Colors:
+ - _Color: {r: 1, g: 0, b: 0, a: 0.5882353}
+ - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
diff --git a/Prefabs/Pointers/SharedResources/Materials/PointerDefaultInvalid.mat.meta b/Prefabs/Pointers/SharedResources/Materials/PointerDefaultInvalid.mat.meta
new file mode 100644
index 00000000..b4794be0
--- /dev/null
+++ b/Prefabs/Pointers/SharedResources/Materials/PointerDefaultInvalid.mat.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3ea92609994834245baf997807c5677c
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Prefabs/Pointers/SharedResources/Materials/PointerDefaultValid.mat b/Prefabs/Pointers/SharedResources/Materials/PointerDefaultValid.mat
new file mode 100644
index 00000000..577bb9fd
--- /dev/null
+++ b/Prefabs/Pointers/SharedResources/Materials/PointerDefaultValid.mat
@@ -0,0 +1,76 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+ serializedVersion: 6
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 0}
+ m_Name: PointerDefaultValid
+ m_Shader: {fileID: 4800000, guid: c6488aa155d56e042b5ff808b89c7dda, type: 3}
+ m_ShaderKeywords:
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _BumpMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailAlbedoMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailMask:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailNormalMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _EmissionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MainTex:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MetallicGlossMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _OcclusionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _ParallaxMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Floats:
+ - _BumpScale: 1
+ - _Cutoff: 0.5
+ - _DetailNormalMapScale: 1
+ - _DstBlend: 0
+ - _GlossMapScale: 1
+ - _Glossiness: 0.5
+ - _GlossyReflections: 1
+ - _Metallic: 0
+ - _Mode: 0
+ - _OcclusionStrength: 1
+ - _Parallax: 0.02
+ - _SmoothnessTextureChannel: 0
+ - _SpecularHighlights: 1
+ - _SrcBlend: 1
+ - _UVSec: 0
+ - _ZWrite: 1
+ m_Colors:
+ - _Color: {r: 0, g: 1, b: 0, a: 0.5882353}
+ - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
diff --git a/Prefabs/Pointers/SharedResources/Materials/PointerDefaultValid.mat.meta b/Prefabs/Pointers/SharedResources/Materials/PointerDefaultValid.mat.meta
new file mode 100644
index 00000000..ddbad4c8
--- /dev/null
+++ b/Prefabs/Pointers/SharedResources/Materials/PointerDefaultValid.mat.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 45363d50487514f40be10a6626b8874d
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Prefabs/Pointers/SolidParabolicPointer.prefab b/Prefabs/Pointers/SolidParabolicPointer.prefab
new file mode 100644
index 00000000..cab93f15
--- /dev/null
+++ b/Prefabs/Pointers/SolidParabolicPointer.prefab
@@ -0,0 +1,750 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1001 &100100000
+Prefab:
+ m_ObjectHideFlags: 1
+ serializedVersion: 2
+ m_Modification:
+ m_TransformParent: {fileID: 0}
+ m_Modifications: []
+ m_RemovedComponents: []
+ m_ParentPrefab: {fileID: 0}
+ m_RootGameObject: {fileID: 1426752779837614}
+ m_IsPrefabParent: 1
+--- !u!1 &1024888594135930
+GameObject:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4478373922372196}
+ m_Layer: 0
+ m_Name: Origin
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1228946520096640
+GameObject:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4918321818942956}
+ m_Layer: 0
+ m_Name: Destination
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1305827182902630
+GameObject:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4139760476663590}
+ m_Layer: 0
+ m_Name: RepeatedSegment
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1369825352190200
+GameObject:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4638500492178774}
+ - component: {fileID: 33546293906207260}
+ - component: {fileID: 23430509447262486}
+ m_Layer: 0
+ m_Name: InvalidDestination
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1426752779837614
+GameObject:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4038976375945052}
+ - component: {fileID: 114944504194883154}
+ - component: {fileID: 114877672256297274}
+ - component: {fileID: 114772459238973134}
+ - component: {fileID: 114824119824032106}
+ - component: {fileID: 114558492882398388}
+ m_Layer: 0
+ m_Name: SolidParabolicPointer
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1608149846681368
+GameObject:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4330820976336630}
+ - component: {fileID: 33997640587568034}
+ - component: {fileID: 23057258501909166}
+ m_Layer: 0
+ m_Name: ValidRepeatedSegment
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1715524685942652
+GameObject:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4254426469250956}
+ - component: {fileID: 33484454961722644}
+ - component: {fileID: 23912877453470822}
+ m_Layer: 0
+ m_Name: InvalidOrigin
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1737914218668402
+GameObject:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4435326370337958}
+ - component: {fileID: 33656412038164788}
+ - component: {fileID: 23059309742268982}
+ m_Layer: 0
+ m_Name: ValidDestination
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1740082415540204
+GameObject:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4302044503901880}
+ - component: {fileID: 33780494619393094}
+ - component: {fileID: 23292336185248774}
+ m_Layer: 0
+ m_Name: ValidOrigin
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1770204428611410
+GameObject:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4376415570113688}
+ - component: {fileID: 33707409387388250}
+ - component: {fileID: 23328632009384172}
+ m_Layer: 0
+ m_Name: InvalidRepeatedSegment
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &4038976375945052
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1426752779837614}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children:
+ - {fileID: 4478373922372196}
+ - {fileID: 4139760476663590}
+ - {fileID: 4918321818942956}
+ m_Father: {fileID: 0}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4139760476663590
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1305827182902630}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children:
+ - {fileID: 4330820976336630}
+ - {fileID: 4376415570113688}
+ m_Father: {fileID: 4038976375945052}
+ m_RootOrder: 1
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4254426469250956
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1715524685942652}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.005, y: 0.005, z: 0.005}
+ m_Children: []
+ m_Father: {fileID: 4478373922372196}
+ m_RootOrder: 1
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4302044503901880
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1740082415540204}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.005, y: 0.005, z: 0.005}
+ m_Children: []
+ m_Father: {fileID: 4478373922372196}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4330820976336630
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1608149846681368}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.005, y: 0.005, z: 0.005}
+ m_Children: []
+ m_Father: {fileID: 4139760476663590}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4376415570113688
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1770204428611410}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.005, y: 0.005, z: 0.005}
+ m_Children: []
+ m_Father: {fileID: 4139760476663590}
+ m_RootOrder: 1
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4435326370337958
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1737914218668402}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.05, y: 0.05, z: 0.05}
+ m_Children: []
+ m_Father: {fileID: 4918321818942956}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4478373922372196
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1024888594135930}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children:
+ - {fileID: 4302044503901880}
+ - {fileID: 4254426469250956}
+ m_Father: {fileID: 4038976375945052}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4638500492178774
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1369825352190200}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.05, y: 0.05, z: 0.05}
+ m_Children: []
+ m_Father: {fileID: 4918321818942956}
+ m_RootOrder: 1
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4918321818942956
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1228946520096640}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children:
+ - {fileID: 4435326370337958}
+ - {fileID: 4638500492178774}
+ m_Father: {fileID: 4038976375945052}
+ m_RootOrder: 2
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &23057258501909166
+MeshRenderer:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1608149846681368}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 4294967295
+ m_Materials:
+ - {fileID: 2100000, guid: 45363d50487514f40be10a6626b8874d, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ 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_StitchLightmapSeams: 0
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+--- !u!23 &23059309742268982
+MeshRenderer:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1737914218668402}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 4294967295
+ m_Materials:
+ - {fileID: 2100000, guid: 45363d50487514f40be10a6626b8874d, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ 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_StitchLightmapSeams: 0
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+--- !u!23 &23292336185248774
+MeshRenderer:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1740082415540204}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 4294967295
+ m_Materials:
+ - {fileID: 2100000, guid: 45363d50487514f40be10a6626b8874d, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ 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_StitchLightmapSeams: 0
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+--- !u!23 &23328632009384172
+MeshRenderer:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1770204428611410}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 4294967295
+ m_Materials:
+ - {fileID: 2100000, guid: 3ea92609994834245baf997807c5677c, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ 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_StitchLightmapSeams: 0
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+--- !u!23 &23430509447262486
+MeshRenderer:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1369825352190200}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 4294967295
+ m_Materials:
+ - {fileID: 2100000, guid: 3ea92609994834245baf997807c5677c, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ 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_StitchLightmapSeams: 0
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+--- !u!23 &23912877453470822
+MeshRenderer:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1715524685942652}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 4294967295
+ m_Materials:
+ - {fileID: 2100000, guid: 3ea92609994834245baf997807c5677c, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ 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_StitchLightmapSeams: 0
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+--- !u!33 &33484454961722644
+MeshFilter:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1715524685942652}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33546293906207260
+MeshFilter:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1369825352190200}
+ m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33656412038164788
+MeshFilter:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1737914218668402}
+ m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33707409387388250
+MeshFilter:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1770204428611410}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33780494619393094
+MeshFilter:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1740082415540204}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33997640587568034
+MeshFilter:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1608149846681368}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!114 &114558492882398388
+MonoBehaviour:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1426752779837614}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a11862926720f544fb5d904995c2b57b, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ process:
+ field: {fileID: 114944504194883154}
+ onlyProcessOnActiveAndEnabled: 1
+--- !u!114 &114772459238973134
+MonoBehaviour:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1426752779837614}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5195ecf61608495884b10998b2c6d117, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ activateOnEnable: 0
+ origin:
+ validObject: {fileID: 1740082415540204}
+ invalidObject: {fileID: 1715524685942652}
+ visibility: 0
+ repeatedSegment:
+ validObject: {fileID: 1608149846681368}
+ invalidObject: {fileID: 1770204428611410}
+ visibility: 0
+ destination:
+ validObject: {fileID: 1737914218668402}
+ invalidObject: {fileID: 1369825352190200}
+ visibility: 0
+ Activated:
+ m_PersistentCalls:
+ m_Calls: []
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ Deactivated:
+ m_PersistentCalls:
+ m_Calls: []
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ Entered:
+ m_PersistentCalls:
+ m_Calls: []
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ Exited:
+ m_PersistentCalls:
+ m_Calls: []
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ Hovering:
+ m_PersistentCalls:
+ m_Calls: []
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ Selected:
+ m_PersistentCalls:
+ m_Calls: []
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ RenderDataChanged:
+ m_PersistentCalls:
+ m_Calls:
+ - m_Target: {fileID: 114877672256297274}
+ m_MethodName: RenderData
+ m_Mode: 0
+ m_Arguments:
+ m_ObjectArgument: {fileID: 0}
+ m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+ m_IntArgument: 0
+ m_FloatArgument: 0
+ m_StringArgument:
+ m_BoolArgument: 0
+ m_CallState: 2
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointsRendererUnityEvent, Assembly-CSharp,
+ Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
+ BecameVisible:
+ m_PersistentCalls:
+ m_Calls:
+ - m_Target: {fileID: 114558492882398388}
+ m_MethodName: set_enabled
+ m_Mode: 6
+ m_Arguments:
+ m_ObjectArgument: {fileID: 0}
+ m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+ m_IntArgument: 0
+ m_FloatArgument: 0
+ m_StringArgument:
+ m_BoolArgument: 1
+ m_CallState: 2
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ BecameHidden:
+ m_PersistentCalls:
+ m_Calls:
+ - m_Target: {fileID: 114558492882398388}
+ m_MethodName: set_enabled
+ m_Mode: 6
+ m_Arguments:
+ m_ObjectArgument: {fileID: 0}
+ m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+ m_IntArgument: 0
+ m_FloatArgument: 0
+ m_StringArgument:
+ m_BoolArgument: 0
+ m_CallState: 2
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+--- !u!114 &114824119824032106
+MonoBehaviour:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1426752779837614}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5c0eab237e25807459af1c5caf4d3d33, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ momentToProcess: 5
+ processes:
+ - {fileID: 114558492882398388}
+--- !u!114 &114877672256297274
+MonoBehaviour:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1426752779837614}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 255407672fbf4289a8950abfa476e0b0, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ scaleDirection: {x: 0, y: 0, z: 1}
+ start: {fileID: 0}
+ repeatedSegment: {fileID: 0}
+ end: {fileID: 0}
+--- !u!114 &114944504194883154
+MonoBehaviour:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1426752779837614}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: f57b1a00a82f48d3a19652931fc4887d, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ physicsCast: {fileID: 0}
+ targetValidity: {fileID: 0}
+ CastResultsChanged:
+ m_PersistentCalls:
+ m_Calls:
+ - m_Target: {fileID: 114772459238973134}
+ m_MethodName: HandleData
+ m_Mode: 0
+ m_Arguments:
+ m_ObjectArgument: {fileID: 0}
+ m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+ m_IntArgument: 0
+ m_FloatArgument: 0
+ m_StringArgument:
+ m_BoolArgument: 0
+ m_CallState: 2
+ m_TypeName: VRTK.Core.Cast.PointsCast+PointsCastUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ maximumLength: {x: 10, y: Infinity}
+ heightLimitAngle: 100
+ segmentCount: 25
+ collisionCheckFrequency: 0
+ curveOffset: 1
diff --git a/Prefabs/Pointers/SolidParabolicPointer.prefab.meta b/Prefabs/Pointers/SolidParabolicPointer.prefab.meta
new file mode 100644
index 00000000..072cd187
--- /dev/null
+++ b/Prefabs/Pointers/SolidParabolicPointer.prefab.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 85ab5ffc906134f4792a21f10e948a12
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 100100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Prefabs/Pointers/SolidStraightPointer.prefab b/Prefabs/Pointers/SolidStraightPointer.prefab
new file mode 100644
index 00000000..5aaa2923
--- /dev/null
+++ b/Prefabs/Pointers/SolidStraightPointer.prefab
@@ -0,0 +1,746 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1001 &100100000
+Prefab:
+ m_ObjectHideFlags: 1
+ serializedVersion: 2
+ m_Modification:
+ m_TransformParent: {fileID: 0}
+ m_Modifications: []
+ m_RemovedComponents: []
+ m_ParentPrefab: {fileID: 0}
+ m_RootGameObject: {fileID: 1552269893497444}
+ m_IsPrefabParent: 1
+--- !u!1 &1076803578579894
+GameObject:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4687295873869394}
+ - component: {fileID: 33355895924255522}
+ - component: {fileID: 23655980069738472}
+ m_Layer: 0
+ m_Name: ValidOrigin
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1089809351942656
+GameObject:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4554141277845868}
+ m_Layer: 0
+ m_Name: Origin
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1151889711566436
+GameObject:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4618714272313756}
+ m_Layer: 0
+ m_Name: RepeatedSegment
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1195745717349208
+GameObject:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4470840868069594}
+ - component: {fileID: 33842711365439030}
+ - component: {fileID: 23813864600538518}
+ m_Layer: 0
+ m_Name: ValidDestination
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1268476617082826
+GameObject:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4603804475465888}
+ - component: {fileID: 33314063943023140}
+ - component: {fileID: 23699266861947568}
+ m_Layer: 0
+ m_Name: InvalidRepeatedSegment
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1496519822845236
+GameObject:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4579394868571944}
+ - component: {fileID: 33710724874815580}
+ - component: {fileID: 23383046084383780}
+ m_Layer: 0
+ m_Name: InvalidDestination
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1552269893497444
+GameObject:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4768196633265156}
+ - component: {fileID: 114710422162132952}
+ - component: {fileID: 114990274115864700}
+ - component: {fileID: 114112185610041394}
+ - component: {fileID: 114712552237190026}
+ - component: {fileID: 114365101931089768}
+ m_Layer: 0
+ m_Name: SolidStraightPointer
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1558147321532568
+GameObject:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4065798878235614}
+ - component: {fileID: 33408914329589152}
+ - component: {fileID: 23017688154559558}
+ m_Layer: 0
+ m_Name: ValidRepeatedSegment
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1685296751010734
+GameObject:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4744977143229268}
+ - component: {fileID: 33294981524400038}
+ - component: {fileID: 23581694834344394}
+ m_Layer: 0
+ m_Name: InvalidOrigin
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &1833070260010384
+GameObject:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 5
+ m_Component:
+ - component: {fileID: 4121294435962586}
+ m_Layer: 0
+ m_Name: Destination
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &4065798878235614
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1558147321532568}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.005, y: 0.005, z: 0.005}
+ m_Children: []
+ m_Father: {fileID: 4618714272313756}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4121294435962586
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1833070260010384}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children:
+ - {fileID: 4470840868069594}
+ - {fileID: 4579394868571944}
+ m_Father: {fileID: 4768196633265156}
+ m_RootOrder: 2
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4470840868069594
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1195745717349208}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.05, y: 0.05, z: 0.05}
+ m_Children: []
+ m_Father: {fileID: 4121294435962586}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4554141277845868
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1089809351942656}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children:
+ - {fileID: 4687295873869394}
+ - {fileID: 4744977143229268}
+ m_Father: {fileID: 4768196633265156}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4579394868571944
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1496519822845236}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.05, y: 0.05, z: 0.05}
+ m_Children: []
+ m_Father: {fileID: 4121294435962586}
+ m_RootOrder: 1
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4603804475465888
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1268476617082826}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.005, y: 0.005, z: 0.005}
+ m_Children: []
+ m_Father: {fileID: 4618714272313756}
+ m_RootOrder: 1
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4618714272313756
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1151889711566436}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children:
+ - {fileID: 4065798878235614}
+ - {fileID: 4603804475465888}
+ m_Father: {fileID: 4768196633265156}
+ m_RootOrder: 1
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4687295873869394
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1076803578579894}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.005, y: 0.005, z: 0.005}
+ m_Children: []
+ m_Father: {fileID: 4554141277845868}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4744977143229268
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1685296751010734}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.005, y: 0.005, z: 0.005}
+ m_Children: []
+ m_Father: {fileID: 4554141277845868}
+ m_RootOrder: 1
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4768196633265156
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1552269893497444}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children:
+ - {fileID: 4554141277845868}
+ - {fileID: 4618714272313756}
+ - {fileID: 4121294435962586}
+ m_Father: {fileID: 0}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &23017688154559558
+MeshRenderer:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1558147321532568}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 4294967295
+ m_Materials:
+ - {fileID: 2100000, guid: 45363d50487514f40be10a6626b8874d, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ 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_StitchLightmapSeams: 0
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+--- !u!23 &23383046084383780
+MeshRenderer:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1496519822845236}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 4294967295
+ m_Materials:
+ - {fileID: 2100000, guid: 3ea92609994834245baf997807c5677c, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ 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_StitchLightmapSeams: 0
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+--- !u!23 &23581694834344394
+MeshRenderer:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1685296751010734}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 4294967295
+ m_Materials:
+ - {fileID: 2100000, guid: 3ea92609994834245baf997807c5677c, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ 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_StitchLightmapSeams: 0
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+--- !u!23 &23655980069738472
+MeshRenderer:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1076803578579894}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 4294967295
+ m_Materials:
+ - {fileID: 2100000, guid: 45363d50487514f40be10a6626b8874d, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ 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_StitchLightmapSeams: 0
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+--- !u!23 &23699266861947568
+MeshRenderer:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1268476617082826}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 4294967295
+ m_Materials:
+ - {fileID: 2100000, guid: 3ea92609994834245baf997807c5677c, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ 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_StitchLightmapSeams: 0
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+--- !u!23 &23813864600538518
+MeshRenderer:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1195745717349208}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 4294967295
+ m_Materials:
+ - {fileID: 2100000, guid: 45363d50487514f40be10a6626b8874d, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ 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_StitchLightmapSeams: 0
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+--- !u!33 &33294981524400038
+MeshFilter:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1685296751010734}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33314063943023140
+MeshFilter:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1268476617082826}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33355895924255522
+MeshFilter:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1076803578579894}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33408914329589152
+MeshFilter:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1558147321532568}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33710724874815580
+MeshFilter:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1496519822845236}
+ m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33842711365439030
+MeshFilter:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1195745717349208}
+ m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!114 &114112185610041394
+MonoBehaviour:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1552269893497444}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5195ecf61608495884b10998b2c6d117, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ activateOnEnable: 0
+ origin:
+ validObject: {fileID: 1076803578579894}
+ invalidObject: {fileID: 1685296751010734}
+ visibility: 0
+ repeatedSegment:
+ validObject: {fileID: 1558147321532568}
+ invalidObject: {fileID: 1268476617082826}
+ visibility: 0
+ destination:
+ validObject: {fileID: 1195745717349208}
+ invalidObject: {fileID: 1496519822845236}
+ visibility: 0
+ Activated:
+ m_PersistentCalls:
+ m_Calls: []
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ Deactivated:
+ m_PersistentCalls:
+ m_Calls: []
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ Entered:
+ m_PersistentCalls:
+ m_Calls: []
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ Exited:
+ m_PersistentCalls:
+ m_Calls: []
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ Hovering:
+ m_PersistentCalls:
+ m_Calls: []
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ Selected:
+ m_PersistentCalls:
+ m_Calls: []
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ RenderDataChanged:
+ m_PersistentCalls:
+ m_Calls:
+ - m_Target: {fileID: 114990274115864700}
+ m_MethodName: RenderData
+ m_Mode: 0
+ m_Arguments:
+ m_ObjectArgument: {fileID: 0}
+ m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+ m_IntArgument: 0
+ m_FloatArgument: 0
+ m_StringArgument:
+ m_BoolArgument: 0
+ m_CallState: 2
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointsRendererUnityEvent, Assembly-CSharp,
+ Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
+ BecameVisible:
+ m_PersistentCalls:
+ m_Calls:
+ - m_Target: {fileID: 114365101931089768}
+ m_MethodName: set_enabled
+ m_Mode: 6
+ m_Arguments:
+ m_ObjectArgument: {fileID: 0}
+ m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+ m_IntArgument: 0
+ m_FloatArgument: 0
+ m_StringArgument:
+ m_BoolArgument: 1
+ m_CallState: 2
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ BecameHidden:
+ m_PersistentCalls:
+ m_Calls:
+ - m_Target: {fileID: 114365101931089768}
+ m_MethodName: set_enabled
+ m_Mode: 6
+ m_Arguments:
+ m_ObjectArgument: {fileID: 0}
+ m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+ m_IntArgument: 0
+ m_FloatArgument: 0
+ m_StringArgument:
+ m_BoolArgument: 0
+ m_CallState: 2
+ m_TypeName: VRTK.Core.Pointer.Pointer+PointerUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+--- !u!114 &114365101931089768
+MonoBehaviour:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1552269893497444}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a11862926720f544fb5d904995c2b57b, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ process:
+ field: {fileID: 114710422162132952}
+ onlyProcessOnActiveAndEnabled: 1
+--- !u!114 &114710422162132952
+MonoBehaviour:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1552269893497444}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 7934e9d7f2f8434c9358d4d4e8a14b6a, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ physicsCast: {fileID: 0}
+ targetValidity: {fileID: 0}
+ CastResultsChanged:
+ m_PersistentCalls:
+ m_Calls:
+ - m_Target: {fileID: 114112185610041394}
+ m_MethodName: HandleData
+ m_Mode: 0
+ m_Arguments:
+ m_ObjectArgument: {fileID: 0}
+ m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+ m_IntArgument: 0
+ m_FloatArgument: 0
+ m_StringArgument:
+ m_BoolArgument: 0
+ m_CallState: 2
+ m_TypeName: VRTK.Core.Cast.PointsCast+PointsCastUnityEvent, Assembly-CSharp, Version=0.0.0.0,
+ Culture=neutral, PublicKeyToken=null
+ maximumLength: 100
+--- !u!114 &114712552237190026
+MonoBehaviour:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1552269893497444}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5c0eab237e25807459af1c5caf4d3d33, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ momentToProcess: 5
+ processes:
+ - {fileID: 114365101931089768}
+--- !u!114 &114990274115864700
+MonoBehaviour:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 1552269893497444}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 255407672fbf4289a8950abfa476e0b0, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ scaleDirection: {x: 0, y: 0, z: 1}
+ start: {fileID: 0}
+ repeatedSegment: {fileID: 0}
+ end: {fileID: 0}
diff --git a/Prefabs/Pointers/SolidStraightPointer.prefab.meta b/Prefabs/Pointers/SolidStraightPointer.prefab.meta
new file mode 100644
index 00000000..f414335d
--- /dev/null
+++ b/Prefabs/Pointers/SolidStraightPointer.prefab.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 88f3454742388c943bc473e342a64467
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 100100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Cast.meta b/Scripts/Cast.meta
new file mode 100644
index 00000000..12655a0e
--- /dev/null
+++ b/Scripts/Cast.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 156756a9266a4c42a4c9363aee845395
+timeCreated: 1526407015
\ No newline at end of file
diff --git a/Scripts/Cast/ParabolicLineCast.cs b/Scripts/Cast/ParabolicLineCast.cs
new file mode 100644
index 00000000..da7b88a2
--- /dev/null
+++ b/Scripts/Cast/ParabolicLineCast.cs
@@ -0,0 +1,178 @@
+namespace VRTK.Core.Cast
+{
+ using UnityEngine;
+ using VRTK.Core.Utility;
+
+ ///
+ /// Casts a parabolic line and creates points at the origin, the target and in between.
+ ///
+ public class ParabolicLineCast : PointsCast
+ {
+ ///
+ /// Used to move the points back and up a bit to prevent the cast clipping at the collision points.
+ ///
+ protected const float ADJUSTMENT_OFFSET = 0.0001f;
+
+ ///
+ /// The maximum length of the projected cast. The x value is the length of the forward cast, the y value is the length of the downward cast.
+ ///
+ [Tooltip("The maximum length of the projected cast. The x value is the length of the forward cast, the y value is the length of the downward cast.")]
+ public Vector2 maximumLength = new Vector2(10f, float.PositiveInfinity);
+ ///
+ /// The maximum angle in degrees of the origin before the cast line height is restricted. A lower angle setting will prevent the cast being projected high into the sky and curving back down.
+ ///
+ [Range(1, 100)]
+ [Tooltip("The maximum angle in degrees of the origin before the cast line height is restricted. A lower angle setting will prevent the cast being projected high into the sky and curving back down.")]
+ public float heightLimitAngle = 100f;
+ ///
+ /// The number of points to generate on the parabolic line.
+ ///
+ /// The higher the number, the more CPU intensive the point generation becomes.
+ [Tooltip("The number of points to generate on the parabolic line. The higher the number, the more CPU intensive the point generation becomes.")]
+ public int segmentCount = 10;
+ ///
+ /// The number of points along the parabolic line to check for an early cast collision. Useful if the parabolic line is appearing to clip through locations. 0 won't make any checks and it will be capped at .
+ ///
+ /// The higher the number, the more CPU intensive the checks become.
+ [Tooltip("The number of points along the parabolic line to check for an early cast collision. Useful if the parabolic line is appearing to clip through locations. 0 won't make any checks and it will be capped at the set segment count. The higher the number, the more CPU intensive the checks become.")]
+ public int collisionCheckFrequency;
+ ///
+ /// The amount of height offset to apply to the projected cast to generate a smoother line even when the cast is pointing straight.
+ ///
+ [Tooltip("The amount of height offset to apply to the projected cast to generate a smoother line even when the cast is pointing straight.")]
+ public float curveOffset = 1f;
+
+ ///
+ public override void CastPoints()
+ {
+ Vector3 forward = ProjectForward();
+ Vector3 down = ProjectDown(forward);
+ GeneratePointsIncludingSegments(forward, down);
+ }
+
+ ///
+ /// Projects a straight line forward from the current .
+ ///
+ /// The collision point or the point being the furthest away on the cast line if nothing is hit.
+ protected virtual Vector3 ProjectForward()
+ {
+ float rotation = Vector3.Dot(Vector3.up, transform.forward.normalized);
+ float length = maximumLength.x;
+
+ if (rotation * 100f > heightLimitAngle)
+ {
+ float controllerRotationOffset = 1f - (rotation - heightLimitAngle / 100f);
+ length = maximumLength.x * controllerRotationOffset * controllerRotationOffset;
+ }
+
+ Ray ray = new Ray(transform.position, transform.forward);
+ RaycastHit hitData;
+ bool hasCollided = PhysicsCast.Raycast(physicsCast, ray, out hitData, length, Physics.IgnoreRaycastLayer);
+
+ // Adjust the cast length if something is blocking it.
+ if (hasCollided && hitData.distance < length)
+ {
+ length = hitData.distance;
+ }
+
+ // Use an offset to move the point back and up a bit to prevent the cast clipping at the collision point.
+ return ray.GetPoint(length - ADJUSTMENT_OFFSET) + Vector3.up * ADJUSTMENT_OFFSET;
+ }
+
+ ///
+ /// Projects a straight line downwards from the provided point.
+ ///
+ /// The origin of the projected line.
+ /// The collision point or the point being the furthest away on the cast line if nothing is hit.
+ protected virtual Vector3 ProjectDown(Vector3 origin)
+ {
+ Vector3 point = Vector3.zero;
+ Ray ray = new Ray(origin, Vector3.down);
+ RaycastHit hitData;
+
+ bool downRayHit = PhysicsCast.Raycast(physicsCast, ray, out hitData, maximumLength.y, Physics.IgnoreRaycastLayer);
+
+ if (!downRayHit || (TargetHit?.collider != null && TargetHit.Value.collider != hitData.collider))
+ {
+ TargetHit = null;
+ point = ray.GetPoint(0f);
+ }
+
+ if (downRayHit)
+ {
+ point = ray.GetPoint(hitData.distance);
+ TargetHit = hitData;
+ }
+
+ return point;
+ }
+
+ ///
+ /// Checks for collisions along the parabolic line segments and generates the final points.
+ ///
+ /// The forward direction to use for the checks.
+ /// The downwards direction to use for the checks.
+ protected virtual void GeneratePointsIncludingSegments(Vector3 forward, Vector3 down)
+ {
+ GeneratePoints(forward, down);
+
+ collisionCheckFrequency = Mathf.Clamp(collisionCheckFrequency, 0, segmentCount);
+ int step = segmentCount / (collisionCheckFrequency > 0 ? collisionCheckFrequency : 1);
+
+ for (int index = 0; index < segmentCount - step; index += step)
+ {
+ Vector3 currentPoint = points[index];
+ Vector3 nextPoint = index + step < points.Count ? points[index + step] : points[points.Count - 1];
+ Vector3 nextPointDirection = (nextPoint - currentPoint).normalized;
+ float nextPointDistance = Vector3.Distance(currentPoint, nextPoint);
+
+ Ray pointsRay = new Ray(currentPoint, nextPointDirection);
+ RaycastHit pointsHitData;
+
+ if (!PhysicsCast.Raycast(physicsCast, pointsRay, out pointsHitData, nextPointDistance, Physics.IgnoreRaycastLayer))
+ {
+ continue;
+ }
+
+ Vector3 collisionPoint = pointsRay.GetPoint(pointsHitData.distance);
+ Ray downwardRay = new Ray(collisionPoint + Vector3.up * 0.01f, Vector3.down);
+ RaycastHit downwardHitData;
+
+ if (!PhysicsCast.Raycast(physicsCast, downwardRay, out downwardHitData, float.PositiveInfinity, Physics.IgnoreRaycastLayer))
+ {
+ continue;
+ }
+
+ TargetHit = downwardHitData;
+
+ Vector3 newDownPosition = downwardRay.GetPoint(downwardHitData.distance);
+ Vector3 newJointPosition = newDownPosition.y < forward.y ? new Vector3(newDownPosition.x, forward.y, newDownPosition.z) : forward;
+ GeneratePoints(newJointPosition, newDownPosition);
+
+ break;
+ }
+
+ OnCastResultsChanged();
+ }
+
+ ///
+ /// Generates points on a parabolic line.
+ ///
+ /// The end point of the forward cast.
+ /// The end point of the down cast.
+ /// The generated points on the parabolic line.
+ protected virtual void GeneratePoints(Vector3 forward, Vector3 down)
+ {
+ Vector3[] curvePoints =
+ {
+ transform.position,
+ forward + new Vector3(0f, curveOffset, 0f),
+ down,
+ down
+ };
+
+ points.Clear();
+ points.AddRange(BezierCurveGenerator.GeneratePoints(segmentCount, curvePoints));
+ }
+ }
+}
diff --git a/Scripts/Cast/ParabolicLineCast.cs.meta b/Scripts/Cast/ParabolicLineCast.cs.meta
new file mode 100644
index 00000000..95258a9a
--- /dev/null
+++ b/Scripts/Cast/ParabolicLineCast.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: f57b1a00a82f48d3a19652931fc4887d
+timeCreated: 1526406952
\ No newline at end of file
diff --git a/Scripts/Utility/PhysicsCast.cs b/Scripts/Cast/PhysicsCast.cs
similarity index 98%
rename from Scripts/Utility/PhysicsCast.cs
rename to Scripts/Cast/PhysicsCast.cs
index a2d89fd0..19a8196e 100644
--- a/Scripts/Utility/PhysicsCast.cs
+++ b/Scripts/Cast/PhysicsCast.cs
@@ -1,4 +1,4 @@
-namespace VRTK.Core.Utility
+namespace VRTK.Core.Cast
{
using UnityEngine;
diff --git a/Scripts/Utility/PhysicsCast.cs.meta b/Scripts/Cast/PhysicsCast.cs.meta
similarity index 100%
rename from Scripts/Utility/PhysicsCast.cs.meta
rename to Scripts/Cast/PhysicsCast.cs.meta
diff --git a/Scripts/Cast/PointsCast.cs b/Scripts/Cast/PointsCast.cs
new file mode 100644
index 00000000..06166b31
--- /dev/null
+++ b/Scripts/Cast/PointsCast.cs
@@ -0,0 +1,107 @@
+namespace VRTK.Core.Cast
+{
+ using UnityEngine;
+ using UnityEngine.Events;
+ using System;
+ using System.Collections.Generic;
+ using VRTK.Core.Process;
+ using VRTK.Core.Utility;
+
+ ///
+ /// Contains information about the current state.
+ ///
+ public class PointsCastData
+ {
+ ///
+ /// The result of the most recent cast. when the cast didn't hit anything.
+ ///
+ public RaycastHit? targetHit;
+ ///
+ /// The points along the the most recent cast.
+ ///
+ public IReadOnlyList points;
+ }
+
+ ///
+ /// The base of casting components that result in points along the cast.
+ ///
+ public abstract class PointsCast : MonoBehaviour, IProcessable
+ {
+ ///
+ /// Allows to optionally affect the cast.
+ ///
+ [Tooltip("Allows to optionally affect the cast.")]
+ public PhysicsCast physicsCast;
+ ///
+ /// Allows to optionally determine targets based on the set rules.
+ ///
+ [Tooltip("Allows to optionally determine targets based on the set rules.")]
+ public ExclusionRule targetValidity;
+
+ ///
+ /// Defines the event with the state and sender .
+ ///
+ [Serializable]
+ public class PointsCastUnityEvent : UnityEvent
+ {
+ }
+
+ ///
+ /// Emitted whenever the cast result changes.
+ ///
+ public PointsCastUnityEvent CastResultsChanged = new PointsCastUnityEvent();
+
+ ///
+ /// The result of the most recent cast. when the cast didn't hit anything or an invalid target according to .
+ ///
+ public RaycastHit? TargetHit
+ {
+ get
+ {
+ return targetHit;
+ }
+ protected set
+ {
+ targetHit = value != null && !ExclusionRule.ShouldExclude(value.Value.transform.gameObject, targetValidity) ? value : null;
+ }
+ }
+
+ ///
+ /// The points along the the most recent cast.
+ ///
+ public IReadOnlyList Points => points;
+
+ protected List points = new List();
+
+ private RaycastHit? targetHit;
+
+ ///
+ /// Casts and creates points along the cast.
+ ///
+ public abstract void CastPoints();
+
+ ///
+ public void Process()
+ {
+ CastPoints();
+ }
+
+ ///
+ /// Builds the event payload for the current state of the cast.
+ ///
+ /// The current state of the cast.
+ protected virtual PointsCastData GetPayload()
+ {
+ return new PointsCastData
+ {
+ targetHit = TargetHit,
+ points = Points
+ };
+ }
+
+ protected virtual void OnCastResultsChanged()
+ {
+ CastResultsChanged?.Invoke(GetPayload(), this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Scripts/Cast/PointsCast.cs.meta b/Scripts/Cast/PointsCast.cs.meta
new file mode 100644
index 00000000..c9728400
--- /dev/null
+++ b/Scripts/Cast/PointsCast.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 8c527ebb1902401b89088eb9c8e627df
+timeCreated: 1526406894
\ No newline at end of file
diff --git a/Scripts/Cast/StraightLineCast.cs b/Scripts/Cast/StraightLineCast.cs
new file mode 100644
index 00000000..ff67d744
--- /dev/null
+++ b/Scripts/Cast/StraightLineCast.cs
@@ -0,0 +1,37 @@
+namespace VRTK.Core.Cast
+{
+ using UnityEngine;
+ using System.Linq;
+
+ ///
+ /// Casts a straight line and creates points at the origin and target.
+ ///
+ public class StraightLineCast : PointsCast
+ {
+ ///
+ /// The maximum length to cast.
+ ///
+ [Tooltip("The maximum length to cast.")]
+ public float maximumLength = 100f;
+
+ protected virtual void Awake()
+ {
+ points.Clear();
+ points.AddRange(Enumerable.Repeat(Vector3.zero, 2));
+ }
+
+ ///
+ public override void CastPoints()
+ {
+ Ray ray = new Ray(transform.position, transform.forward);
+ RaycastHit hitData;
+ bool hasCollided = PhysicsCast.Raycast(physicsCast, ray, out hitData, maximumLength, Physics.IgnoreRaycastLayer);
+ TargetHit = hasCollided ? hitData : (RaycastHit?)null;
+
+ points[0] = transform.position;
+ points[1] = hasCollided ? hitData.point : transform.position + transform.forward * maximumLength;
+
+ OnCastResultsChanged();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Scripts/Cast/StraightLineCast.cs.meta b/Scripts/Cast/StraightLineCast.cs.meta
new file mode 100644
index 00000000..7fec7946
--- /dev/null
+++ b/Scripts/Cast/StraightLineCast.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 7934e9d7f2f8434c9358d4d4e8a14b6a
+timeCreated: 1526406940
\ No newline at end of file
diff --git a/Scripts/Pointer.meta b/Scripts/Pointer.meta
new file mode 100644
index 00000000..ce99db63
--- /dev/null
+++ b/Scripts/Pointer.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 2a8115f519a29a948b2df09b1e703d7a
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Pointer/Pointer.cs b/Scripts/Pointer/Pointer.cs
new file mode 100644
index 00000000..64bf46a0
--- /dev/null
+++ b/Scripts/Pointer/Pointer.cs
@@ -0,0 +1,442 @@
+namespace VRTK.Core.Pointer
+{
+ using UnityEngine;
+ using UnityEngine.Events;
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using VRTK.Core.Cast;
+ using VRTK.Core.Data.Type;
+ using VRTK.Core.Visual;
+
+ ///
+ /// Contains information about the current state.
+ ///
+ public class PointerData : SurfaceData
+ {
+ ///
+ /// Whether the is currently activated.
+ ///
+ public bool isActive;
+ ///
+ /// Whether the is currently hovering over a target.
+ ///
+ public bool isHovering;
+ ///
+ /// The duration that the has been hovering over it's current target.
+ ///
+ public float hoverDuration;
+ ///
+ /// The points cast data given to the .
+ ///
+ public PointsCastData pointsCastData;
+ }
+
+ ///
+ /// Allows pointing at objects and notifies when a target is hit, continues to be hit or stops being hit by listening to a .
+ ///
+ public class Pointer : MonoBehaviour
+ {
+ ///
+ /// Describes an element of the rendered .
+ ///
+ [Serializable]
+ public class Element
+ {
+ ///
+ /// The visibility of an .
+ ///
+ public enum Visibility
+ {
+ ///
+ /// The will only be visible when the is activated.
+ ///
+ OnWhenPointerActivated,
+ ///
+ /// The will always be visible regardless of the state.
+ ///
+ AlwaysOn,
+ ///
+ /// The will never be visible regardless of the state.
+ ///
+ AlwaysOff
+ }
+
+ ///
+ /// Represents the when it's colliding with a valid object.
+ ///
+ [Tooltip("Represents the Element when it's colliding with a valid object.")]
+ public GameObject validObject;
+ ///
+ /// Represents the when it's colliding with an invalid object or not colliding at all.
+ ///
+ [Tooltip("Represents the Element when it's colliding with an invalid object or not colliding at all.")]
+ public GameObject invalidObject;
+ ///
+ /// Determines when the is visible.
+ ///
+ [Tooltip("Determines when the Element is visible.")]
+ public Visibility visibility = Visibility.OnWhenPointerActivated;
+ }
+
+ ///
+ /// Defines the event with the state and sender .
+ ///
+ /// The data is in case the isn't hitting any target.
+ [Serializable]
+ public class PointerUnityEvent : UnityEvent
+ {
+ }
+
+ ///
+ /// Defines the event with the state and sender .
+ ///
+ [Serializable]
+ public class PointsRendererUnityEvent : UnityEvent
+ {
+ }
+
+ ///
+ /// Determines if the should be automatically activated when the script is enabled.
+ ///
+ [Tooltip("Determines if the pointer should be automatically activated when the script is enabled.")]
+ public bool activateOnEnable;
+
+ ///
+ /// Represents the origin, i.e. the first rendered point.
+ ///
+ [Tooltip("Represents the origin, i.e. the first rendered point.")]
+ public Element origin;
+ ///
+ /// Represents the segments between and . This will get cloned to create all the segments.
+ ///
+ [Tooltip("Represents the segments between origin and destination. This will get cloned to create all the segments.")]
+ public Element repeatedSegment;
+ ///
+ /// Represents the destination, i.e. the last rendered point.
+ ///
+ [Tooltip("Represents the destination, i.e. the last rendered point.")]
+ public Element destination;
+
+ ///
+ /// The Activated event is emitted when the becomes active.
+ ///
+ public PointerUnityEvent Activated = new PointerUnityEvent();
+ ///
+ /// The Deactivated event is emitted when the becomes inactive.
+ ///
+ public PointerUnityEvent Deactivated = new PointerUnityEvent();
+ ///
+ /// Emitted when the collides with a new target.
+ ///
+ public PointerUnityEvent Entered = new PointerUnityEvent();
+ ///
+ /// Emitted when the stops colliding with an existing target.
+ ///
+ public PointerUnityEvent Exited = new PointerUnityEvent();
+ ///
+ /// Emitted when the changes its hovering position over an existing target.
+ ///
+ public PointerUnityEvent Hovering = new PointerUnityEvent();
+ ///
+ /// Emitted whenever is called.
+ ///
+ public PointerUnityEvent Selected = new PointerUnityEvent();
+ ///
+ /// Emitted when the elements change.
+ ///
+ public PointsRendererUnityEvent RenderDataChanged = new PointsRendererUnityEvent();
+ ///
+ /// Emitted when the becomes visible.
+ ///
+ public PointerUnityEvent BecameVisible = new PointerUnityEvent();
+ ///
+ /// Emitted when the becomes hidden.
+ ///
+ public PointerUnityEvent BecameHidden = new PointerUnityEvent();
+
+ ///
+ /// The activation state of the .
+ ///
+ public bool ActivationState
+ {
+ get;
+ protected set;
+ }
+
+ ///
+ /// Reports hover duration of the over the current target.
+ ///
+ public float HoverDuration
+ {
+ get;
+ protected set;
+ }
+
+ ///
+ /// Whether the is currently hovering over a target.
+ ///
+ /// if the is currently hovering over a target, otherwise.
+ public bool IsHovering => HoverDuration > 0f;
+
+ ///
+ /// Whether any of the is currently visible.
+ ///
+ public bool IsVisible
+ {
+ get
+ {
+ if (!enabled)
+ {
+ return false;
+ }
+
+ if (origin.visibility == Element.Visibility.AlwaysOff && repeatedSegment.visibility == Element.Visibility.AlwaysOff && destination.visibility == Element.Visibility.AlwaysOff)
+ {
+ return false;
+ }
+
+ if (origin.visibility == Element.Visibility.AlwaysOn || repeatedSegment.visibility == Element.Visibility.AlwaysOn || destination.visibility == Element.Visibility.AlwaysOn)
+ {
+ return true;
+ }
+
+ return ActivationState;
+ }
+ }
+
+ protected PointsCastData previousPointsCastData;
+ protected bool? previousVisibility;
+
+ ///
+ /// The current state of the .
+ ///
+ /// A object if the is currently hitting a target, otherwise.
+ public PointerData GetCurrentState()
+ {
+ return previousPointsCastData == null ? null : GetPayload(previousPointsCastData);
+ }
+
+ ///
+ /// The Activate method turns on the .
+ ///
+ public virtual void Activate()
+ {
+ ActivationState = true;
+ UpdateRenderData();
+ Activated?.Invoke(GetCurrentState(), this);
+ }
+
+ ///
+ /// The Deactivate method turns off the .
+ ///
+ public virtual void Deactivate()
+ {
+ ActivationState = false;
+ TryEmitExit(previousPointsCastData);
+ UpdateRenderData();
+ Deactivated?.Invoke(GetCurrentState(), this);
+ }
+
+ ///
+ /// Gets the current state and emits it through .
+ ///
+ public virtual void Select()
+ {
+ Selected?.Invoke(ActivationState ? GetCurrentState() : null, this);
+ }
+
+ ///
+ /// Handles the provided data to transition state and emit the events.
+ ///
+ /// The data describing the results of the most recent cast.
+ /// The initiator of this method.
+ public virtual void HandleData(PointsCastData data, object initiator = null)
+ {
+ if (data.targetHit != null)
+ {
+ Transform targetTransform = data.targetHit.Value.transform;
+ if (targetTransform != null && targetTransform != previousPointsCastData?.targetHit?.transform)
+ {
+ TryEmitExit(data);
+ OnEntered(data);
+ }
+
+ HoverDuration += Time.deltaTime;
+ OnHovering(data);
+ }
+ else
+ {
+ TryEmitExit(data);
+ }
+
+ previousPointsCastData = data;
+ UpdateRenderData();
+ }
+
+ protected virtual void OnEnable()
+ {
+ ActivationState = activateOnEnable;
+ TryEmitVisibilityEvent();
+ }
+
+ protected virtual void Update()
+ {
+ TryEmitVisibilityEvent();
+ }
+
+ ///
+ /// Updates the 's 's visibility and emits the event with the s used for the s.
+ ///
+ protected virtual void UpdateRenderData()
+ {
+ PointsRendererData data = new PointsRendererData
+ {
+ points = previousPointsCastData?.points ?? Array.Empty(),
+ start = GetElementRepresentation(origin),
+ repeatedSegment = GetElementRepresentation(repeatedSegment),
+ end = GetElementRepresentation(destination)
+ };
+
+ GameObject[] gameObjects =
+ {
+ origin.validObject,
+ origin.invalidObject,
+ repeatedSegment.validObject,
+ repeatedSegment.invalidObject,
+ destination.validObject,
+ destination.invalidObject
+ };
+ IEnumerable unusedGameObjects = gameObjects.Except(
+ new[]
+ {
+ data.start,
+ data.repeatedSegment,
+ data.end
+ })
+ .Concat(
+ new[]
+ {
+ repeatedSegment.validObject,
+ repeatedSegment.invalidObject
+ })
+ .Where(@object => @object != null);
+ foreach (GameObject unusedGameObject in unusedGameObjects)
+ {
+ unusedGameObject.SetActive(false);
+ }
+
+ IEnumerable usedGameObjects = new[]
+ {
+ data.start,
+ data.repeatedSegment,
+ data.end
+ }.Where(@object => @object != null);
+ foreach (GameObject usedGameObject in usedGameObjects)
+ {
+ usedGameObject.SetActive(true);
+ }
+
+ RenderDataChanged?.Invoke(data, this);
+ TryEmitVisibilityEvent();
+ }
+
+ ///
+ /// Checks to see if the is not currently colliding with a valid target and emits the event.
+ ///
+ /// The current points cast data.
+ protected virtual void TryEmitExit(PointsCastData data)
+ {
+ if (previousPointsCastData?.targetHit?.transform == null)
+ {
+ return;
+ }
+
+ HoverDuration = 0f;
+ OnExited(data);
+ previousPointsCastData = null;
+ }
+
+ ///
+ /// Emits the or event for the current state in case that state changed.
+ ///
+ protected virtual void TryEmitVisibilityEvent()
+ {
+ if (IsVisible == previousVisibility)
+ {
+ return;
+ }
+
+ previousVisibility = IsVisible;
+
+ if (IsVisible)
+ {
+ BecameVisible?.Invoke(GetCurrentState(), this);
+ }
+ else
+ {
+ BecameHidden?.Invoke(GetCurrentState(), this);
+ }
+ }
+
+ ///
+ /// Returns the used for a specific based on the current state.
+ ///
+ /// The to return a for.
+ /// A to represent .
+ protected virtual GameObject GetElementRepresentation(Element element)
+ {
+ bool isValid = previousPointsCastData?.targetHit != null;
+
+ switch (element.visibility)
+ {
+ case Element.Visibility.OnWhenPointerActivated:
+ return ActivationState ? (isValid ? element.validObject : element.invalidObject) : null;
+ case Element.Visibility.AlwaysOn:
+ return isValid ? element.validObject : element.invalidObject;
+ case Element.Visibility.AlwaysOff:
+ return null;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(element.visibility), element.visibility, null);
+ }
+ }
+
+ ///
+ /// Builds a valid payload to use in the events.
+ ///
+ /// A object of the 's current state.
+ protected virtual PointerData GetPayload(PointsCastData data)
+ {
+ Transform targetTransform = data.targetHit?.transform;
+ return new PointerData
+ {
+ transform = transform,
+ positionOverride = targetTransform == null ? (Vector3?)null : targetTransform.position,
+ rotationOverride = targetTransform == null ? (Quaternion?)null : targetTransform.rotation,
+ localScaleOverride = targetTransform == null ? (Vector3?)null : targetTransform.localScale,
+ origin = transform.position,
+ direction = transform.forward,
+ CollisionData = data.targetHit ?? default(RaycastHit),
+ isActive = ActivationState,
+ isHovering = IsHovering,
+ hoverDuration = HoverDuration,
+ pointsCastData = data
+ };
+ }
+
+ protected virtual void OnEntered(PointsCastData data)
+ {
+ Entered?.Invoke(GetPayload(data), this);
+ }
+
+ protected virtual void OnExited(PointsCastData data)
+ {
+ Exited?.Invoke(GetPayload(data), this);
+ }
+
+ protected virtual void OnHovering(PointsCastData data)
+ {
+ Hovering?.Invoke(GetPayload(data), this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Scripts/Pointer/Pointer.cs.meta b/Scripts/Pointer/Pointer.cs.meta
new file mode 100644
index 00000000..7250722d
--- /dev/null
+++ b/Scripts/Pointer/Pointer.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 5195ecf61608495884b10998b2c6d117
+timeCreated: 1526406779
\ No newline at end of file
diff --git a/Scripts/Tracking/SurfaceLocator.cs b/Scripts/Tracking/SurfaceLocator.cs
index d8894112..03601beb 100644
--- a/Scripts/Tracking/SurfaceLocator.cs
+++ b/Scripts/Tracking/SurfaceLocator.cs
@@ -3,6 +3,7 @@
using UnityEngine;
using UnityEngine.Events;
using System;
+ using VRTK.Core.Cast;
using VRTK.Core.Utility;
using VRTK.Core.Data.Type;
using VRTK.Core.Process;
diff --git a/Scripts/Utility/BezierCurveGenerator.cs b/Scripts/Utility/BezierCurveGenerator.cs
new file mode 100644
index 00000000..ea322a63
--- /dev/null
+++ b/Scripts/Utility/BezierCurveGenerator.cs
@@ -0,0 +1,52 @@
+namespace VRTK.Core.Utility
+{
+ using UnityEngine;
+ using System.Collections.Generic;
+
+ ///
+ /// A collection of helper methods generating points on a bezier curve.
+ ///
+ public static class BezierCurveGenerator
+ {
+ ///
+ /// Generates points on a bezier curve.
+ ///
+ /// The number of points to generate.
+ /// Points defining the bezier curve.
+ /// The generated points.
+ public static Vector3[] GeneratePoints(int count, Vector3[] controlPoints)
+ {
+ Vector3[] calculatedPoints = new Vector3[count];
+ float stepSize = count != 1 ? 1f / (count - 1) : count;
+
+ for (int f = 0; f < count; f++)
+ {
+ calculatedPoints[f] = GeneratePoint(controlPoints, f * stepSize);
+ }
+
+ return calculatedPoints;
+ }
+
+ private static Vector3 GeneratePoint(IReadOnlyList controlPoints, float t)
+ {
+ int index;
+ if (t >= 1f)
+ {
+ t = 1f;
+ index = controlPoints.Count - 4;
+ }
+ else
+ {
+ t = Mathf.Clamp01(t) * ((controlPoints.Count - 1) / 3f);
+ index = (int)t;
+ t -= index;
+ index *= 3;
+ }
+
+ float t1 = t;
+ t1 = Mathf.Clamp01(t1);
+ float oneMinusT = 1f - t1;
+ return oneMinusT * oneMinusT * oneMinusT * controlPoints[index] + 3f * oneMinusT * oneMinusT * t1 * controlPoints[index + 1] + 3f * oneMinusT * t1 * t1 * controlPoints[index + 2] + t1 * t1 * t1 * controlPoints[index + 3];
+ }
+ }
+}
diff --git a/Scripts/Utility/BezierCurveGenerator.cs.meta b/Scripts/Utility/BezierCurveGenerator.cs.meta
new file mode 100644
index 00000000..e326d7da
--- /dev/null
+++ b/Scripts/Utility/BezierCurveGenerator.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: a17fd115e2a54dbeb58716bc64cb8c7c
+timeCreated: 1526417342
\ No newline at end of file
diff --git a/Scripts/Utility/TransformExtensions.cs b/Scripts/Utility/TransformExtensions.cs
new file mode 100644
index 00000000..b56c20ca
--- /dev/null
+++ b/Scripts/Utility/TransformExtensions.cs
@@ -0,0 +1,18 @@
+namespace VRTK.Core.Utility
+{
+ using UnityEngine;
+
+ public static class TransformExtensions
+ {
+ ///
+ /// The SetGlobalScale method is used to set a transform scale based on a global scale instead of a local scale.
+ ///
+ /// The reference to the transform to scale.
+ /// A Vector3 of a global scale to apply to the given transform.
+ public static void SetGlobalScale(this Transform transform, Vector3 globalScale)
+ {
+ transform.localScale = Vector3.one;
+ transform.localScale = new Vector3(globalScale.x / transform.lossyScale.x, globalScale.y / transform.lossyScale.y, globalScale.z / transform.lossyScale.z);
+ }
+ }
+}
diff --git a/Scripts/Utility/TransformExtensions.cs.meta b/Scripts/Utility/TransformExtensions.cs.meta
new file mode 100644
index 00000000..4af8e183
--- /dev/null
+++ b/Scripts/Utility/TransformExtensions.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: a54e9605dd1c416e8f50e7e6943e3f9a
+timeCreated: 1526738386
\ No newline at end of file
diff --git a/Scripts/Visual/PointsRenderer.cs b/Scripts/Visual/PointsRenderer.cs
new file mode 100644
index 00000000..a13d0743
--- /dev/null
+++ b/Scripts/Visual/PointsRenderer.cs
@@ -0,0 +1,176 @@
+namespace VRTK.Core.Visual
+{
+ using UnityEngine;
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using VRTK.Core.Utility;
+
+ ///
+ /// Contains all the data needed for a to render.
+ ///
+ public class PointsRendererData
+ {
+ ///
+ /// The points along the the most recent cast.
+ ///
+ public IReadOnlyList points;
+
+ ///
+ /// Represents the start, i.e. the first rendered point.
+ ///
+ [Tooltip("Represents the start, i.e. the first rendered point.")]
+ public GameObject start;
+ ///
+ /// Represents the segments between and . This will get cloned to create all the segments.
+ ///
+ [Tooltip("Represents the segments between start and end. This will get cloned to create all the segments.")]
+ public GameObject repeatedSegment;
+ ///
+ /// Represents the end, i.e. the last rendered point.
+ ///
+ [Tooltip("Represents the end, i.e. the last rendered point.")]
+ public GameObject end;
+ }
+
+ ///
+ /// Renders points using s.
+ ///
+ public class PointsRenderer : MonoBehaviour
+ {
+ ///
+ /// The direction to scale the s in. Set axes to 0 to disable scaling on that axis.
+ ///
+ [Tooltip("The direction to scale the GameObjects in. Set axes to 0 to disable scaling on that axis.")]
+ public Vector3 scaleDirection = Vector3.forward;
+
+ ///
+ /// Represents the start, i.e. the first rendered point.
+ ///
+ [Tooltip("Represents the start, i.e. the first rendered point.")]
+ public GameObject start;
+ ///
+ /// Represents the segments between and . This will get cloned to create all the segments.
+ ///
+ [Tooltip("Represents the segments between start and end. This will get cloned to create all the segments.")]
+ public GameObject repeatedSegment;
+ ///
+ /// Represents the end, i.e. the last rendered point.
+ ///
+ [Tooltip("Represents the end, i.e. the last rendered point.")]
+ public GameObject end;
+
+ protected readonly List segmentClones = new List();
+
+ ///
+ /// Renders the given points.
+ ///
+ /// The data to render.
+ /// The initiator of this method.
+ public virtual void RenderData(PointsRendererData data, object initiator = null)
+ {
+ start = data.start;
+ end = data.end;
+
+ if (repeatedSegment != data.repeatedSegment)
+ {
+ segmentClones.ForEach(Destroy);
+ segmentClones.Clear();
+
+ repeatedSegment = data.repeatedSegment;
+ }
+
+ UpdateNumberOfClones(data.points);
+
+ UpdateElement(data.points, 0, false, start);
+ UpdateElement(data.points, data.points.Count - 1, false, end);
+
+ for (int index = 0; index < segmentClones.Count; index++)
+ {
+ UpdateElement(data.points, index, true, segmentClones[index]);
+ }
+ }
+
+ protected virtual void OnDisable()
+ {
+ segmentClones.ForEach(Destroy);
+ segmentClones.Clear();
+
+ foreach (GameObject @object in new[]
+ {
+ start,
+ repeatedSegment,
+ end
+ }.Where(@object => @object != null))
+ {
+ @object.SetActive(false);
+ }
+ }
+
+ ///
+ /// Ensures the number of cloned elements matches the provided number of points.
+ ///
+ /// The points to create cloned elements for.
+ protected virtual void UpdateNumberOfClones(IReadOnlyList points)
+ {
+ if (repeatedSegment == null)
+ {
+ return;
+ }
+
+ int targetCount = points.Count > 0 ? points.Count - 1 : 0;
+ for (int index = segmentClones.Count - 1; index >= targetCount; index--)
+ {
+ Destroy(segmentClones[index]);
+ segmentClones.RemoveAt(index);
+ }
+
+ for (int index = segmentClones.Count; index < targetCount; index++)
+ {
+ segmentClones.Add(Instantiate(repeatedSegment, repeatedSegment.transform.parent));
+ }
+ }
+
+ ///
+ /// Updates the element for a specific point.
+ ///
+ /// All points to render.
+ /// The index of the point that is represented by the element.
+ /// Whether the element is part of the line or alternatively it's representing a point.
+ /// The to use for rendering.
+ protected virtual void UpdateElement(IReadOnlyList points, int pointsIndex, bool isPartOfLine, GameObject @object)
+ {
+ if (@object == null || 0 > pointsIndex || pointsIndex >= points.Count)
+ {
+ return;
+ }
+
+ Vector3 targetPoint = points[pointsIndex];
+ Vector3 otherPoint = pointsIndex + 1 < points.Count ? points[pointsIndex + 1] : points[pointsIndex - 1];
+ Vector3 forward = otherPoint - targetPoint;
+ Vector3 position = isPartOfLine ? targetPoint + 0.5f * forward : targetPoint;
+ float scaleTarget = Mathf.Abs(Vector3.Distance(targetPoint, otherPoint));
+
+ @object.transform.position = position;
+
+ if (!isPartOfLine)
+ {
+ return;
+ }
+
+ @object.transform.forward = forward;
+
+ Vector3 scale = @object.transform.lossyScale;
+
+ for (int index = 0; index < 3; index++)
+ {
+ if (Math.Abs(scaleDirection[index]) >= float.Epsilon)
+ {
+ scale[index] = scaleDirection[index] * scaleTarget;
+ }
+ }
+
+ @object.transform.SetGlobalScale(scale);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Scripts/Visual/PointsRenderer.cs.meta b/Scripts/Visual/PointsRenderer.cs.meta
new file mode 100644
index 00000000..0945c50e
--- /dev/null
+++ b/Scripts/Visual/PointsRenderer.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 255407672fbf4289a8950abfa476e0b0
+timeCreated: 1526406857
\ No newline at end of file