deltavr multiplayer 2.0
This commit is contained in:
8
Assets/XRI_Examples/HoverHighlight/Audio.meta
Normal file
8
Assets/XRI_Examples/HoverHighlight/Audio.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1ce3259f8e6496439566d1ca947af58
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/XRI_Examples/HoverHighlight/Audio/Button_14_Hover.wav
LFS
Normal file
BIN
Assets/XRI_Examples/HoverHighlight/Audio/Button_14_Hover.wav
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,36 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d4ffba877e11574b83dd66ffe09c3e2
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 6
|
||||
defaultSettings:
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
platformSettingOverrides:
|
||||
4:
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 3
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
7:
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
preloadAudioData: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/XRI_Examples/HoverHighlight/Audio/Button_22_Click.wav
LFS
Normal file
BIN
Assets/XRI_Examples/HoverHighlight/Audio/Button_22_Click.wav
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,36 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4aa5e83ae912c46409c45fc3f4f5cfe4
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 6
|
||||
defaultSettings:
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
platformSettingOverrides:
|
||||
4:
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 3
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
7:
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
preloadAudioData: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/XRI_Examples/HoverHighlight/Materials.meta
Normal file
8
Assets/XRI_Examples/HoverHighlight/Materials.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed74ffa6716bb604cb48ac80e594231f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,110 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: InteractablePulse
|
||||
m_Shader: {fileID: 4800000, guid: 64dbf9ec24b89d54d96a3ec606b5c84c, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DecalTex:
|
||||
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}
|
||||
- _EdgeTex:
|
||||
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_Ints: []
|
||||
m_Floats:
|
||||
- _BlendOp: 0
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DistanceFadeFactor: 0.295
|
||||
- _DstBlend: 0
|
||||
- _EdgeGradient: 1
|
||||
- _Fade: 0.5
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _GradientSize: 2
|
||||
- _MaxDistance: 72.1
|
||||
- _Metallic: 0
|
||||
- _MinFade: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _PulseMaxAlpha: 0.5
|
||||
- _PulseMinAlpha: 0.5
|
||||
- _PulseSpeed: 0
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _WaveMaxAlpha: 0.107
|
||||
- _WaveMinAlpha: 0.524
|
||||
- _WaveSize: 25.6
|
||||
- _WaveSpeed: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Center: {r: 13.784426, g: 2.784858, b: 0.45263284, a: 0}
|
||||
- _Color: {r: 0.25, g: 0.7, b: 0.9, a: 1}
|
||||
- _DecalPositionOffset: {r: 0, g: 0, b: 0, a: 0}
|
||||
- _DecalSize: {r: 1, g: 1, b: 0, a: 0}
|
||||
- _EdgeColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EdgeData: {r: 0, g: 0.85, b: 0.5, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7300d560c891a2441b8b283147b5bcbb
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/XRI_Examples/HoverHighlight/Prefabs.meta
Normal file
8
Assets/XRI_Examples/HoverHighlight/Prefabs.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca996f2ef10684944b8b6b826b8f5842
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,295 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &566179490935405789
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 566179490935405797}
|
||||
- component: {fileID: 566179490935405791}
|
||||
- component: {fileID: 566179490935405793}
|
||||
- component: {fileID: 566179490935405792}
|
||||
- component: {fileID: 566179490935405790}
|
||||
- component: {fileID: 566179490935405760}
|
||||
m_Layer: 0
|
||||
m_Name: HoverStateVisuals_Full
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &566179490935405797
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 566179490935405789}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &566179490935405791
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 566179490935405789}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: bc812c2b9f69cb94ea80d24d6b974fcc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_AudioHover: {fileID: 566179490935405790}
|
||||
m_AudioClick: {fileID: 566179490935405760}
|
||||
m_HighlightController:
|
||||
m_RendererCaptureDepth: 0
|
||||
m_ManuallySetRenderers: []
|
||||
m_OutlineHighlight: {fileID: 566179490935405793}
|
||||
m_MaterialHighlight: {fileID: 566179490935405792}
|
||||
m_HoverColor: {r: 0.25, g: 0.7, b: 0.9, a: 1}
|
||||
m_HoverPriorityColor: {r: 0.09411765, g: 0.4392157, b: 0.7137255, a: 1}
|
||||
m_SelectionColor: {r: 1, g: 0.4, b: 0, a: 1}
|
||||
m_PlayMaterialActivateAnim: 1
|
||||
m_PlayOutlineActivateAnim: 0
|
||||
m_HighlightOnHover: 1
|
||||
m_HighlightOnHoverPriority: 1
|
||||
m_HighlightOnSelect: 1
|
||||
m_HighlightOnActivate: 1
|
||||
--- !u!114 &566179490935405793
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 566179490935405789}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5bad813e71e6dea43a3833ba919c1e1b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HighlightMode: 0
|
||||
m_OutlineSource: 0
|
||||
m_Shader: {fileID: 4800000, guid: 7200aef8a341733498b6598b176e0828, type: 3}
|
||||
m_HighlightMaterial: {fileID: 0}
|
||||
m_TransitionWidth: 1
|
||||
m_OutlineScale: 0.75
|
||||
m_StartingOutlineScale: 0
|
||||
m_TransitionColor: 1
|
||||
m_OutlineColor: {r: 0.9254902, g: 0.5176471, b: 0.03529412, a: 1}
|
||||
m_StartingOutlineColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_TransitionDuration: 0
|
||||
m_StartWithMaterialValues: 0
|
||||
--- !u!114 &566179490935405792
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 566179490935405789}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 2ecee6e1c65d5fa4a8f931a3f7e79229, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HighlightMode: 0
|
||||
m_HighlightMaterial: {fileID: 2100000, guid: 7300d560c891a2441b8b283147b5bcbb, type: 2}
|
||||
--- !u!82 &566179490935405790
|
||||
AudioSource:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 566179490935405789}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 4
|
||||
OutputAudioMixerGroup: {fileID: 0}
|
||||
m_audioClip: {fileID: 8300000, guid: 1d4ffba877e11574b83dd66ffe09c3e2, type: 3}
|
||||
m_PlayOnAwake: 0
|
||||
m_Volume: 1
|
||||
m_Pitch: 1
|
||||
Loop: 0
|
||||
Mute: 0
|
||||
Spatialize: 0
|
||||
SpatializePostEffects: 0
|
||||
Priority: 128
|
||||
DopplerLevel: 1
|
||||
MinDistance: 1
|
||||
MaxDistance: 500
|
||||
Pan2D: 0
|
||||
rolloffMode: 0
|
||||
BypassEffects: 0
|
||||
BypassListenerEffects: 0
|
||||
BypassReverbZones: 0
|
||||
rolloffCustomCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
- serializedVersion: 3
|
||||
time: 1
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
panLevelCustomCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
spreadCustomCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
reverbZoneMixCustomCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
--- !u!82 &566179490935405760
|
||||
AudioSource:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 566179490935405789}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 4
|
||||
OutputAudioMixerGroup: {fileID: 0}
|
||||
m_audioClip: {fileID: 8300000, guid: 4aa5e83ae912c46409c45fc3f4f5cfe4, type: 3}
|
||||
m_PlayOnAwake: 0
|
||||
m_Volume: 1
|
||||
m_Pitch: 1
|
||||
Loop: 0
|
||||
Mute: 0
|
||||
Spatialize: 0
|
||||
SpatializePostEffects: 0
|
||||
Priority: 128
|
||||
DopplerLevel: 1
|
||||
MinDistance: 1
|
||||
MaxDistance: 500
|
||||
Pan2D: 0
|
||||
rolloffMode: 0
|
||||
BypassEffects: 0
|
||||
BypassListenerEffects: 0
|
||||
BypassReverbZones: 0
|
||||
rolloffCustomCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
- serializedVersion: 3
|
||||
time: 1
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
panLevelCustomCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
spreadCustomCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
reverbZoneMixCustomCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7993ae71b53b408449cea86d791c878e
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,82 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &1052180204205180280
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 566179490935405789, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_Name
|
||||
value: HoverStateVisuals_NoPulse
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405791, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_AudioClick
|
||||
value:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405791, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_PlayMaterialActivateAnim
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_RootOrder
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents:
|
||||
- {fileID: 566179490935405760, guid: 7993ae71b53b408449cea86d791c878e, type: 3}
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 7993ae71b53b408449cea86d791c878e, type: 3}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c102231f74abcce4382946b5716f88a0
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,107 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &2715104923692232958
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 566179490935405789, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_Name
|
||||
value: HoverStateVisuals_OnlyHover
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405791, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_AudioClick
|
||||
value:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405791, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_SelectionColor.b
|
||||
value: 0.9019608
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405791, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_SelectionColor.g
|
||||
value: 0.69803923
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405791, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_SelectionColor.r
|
||||
value: 0.2509804
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405791, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_HighlightOnSelect
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405791, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_HighlightOnActivate
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405791, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_PlayMaterialActivateAnim
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_RootOrder
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 566179490935405797, guid: 7993ae71b53b408449cea86d791c878e,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents:
|
||||
- {fileID: 566179490935405760, guid: 7993ae71b53b408449cea86d791c878e, type: 3}
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 7993ae71b53b408449cea86d791c878e, type: 3}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82bfca775e5a52f4caa5cdb4a40e48e7
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/XRI_Examples/HoverHighlight/Scripts.meta
Normal file
8
Assets/XRI_Examples/HoverHighlight/Scripts.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f34cd2848ae5904f8c79ec7c2b090f4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,312 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace UnityEngine.XR.Content.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// The HighlightController manages scripts that highlight objects in some way - those that inherit from IMaterialHighlight
|
||||
/// It is in charge of locating all applicable renderers, and swapping/doing additional drawing passes as needed to represent the highlights
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class HighlightController
|
||||
{
|
||||
// Local method use only -- created here to reduce garbage collection. Collections must be cleared before use
|
||||
static readonly List<Renderer> k_RendererComponents = new List<Renderer>();
|
||||
|
||||
/// <summary>
|
||||
/// Holds additional data for renderers that need additional drawing passes
|
||||
/// This is specically MeshRenderers with more than one submesh - we can't just extend the material array
|
||||
/// to get additional drawing passes, so we use this data to draw them manually.
|
||||
/// </summary>
|
||||
class CustomHighlightLayer
|
||||
{
|
||||
internal Material[] m_HighlightMaterials;
|
||||
internal Mesh m_SharedMesh;
|
||||
internal Transform m_Transform;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Used to set the mode of capturing renderers on an object or to use only manually set renderers.")]
|
||||
RendererCaptureDepth m_RendererCaptureDepth = RendererCaptureDepth.AllChildRenderers;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Manually set renderers to be affected by the highlight")]
|
||||
protected Renderer[] m_ManuallySetRenderers = new Renderer[0];
|
||||
|
||||
// Cached data about any renderers that will be highlighted, and materials that are swapped in and out
|
||||
int m_MaterialAdditions = 0;
|
||||
|
||||
List<IMaterialHighlight> m_CacheUsers = new List<IMaterialHighlight>();
|
||||
HashSet<Renderer> m_Renderers = new HashSet<Renderer>();
|
||||
Dictionary<int, Material[]> m_OriginalMaterials = new Dictionary<int, Material[]>();
|
||||
Dictionary<int, Material[]> m_HighlightMaterials = new Dictionary<int, Material[]>();
|
||||
Dictionary<int, CustomHighlightLayer> m_CustomLayerMaterials = new Dictionary<int, CustomHighlightLayer>();
|
||||
|
||||
bool m_DelayedUnhighlight = false;
|
||||
bool m_Highlighting = false;
|
||||
float m_UnhighlightTimer = 0.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The transform that will be highlighted - it is searched for any child renderers
|
||||
/// </summary>
|
||||
public Transform rendererSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Registers a highlight script - this will provide materials to replace or layer when highlighting an object
|
||||
/// </summary>
|
||||
/// <param name="cacheUser">The highlight script to apply to the cached child renderers</param>
|
||||
public void RegisterCacheUser(IMaterialHighlight cacheUser)
|
||||
{
|
||||
if (cacheUser.highlightMode == MaterialHighlightMode.Layer)
|
||||
m_MaterialAdditions++;
|
||||
|
||||
// Set cache user to know about this
|
||||
m_CacheUsers.Add(cacheUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters a highlight script so that it will no longer influence the cached renderers
|
||||
/// </summary>
|
||||
/// <param name="cacheUser">The highlight script to remove from influencing renderers</param>
|
||||
public void UnregisterCacheUser(IMaterialHighlight cacheUser)
|
||||
{
|
||||
if (cacheUser.highlightMode == MaterialHighlightMode.Layer)
|
||||
m_MaterialAdditions--;
|
||||
|
||||
m_CacheUsers.Remove(cacheUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that all renderers, materials, and highlight scripts have their materials ready
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
if (rendererSource == null)
|
||||
{
|
||||
Debug.LogError("Trying to use a Highlight Controller before setting the root gameobject!");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var cacheUser in m_CacheUsers)
|
||||
{
|
||||
cacheUser.Initialize();
|
||||
}
|
||||
|
||||
// Cache the renderers
|
||||
UpdateRendererCache();
|
||||
|
||||
// Generate the original material list and implement the materials from the included highlights
|
||||
UpdateMaterialCache();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that any materials or other objects allocated by highlight scripts can be cleaned up
|
||||
/// </summary>
|
||||
public void Deinitialize()
|
||||
{
|
||||
foreach (var cacheUser in m_CacheUsers)
|
||||
{
|
||||
if (cacheUser != null)
|
||||
cacheUser.Deinitialize();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles fading out materials when highlights are disabled and also manually drawing layered highlights as needed
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
if (m_DelayedUnhighlight)
|
||||
{
|
||||
m_UnhighlightTimer -= Time.deltaTime;
|
||||
if (m_UnhighlightTimer <= 0.0f)
|
||||
{
|
||||
m_DelayedUnhighlight = false;
|
||||
m_Highlighting = false;
|
||||
UpdateMaterialCache();
|
||||
foreach (var renderer in m_Renderers)
|
||||
{
|
||||
var rendererID = renderer.GetInstanceID();
|
||||
renderer.materials = m_OriginalMaterials[rendererID];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_Highlighting && m_CustomLayerMaterials.Count > 0)
|
||||
{
|
||||
foreach (var customLayer in m_CustomLayerMaterials.Values)
|
||||
{
|
||||
for (var matIndex = 0; matIndex < customLayer.m_HighlightMaterials.Length; ++matIndex)
|
||||
{
|
||||
for (var submeshIndex = 0; submeshIndex < customLayer.m_SharedMesh.subMeshCount; ++submeshIndex)
|
||||
{
|
||||
Graphics.DrawMesh(
|
||||
customLayer.m_SharedMesh,
|
||||
customLayer.m_Transform.localToWorldMatrix,
|
||||
customLayer.m_HighlightMaterials[matIndex],
|
||||
customLayer.m_Transform.gameObject.layer,
|
||||
null,
|
||||
submeshIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies highlight materials to all the targeted renderers
|
||||
/// </summary>
|
||||
public void Highlight()
|
||||
{
|
||||
m_DelayedUnhighlight = false;
|
||||
m_Highlighting = true;
|
||||
UpdateMaterialCache();
|
||||
foreach (var renderer in m_Renderers)
|
||||
{
|
||||
var rendererID = renderer.GetInstanceID();
|
||||
renderer.materials = m_HighlightMaterials[rendererID];
|
||||
}
|
||||
foreach (var cacheUser in m_CacheUsers)
|
||||
{
|
||||
if (cacheUser != null)
|
||||
cacheUser.OnHighlight();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores the original materials to all the targeted renderers
|
||||
/// </summary>
|
||||
/// <param name="force">If true, the original materials are restored instantly. Otherwise, a fade can occur.</param>
|
||||
public void Unhighlight(bool force = false)
|
||||
{
|
||||
UpdateMaterialCache();
|
||||
|
||||
var maxDelay = 0.0f;
|
||||
foreach (var cacheUser in m_CacheUsers)
|
||||
{
|
||||
if (cacheUser != null)
|
||||
maxDelay = Mathf.Max(cacheUser.OnUnhighlight());
|
||||
}
|
||||
|
||||
if (maxDelay <= 0.0f)
|
||||
{
|
||||
foreach (var renderer in m_Renderers)
|
||||
{
|
||||
var rendererID = renderer.GetInstanceID();
|
||||
renderer.materials = m_OriginalMaterials[rendererID];
|
||||
}
|
||||
m_Highlighting = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_DelayedUnhighlight = true;
|
||||
m_UnhighlightTimer = maxDelay;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateRendererCache()
|
||||
{
|
||||
m_Renderers.Clear();
|
||||
m_Renderers.UnionWith(m_ManuallySetRenderers.Where(r => r != null));
|
||||
|
||||
switch (m_RendererCaptureDepth)
|
||||
{
|
||||
case RendererCaptureDepth.AllChildRenderers:
|
||||
rendererSource.GetComponentsInChildren(true, k_RendererComponents);
|
||||
|
||||
foreach (var renderer in k_RendererComponents)
|
||||
{
|
||||
var textMesh = renderer.GetComponent<TextMesh>();
|
||||
var meshFilter = renderer.GetComponent<MeshFilter>();
|
||||
|
||||
if (textMesh == null)
|
||||
m_Renderers.Add(renderer);
|
||||
|
||||
if (meshFilter != null && meshFilter.mesh.subMeshCount > 1)
|
||||
m_CustomLayerMaterials.Add(renderer.GetInstanceID(), new CustomHighlightLayer { m_SharedMesh = meshFilter.sharedMesh, m_Transform = renderer.transform });
|
||||
}
|
||||
k_RendererComponents.Clear();
|
||||
|
||||
break;
|
||||
case RendererCaptureDepth.CurrentRenderer:
|
||||
rendererSource.GetComponents(k_RendererComponents);
|
||||
|
||||
foreach (var renderer in k_RendererComponents)
|
||||
{
|
||||
var textMesh = renderer.GetComponent<TextMesh>();
|
||||
var meshFilter = renderer.GetComponent<MeshFilter>();
|
||||
|
||||
if (textMesh == null)
|
||||
m_Renderers.Add(renderer);
|
||||
|
||||
if (meshFilter != null && meshFilter.mesh.subMeshCount > 1)
|
||||
m_CustomLayerMaterials.Add(renderer.GetInstanceID(), new CustomHighlightLayer { m_SharedMesh = meshFilter.sharedMesh, m_Transform = renderer.transform });
|
||||
}
|
||||
k_RendererComponents.Clear();
|
||||
break;
|
||||
case RendererCaptureDepth.ManualOnly:
|
||||
break;
|
||||
default:
|
||||
Debug.LogError($"{rendererSource.name} highlight has an invalid renderer capture mode {m_RendererCaptureDepth}.", rendererSource);
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_Renderers.Count == 0)
|
||||
Debug.LogWarning($"{rendererSource.name} highlight has no renderers set.", rendererSource);
|
||||
}
|
||||
|
||||
void UpdateMaterialCache()
|
||||
{
|
||||
foreach (var renderer in m_Renderers)
|
||||
{
|
||||
var rendererID = renderer.GetInstanceID();
|
||||
if (m_OriginalMaterials.ContainsKey(rendererID))
|
||||
continue;
|
||||
|
||||
var sharedMaterials = renderer.sharedMaterials;
|
||||
var sharedLength = sharedMaterials.Length;
|
||||
m_OriginalMaterials[rendererID] = sharedMaterials;
|
||||
|
||||
CustomHighlightLayer highlightLayer = null;
|
||||
Material[] highlightMaterials;
|
||||
Material[] layerMaterials;
|
||||
var addOffset = sharedLength;
|
||||
|
||||
if (m_CustomLayerMaterials.TryGetValue(rendererID, out highlightLayer))
|
||||
{
|
||||
highlightMaterials = new Material[sharedLength];
|
||||
highlightLayer.m_HighlightMaterials = new Material[m_MaterialAdditions];
|
||||
layerMaterials = highlightLayer.m_HighlightMaterials;
|
||||
addOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
highlightMaterials = new Material[sharedLength + m_MaterialAdditions];
|
||||
layerMaterials = highlightMaterials;
|
||||
}
|
||||
|
||||
for (var matIndex = 0; matIndex < sharedLength; matIndex++)
|
||||
{
|
||||
highlightMaterials[matIndex] = sharedMaterials[matIndex];
|
||||
}
|
||||
|
||||
for (var i = 0; i < m_CacheUsers.Count; i++)
|
||||
{
|
||||
var cacheUser = m_CacheUsers[i];
|
||||
if (cacheUser.highlightMode == MaterialHighlightMode.Replace)
|
||||
{
|
||||
for (var matIndex = 0; matIndex < sharedLength; matIndex++)
|
||||
{
|
||||
highlightMaterials[matIndex] = cacheUser.highlightMaterial;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
layerMaterials[addOffset] = cacheUser.highlightMaterial;
|
||||
addOffset++;
|
||||
}
|
||||
}
|
||||
m_HighlightMaterials[rendererID] = highlightMaterials;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c01ba99b66d7e74f8c5cbc4aaf7b411
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
namespace UnityEngine.XR.Content.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies how a material is applied to renderer for highlighting
|
||||
/// </summary>
|
||||
public enum MaterialHighlightMode
|
||||
{
|
||||
/// <summary>Adds a new material to the renderers materials array</summary>
|
||||
Layer,
|
||||
/// <summary>Replace the renderers materials with materials</summary>
|
||||
Replace,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identifies a script as one that can apply a highlight to renderers
|
||||
/// </summary>
|
||||
public interface IMaterialHighlight
|
||||
{
|
||||
/// <summary>
|
||||
/// How a new material will be applied to the renderer's material array.
|
||||
/// </summary>
|
||||
MaterialHighlightMode highlightMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Material to use for highlighting
|
||||
/// </summary>
|
||||
Material highlightMaterial { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Used to set up any initial values or materials
|
||||
/// </summary>
|
||||
void Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Used to remove any persistent objects
|
||||
/// </summary>
|
||||
void Deinitialize();
|
||||
|
||||
/// <summary>
|
||||
/// Raised when a highlight operations has completed
|
||||
/// </summary>
|
||||
void OnHighlight();
|
||||
|
||||
/// <summary>
|
||||
/// Raised when a un-highlight operations has completed
|
||||
/// </summary>
|
||||
/// <returns>A requested delay to transition out the highlight</returns>
|
||||
float OnUnhighlight();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e7a7016d637b614986ed6dc8b30674e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,362 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace UnityEngine.XR.Content.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// All-in-one controller for animated object highlights in different states - hovered, selected, and activated
|
||||
/// </summary>
|
||||
public class InteractableVisualsController : MonoBehaviour
|
||||
{
|
||||
const float k_ShineTime = 0.2f;
|
||||
|
||||
enum PriorityHighlightingState
|
||||
{
|
||||
Unknown,
|
||||
Highlighted,
|
||||
Unhighlighted,
|
||||
}
|
||||
|
||||
static List<IXRTargetPriorityInteractor> s_InteractorList = new List<IXRTargetPriorityInteractor>();
|
||||
|
||||
#pragma warning disable 649
|
||||
[Header("Audio")]
|
||||
[SerializeField]
|
||||
[Tooltip("The hover audio source.")]
|
||||
AudioSource m_AudioHover;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The click audio source.")]
|
||||
AudioSource m_AudioClick;
|
||||
|
||||
[Header("Visual")]
|
||||
[SerializeField]
|
||||
[Tooltip("Material capture settings.")]
|
||||
HighlightController m_HighlightController = new HighlightController();
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The outline highlight for selection.")]
|
||||
OutlineHighlight m_OutlineHighlight;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The material highlight for hover.")]
|
||||
MaterialHighlight m_MaterialHighlight;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The outline hover color.")]
|
||||
Color m_HoverColor = new Color(0.25f, 0.7f, 0.9f, 1f);
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The outline hover color when the Interactable has the highest priority for selection.")]
|
||||
Color m_HoverPriorityColor = new Color(0.09411765f, 0.4392157f, 0.7137255f, 1f);
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The outline selection color.")]
|
||||
Color m_SelectionColor = new Color(1f, 0.4f, 0f, 1f);
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("To play material activate anim.")]
|
||||
bool m_PlayMaterialActivateAnim;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("To play outline activate anim.")]
|
||||
bool m_PlayOutlineActivateAnim;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("If true, the highlight state will be on during hover.")]
|
||||
bool m_HighlightOnHover = true;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("If true, the highlight state will be on during hover when the Interactable has the highest priority for selection.")]
|
||||
bool m_HighlightOnHoverPriority = true;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("If true, the highlight state will be on during select.")]
|
||||
bool m_HighlightOnSelect = true;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("If true, the highlight state will be on during activate.")]
|
||||
bool m_HighlightOnActivate = true;
|
||||
|
||||
#pragma warning restore 649
|
||||
|
||||
XRBaseInteractable m_Interactable;
|
||||
|
||||
Material m_PulseMaterial;
|
||||
float m_StartingAlpha;
|
||||
float m_StartingWidth;
|
||||
|
||||
int m_SelectedCount;
|
||||
int m_HoveredCount;
|
||||
bool m_Highlighting;
|
||||
PriorityHighlightingState m_PriorityHighlightingState;
|
||||
|
||||
bool m_PlayShine;
|
||||
float m_ShineTimer;
|
||||
|
||||
bool isActivated { get; set; }
|
||||
bool isSelected => m_SelectedCount > 0;
|
||||
bool isHovered => m_HoveredCount > 0;
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="MonoBehaviour"/>.
|
||||
/// </summary>
|
||||
protected void Awake()
|
||||
{
|
||||
// Find the grab interactable
|
||||
m_Interactable = GetComponentInParent<XRBaseInteractable>();
|
||||
|
||||
// Hook up to events
|
||||
if (m_Interactable is IXRHoverInteractable hoverInteractable)
|
||||
{
|
||||
hoverInteractable.hoverEntered.AddListener(OnHoverEntered);
|
||||
hoverInteractable.hoverExited.AddListener(OnHoverExited);
|
||||
}
|
||||
|
||||
if (m_Interactable is IXRSelectInteractable selectInteractable)
|
||||
{
|
||||
selectInteractable.selectEntered.AddListener(OnSelectEntered);
|
||||
selectInteractable.selectExited.AddListener(OnSelectExited);
|
||||
}
|
||||
|
||||
if (m_Interactable is IXRActivateInteractable activateInteractable)
|
||||
{
|
||||
activateInteractable.activated.AddListener(OnActivated);
|
||||
activateInteractable.deactivated.AddListener(OnDeactivated);
|
||||
}
|
||||
|
||||
// Cache materials for highlighting
|
||||
m_HighlightController.rendererSource = m_Interactable.transform;
|
||||
|
||||
// Tell the highlight objects to get renderers starting at the grab interactable down
|
||||
if (m_MaterialHighlight != null)
|
||||
{
|
||||
m_HighlightController.RegisterCacheUser(m_MaterialHighlight);
|
||||
m_PulseMaterial = m_MaterialHighlight.highlightMaterial;
|
||||
|
||||
if (m_PulseMaterial != null)
|
||||
m_StartingAlpha = m_PulseMaterial.GetFloat("_PulseMinAlpha");
|
||||
}
|
||||
if (m_OutlineHighlight != null)
|
||||
m_HighlightController.RegisterCacheUser(m_OutlineHighlight);
|
||||
|
||||
m_HighlightController.Initialize();
|
||||
m_StartingWidth = m_OutlineHighlight.outlineScale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="MonoBehaviour"/>.
|
||||
/// </summary>
|
||||
protected void Update()
|
||||
{
|
||||
UpdatePriorityHighlightingState();
|
||||
m_HighlightController.Update();
|
||||
if (m_MaterialHighlight != null)
|
||||
{
|
||||
// Do timer count up/count down
|
||||
if (m_PlayShine)
|
||||
{
|
||||
m_ShineTimer += Time.deltaTime;
|
||||
|
||||
var shinePercent = Mathf.Clamp01(m_ShineTimer / k_ShineTime);
|
||||
var shineValue = Mathf.PingPong(shinePercent, 0.5f) * 2.0f;
|
||||
|
||||
m_PulseMaterial.SetFloat("_PulseMinAlpha", Mathf.Lerp(m_StartingAlpha, 1f, shineValue));
|
||||
|
||||
if (shinePercent >= 1.0f)
|
||||
{
|
||||
m_PlayShine = false;
|
||||
m_ShineTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateHighlightState()
|
||||
{
|
||||
var shouldHighlight = false;
|
||||
|
||||
if (isActivated)
|
||||
shouldHighlight = m_HighlightOnActivate;
|
||||
else
|
||||
{
|
||||
if (isSelected)
|
||||
shouldHighlight = m_HighlightOnSelect;
|
||||
else if (isHovered)
|
||||
shouldHighlight = m_HighlightOnHover || (m_HighlightOnHoverPriority && m_PriorityHighlightingState == PriorityHighlightingState.Highlighted);
|
||||
}
|
||||
|
||||
if (shouldHighlight == m_Highlighting)
|
||||
return;
|
||||
|
||||
m_Highlighting = shouldHighlight;
|
||||
|
||||
if (m_Highlighting)
|
||||
m_HighlightController.Highlight();
|
||||
else
|
||||
m_HighlightController.Unhighlight();
|
||||
}
|
||||
|
||||
void OnHoverEntered(HoverEnterEventArgs args)
|
||||
{
|
||||
if (args.interactorObject is XRSocketInteractor)
|
||||
return;
|
||||
|
||||
m_HoveredCount++;
|
||||
|
||||
if (isSelected)
|
||||
return;
|
||||
|
||||
if (m_AudioHover != null)
|
||||
m_AudioHover.Play();
|
||||
|
||||
if (m_MaterialHighlight != null)
|
||||
m_PulseMaterial.color = m_HoverColor;
|
||||
|
||||
if (m_OutlineHighlight != null)
|
||||
m_OutlineHighlight.outlineColor = m_HoverColor;
|
||||
|
||||
m_PriorityHighlightingState = PriorityHighlightingState.Unknown;
|
||||
UpdateHighlightState();
|
||||
}
|
||||
|
||||
void OnHoverExited(HoverExitEventArgs args)
|
||||
{
|
||||
if (args.interactorObject is XRSocketInteractor)
|
||||
return;
|
||||
|
||||
m_HoveredCount--;
|
||||
m_PriorityHighlightingState = PriorityHighlightingState.Unknown;
|
||||
UpdateHighlightState();
|
||||
}
|
||||
|
||||
bool HasValidInteractor(List<IXRTargetPriorityInteractor> interactors)
|
||||
{
|
||||
foreach (var interactor in interactors)
|
||||
{
|
||||
if (!(interactor is XRSocketInteractor))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void UpdatePriorityHighlightingState()
|
||||
{
|
||||
if (!m_HighlightOnHoverPriority || !isHovered || isSelected)
|
||||
return;
|
||||
|
||||
var manager = m_Interactable.interactionManager;
|
||||
if (manager == null)
|
||||
return;
|
||||
|
||||
var highestPriorityForSelection = manager.IsHighestPriorityTarget(m_Interactable, s_InteractorList);
|
||||
if (!HasValidInteractor(s_InteractorList))
|
||||
return;
|
||||
|
||||
if (highestPriorityForSelection && m_PriorityHighlightingState != PriorityHighlightingState.Highlighted)
|
||||
{
|
||||
m_PriorityHighlightingState = PriorityHighlightingState.Highlighted;
|
||||
|
||||
if (m_PulseMaterial != null)
|
||||
m_PulseMaterial.color = m_HoverPriorityColor;
|
||||
|
||||
if (m_OutlineHighlight != null)
|
||||
m_OutlineHighlight.outlineColor = m_HoverPriorityColor;
|
||||
|
||||
UpdateHighlightState();
|
||||
}
|
||||
|
||||
if (!highestPriorityForSelection && m_PriorityHighlightingState != PriorityHighlightingState.Unhighlighted)
|
||||
{
|
||||
m_PriorityHighlightingState = PriorityHighlightingState.Unhighlighted;
|
||||
|
||||
if (m_PulseMaterial != null)
|
||||
m_PulseMaterial.color = m_HoverColor;
|
||||
|
||||
if (m_OutlineHighlight != null)
|
||||
m_OutlineHighlight.outlineColor = m_HoverColor;
|
||||
|
||||
UpdateHighlightState();
|
||||
}
|
||||
}
|
||||
|
||||
void OnSelectEntered(SelectEnterEventArgs args)
|
||||
{
|
||||
if (args.interactorObject is XRSocketInteractor)
|
||||
return;
|
||||
|
||||
if (m_AudioClick != null)
|
||||
m_AudioClick.Play();
|
||||
|
||||
if (m_OutlineHighlight != null)
|
||||
{
|
||||
m_OutlineHighlight.outlineColor = m_SelectionColor;
|
||||
m_OutlineHighlight.PlayPulseAnimation();
|
||||
}
|
||||
|
||||
if (m_MaterialHighlight != null)
|
||||
m_PulseMaterial.color = m_SelectionColor;
|
||||
|
||||
m_SelectedCount++;
|
||||
UpdateHighlightState();
|
||||
}
|
||||
|
||||
void OnSelectExited(SelectExitEventArgs args)
|
||||
{
|
||||
if (args.interactorObject is XRSocketInteractor)
|
||||
return;
|
||||
|
||||
if (m_OutlineHighlight != null)
|
||||
m_OutlineHighlight.outlineColor = m_HoverColor;
|
||||
if (m_MaterialHighlight != null)
|
||||
m_PulseMaterial.color = m_HoverColor;
|
||||
|
||||
m_OutlineHighlight.PlayPulseAnimation();
|
||||
|
||||
// In case the Interactable is dropped while activated.
|
||||
isActivated = false;
|
||||
m_SelectedCount--;
|
||||
m_PriorityHighlightingState = PriorityHighlightingState.Unknown;
|
||||
UpdateHighlightState();
|
||||
}
|
||||
|
||||
void OnActivated(ActivateEventArgs args)
|
||||
{
|
||||
if (args.interactorObject is XRSocketInteractor)
|
||||
return;
|
||||
|
||||
if (m_OutlineHighlight != null)
|
||||
{
|
||||
if (m_PlayMaterialActivateAnim)
|
||||
m_PlayShine = true;
|
||||
|
||||
if (m_PlayOutlineActivateAnim)
|
||||
{
|
||||
m_OutlineHighlight.outlineScale = 1f;
|
||||
m_OutlineHighlight.PlayPulseAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
isActivated = true;
|
||||
UpdateHighlightState();
|
||||
}
|
||||
|
||||
void OnDeactivated(DeactivateEventArgs args)
|
||||
{
|
||||
if (args.interactorObject is XRSocketInteractor)
|
||||
return;
|
||||
|
||||
if (m_OutlineHighlight != null)
|
||||
{
|
||||
if (m_PlayOutlineActivateAnim)
|
||||
{
|
||||
m_OutlineHighlight.outlineScale = m_StartingWidth;
|
||||
m_OutlineHighlight.PlayPulseAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
isActivated = false;
|
||||
UpdateHighlightState();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc812c2b9f69cb94ea80d24d6b974fcc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,75 @@
|
||||
namespace UnityEngine.XR.Content.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to change the materials array of an object when highlighted. Can either add the highlight material to the
|
||||
/// renderers materials array or replace the renderers materials with the highlight material.
|
||||
/// </summary>
|
||||
public class MaterialHighlight : MonoBehaviour, IMaterialHighlight
|
||||
{
|
||||
[SerializeField]
|
||||
[Tooltip("How the highlight material will be applied to the renderer's material array.")]
|
||||
MaterialHighlightMode m_HighlightMode = MaterialHighlightMode.Replace;
|
||||
|
||||
[SerializeField, Tooltip("Material to use for highlighting. The assigned material will be instantiated and used for highlighting.")]
|
||||
Material m_HighlightMaterial;
|
||||
|
||||
Material m_InstanceHighlightMaterial;
|
||||
|
||||
/// <summary>
|
||||
/// How the highlight material will be applied to the renderer's material array.
|
||||
/// </summary>
|
||||
public MaterialHighlightMode highlightMode
|
||||
{
|
||||
get => m_HighlightMode;
|
||||
set => m_HighlightMode = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Material to use for highlighting. The assigned material will be instantiated and used for highlighting.
|
||||
/// </summary>
|
||||
public Material highlightMaterial
|
||||
{
|
||||
get => m_HighlightMaterial;
|
||||
set => m_HighlightMaterial = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="MonoBehaviour"/>.
|
||||
/// </summary>
|
||||
protected void Awake()
|
||||
{
|
||||
if (m_HighlightMaterial == null)
|
||||
return;
|
||||
|
||||
m_InstanceHighlightMaterial = Instantiate(m_HighlightMaterial);
|
||||
m_HighlightMaterial = m_InstanceHighlightMaterial;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="MonoBehaviour"/>.
|
||||
/// </summary>
|
||||
protected void OnDestroy()
|
||||
{
|
||||
if (m_InstanceHighlightMaterial != null)
|
||||
Destroy(m_InstanceHighlightMaterial);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
void IMaterialHighlight.Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
void IMaterialHighlight.Deinitialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
void IMaterialHighlight.OnHighlight()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
float IMaterialHighlight.OnUnhighlight() => 0f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ecee6e1c65d5fa4a8f931a3f7e79229
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
323
Assets/XRI_Examples/HoverHighlight/Scripts/OutlineHighlight.cs
Normal file
323
Assets/XRI_Examples/HoverHighlight/Scripts/OutlineHighlight.cs
Normal file
@@ -0,0 +1,323 @@
|
||||
namespace UnityEngine.XR.Content.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Draws an outline on an object when highlighting. Can either transition the color and or size of the out line
|
||||
/// as selected or be instant on.
|
||||
/// </summary>
|
||||
public class OutlineHighlight : MonoBehaviour, IMaterialHighlight
|
||||
{
|
||||
enum OutlineSource
|
||||
{
|
||||
Shader = 0,
|
||||
Material
|
||||
}
|
||||
|
||||
const float k_OutlineWidth = 0.005f;
|
||||
const string k_ShaderColorParameter = "_Color";
|
||||
const string k_ShaderWidthParameter = "g_flOutlineWidth";
|
||||
static readonly int k_GFlOutlineWidth = Shader.PropertyToID(k_ShaderWidthParameter);
|
||||
static readonly int k_Color = Shader.PropertyToID(k_ShaderColorParameter);
|
||||
|
||||
#pragma warning disable 649
|
||||
[SerializeField]
|
||||
[Tooltip("How the highlight material will be applied to the renderer's material array.")]
|
||||
MaterialHighlightMode m_HighlightMode = MaterialHighlightMode.Replace;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Selects source for the highlight material. Either using a shader or material.")]
|
||||
OutlineSource m_OutlineSource = OutlineSource.Shader;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Outline highlight shader to use for highlight material.")]
|
||||
Shader m_Shader;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Material used for drawing the outline highlight.")]
|
||||
Material m_HighlightMaterial;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Transition outline width over time")]
|
||||
bool m_TransitionWidth;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The outline width used if no transition or the end value for transition width of outline")]
|
||||
[Range(0f, 1f)]
|
||||
float m_OutlineScale = 1f;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Starting value for transition width of outline")]
|
||||
[Range(0f, 1f)]
|
||||
float m_StartingOutlineScale;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Transition outline color over time")]
|
||||
bool m_TransitionColor;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The outline color used if no transition or the end value for transition color of outline")]
|
||||
Color m_OutlineColor = new Color(0.3f, 0.6f, 1f, 1f);
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Starting value for transition color of outline")]
|
||||
Color m_StartingOutlineColor = Color.black;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Time it takes to transition from start to end on highlight")]
|
||||
float m_TransitionDuration = 0.3f;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Use material values for starting color and width")]
|
||||
bool m_StartWithMaterialValues;
|
||||
#pragma warning restore 649
|
||||
|
||||
Material m_InstanceOutlineMaterial;
|
||||
|
||||
bool m_Animating = false;
|
||||
bool m_AnimatingIn = false;
|
||||
float m_TransitionTimer = 0.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Time it takes to transition from start to end on highlight
|
||||
/// </summary>
|
||||
public float transitionDuration
|
||||
{
|
||||
get => m_TransitionDuration;
|
||||
set => m_TransitionDuration = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transition outline width over time
|
||||
/// </summary>
|
||||
public bool transitionWidth
|
||||
{
|
||||
get => m_TransitionWidth;
|
||||
set => m_TransitionWidth = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transition outline color over time
|
||||
/// </summary>
|
||||
public bool transitionColor
|
||||
{
|
||||
get => m_TransitionColor;
|
||||
set => m_TransitionColor = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The outline color used if no transition or the end value for transition color of outline
|
||||
/// </summary>
|
||||
public Color outlineColor
|
||||
{
|
||||
get => m_OutlineColor;
|
||||
set => m_OutlineColor = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starting value for transition color of outline
|
||||
/// </summary>
|
||||
public Color startingOutlineColor
|
||||
{
|
||||
get => m_StartingOutlineColor;
|
||||
set => m_StartingOutlineColor = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The outline width used if no transition or the end value for transition width of outline
|
||||
/// </summary>
|
||||
public float outlineScale
|
||||
{
|
||||
get => m_OutlineScale;
|
||||
set => m_OutlineScale = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starting value for transition width of outline
|
||||
/// </summary>
|
||||
public float startingOutlineScale
|
||||
{
|
||||
get => m_StartingOutlineScale;
|
||||
set => m_StartingOutlineScale = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A 0-1 relative outline scale that takes into account the ideal base outline width,
|
||||
/// multiplied by the user specified value. This allows for more intuitive adjustment of the value.
|
||||
/// This is the value used if there is no transition otherwise this is the end value of a transition.
|
||||
/// </summary>
|
||||
float relativeOutlineScale => outlineScale * k_OutlineWidth;
|
||||
|
||||
/// <summary>
|
||||
/// A 0-1 relative outline scale that takes into account the ideal base outline width,
|
||||
/// multiplied by the user specified value. This allows for more intuitive adjustment of the value.
|
||||
/// This is the start value of a transition otherwise this value is not used.
|
||||
/// </summary>
|
||||
float startingRelativeOutlineScale => startingOutlineScale * k_OutlineWidth;
|
||||
|
||||
/// <summary>
|
||||
/// How the highlight material will be applied to the renderer's material array.
|
||||
/// </summary>
|
||||
public MaterialHighlightMode highlightMode
|
||||
{
|
||||
get => m_HighlightMode;
|
||||
set => m_HighlightMode = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Material to use for highlighting
|
||||
/// </summary>
|
||||
public Material highlightMaterial => m_InstanceOutlineMaterial;
|
||||
|
||||
void IMaterialHighlight.Initialize()
|
||||
{
|
||||
InstantiateHighlightMaterial();
|
||||
|
||||
if (m_StartWithMaterialValues)
|
||||
{
|
||||
startingOutlineScale = m_HighlightMaterial.GetFloat(k_GFlOutlineWidth) / k_OutlineWidth;
|
||||
startingOutlineColor = m_HighlightMaterial.GetColor(k_Color);
|
||||
}
|
||||
}
|
||||
|
||||
void IMaterialHighlight.Deinitialize()
|
||||
{
|
||||
if (m_InstanceOutlineMaterial)
|
||||
{
|
||||
Destroy(m_InstanceOutlineMaterial);
|
||||
m_InstanceOutlineMaterial = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnDestroy()
|
||||
{
|
||||
((IMaterialHighlight)(this)).Deinitialize();
|
||||
}
|
||||
|
||||
protected void Update()
|
||||
{
|
||||
if (m_Animating)
|
||||
{
|
||||
m_TransitionTimer += Time.unscaledDeltaTime;
|
||||
|
||||
var transitionPercent = Mathf.Clamp01(m_TransitionTimer / m_TransitionDuration);
|
||||
var alpha = m_AnimatingIn ? transitionPercent : (1.0f - transitionPercent);
|
||||
|
||||
if (m_TransitionWidth)
|
||||
{
|
||||
var size = Mathf.Lerp(startingRelativeOutlineScale, relativeOutlineScale, alpha);
|
||||
m_InstanceOutlineMaterial.SetFloat(k_GFlOutlineWidth, size);
|
||||
}
|
||||
|
||||
if (m_TransitionColor)
|
||||
{
|
||||
var color = Color.Lerp(startingOutlineColor, outlineColor, alpha);
|
||||
m_InstanceOutlineMaterial.SetColor(k_Color, color);
|
||||
}
|
||||
|
||||
if (transitionPercent >= 1.0f)
|
||||
{
|
||||
m_TransitionTimer = 0.0f;
|
||||
m_Animating = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IMaterialHighlight.OnHighlight()
|
||||
{
|
||||
if (m_InstanceOutlineMaterial == null)
|
||||
return;
|
||||
|
||||
PlayPulseAnimation();
|
||||
}
|
||||
|
||||
float IMaterialHighlight.OnUnhighlight()
|
||||
{
|
||||
if (m_InstanceOutlineMaterial == null)
|
||||
return 0.0f;
|
||||
|
||||
PlayPulseAnimation(false);
|
||||
|
||||
if (!m_TransitionWidth && !m_TransitionColor || Mathf.Approximately(m_TransitionDuration, 0f))
|
||||
return 0.0f;
|
||||
else
|
||||
return m_TransitionDuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pulses the highlight - even if it is already active
|
||||
/// </summary>
|
||||
/// <param name="pulseUp">Whether the highlight is fading in or out</param>
|
||||
public void PlayPulseAnimation(bool pulseUp = true)
|
||||
{
|
||||
if (!m_TransitionWidth && !m_TransitionColor || Mathf.Approximately(m_TransitionDuration, 0f))
|
||||
{
|
||||
m_InstanceOutlineMaterial.SetFloat(k_GFlOutlineWidth, relativeOutlineScale);
|
||||
m_InstanceOutlineMaterial.SetColor(k_Color, m_OutlineColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the same animation is already occurring, we just let it play. If it is playing backwards, we seamlessly transition
|
||||
if (m_Animating)
|
||||
{
|
||||
if (m_AnimatingIn != pulseUp)
|
||||
{
|
||||
m_TransitionTimer = 1.0f - m_TransitionTimer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Animating = true;
|
||||
m_AnimatingIn = pulseUp;
|
||||
m_TransitionTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InstantiateHighlightMaterial()
|
||||
{
|
||||
if (m_Shader == null && m_HighlightMaterial == null)
|
||||
{
|
||||
Debug.LogError($"{gameObject.name} has no highlight material or shader set!", this);
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const string outlineMaterialName = "Outline Material Instance";
|
||||
|
||||
switch (m_OutlineSource)
|
||||
{
|
||||
case OutlineSource.Material:
|
||||
if (m_HighlightMaterial == null)
|
||||
{
|
||||
Debug.LogError($"{gameObject.name} Outline highlight has no material assigned. Please assign outline material.", this);
|
||||
enabled = false;
|
||||
break;
|
||||
}
|
||||
|
||||
m_InstanceOutlineMaterial = new Material(m_HighlightMaterial) { name = outlineMaterialName };
|
||||
break;
|
||||
case OutlineSource.Shader:
|
||||
if (m_Shader == null)
|
||||
{
|
||||
Debug.LogError($"{gameObject.name} Outline highlight has no shader assigned. Please assign outline shader. ", this);
|
||||
enabled = false;
|
||||
break;
|
||||
}
|
||||
|
||||
m_InstanceOutlineMaterial = new Material(m_Shader) { name = outlineMaterialName };
|
||||
break;
|
||||
default:
|
||||
Debug.LogError($"{gameObject.name} Outline highlight has an invalid highlight mode {m_OutlineSource}.", this);
|
||||
enabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnValidate()
|
||||
{
|
||||
if (m_TransitionDuration < 0f)
|
||||
{
|
||||
m_TransitionDuration = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bad813e71e6dea43a3833ba919c1e1b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace UnityEngine.XR.Content.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies how a transform's hierarchy is traversed to locate renderers to highlight
|
||||
/// </summary>
|
||||
public enum RendererCaptureDepth
|
||||
{
|
||||
/// <summary>Get all active renders on an object, its children and manually set renderers.</summary>
|
||||
AllChildRenderers,
|
||||
/// <summary>Get all active renders on an object and manually set renderers. Ignores children.</summary>
|
||||
CurrentRenderer,
|
||||
/// <summary>Only uses manually set renderers.</summary>
|
||||
ManualOnly,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4708094eb64748441bcec602ef27eaa1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/XRI_Examples/HoverHighlight/Shaders.meta
Normal file
8
Assets/XRI_Examples/HoverHighlight/Shaders.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 034a059f7548bea43bcfde1917c917d9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
149
Assets/XRI_Examples/HoverHighlight/Shaders/Silhouette.cginc
Normal file
149
Assets/XRI_Examples/HoverHighlight/Shaders/Silhouette.cginc
Normal file
@@ -0,0 +1,149 @@
|
||||
#pragma target 5.0
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
float4 _Color;
|
||||
float g_flOutlineWidth;
|
||||
float g_flCornerAdjust;
|
||||
|
||||
float4x4 _InverseRotation;
|
||||
float4 _GlobalClipCenter;
|
||||
float4 _GlobalClipExtents;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
struct VS_INPUT
|
||||
{
|
||||
float4 vPositionOs : POSITION;
|
||||
float3 vNormalOs : NORMAL;
|
||||
};
|
||||
|
||||
struct PS_INPUT
|
||||
{
|
||||
float4 vPositionOs : TEXCOORD0;
|
||||
float3 vNormalOs : TEXCOORD1;
|
||||
float3 clipPos : TEXCOORD2;
|
||||
float4 vPositionPs : SV_POSITION;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
PS_INPUT MainVs(VS_INPUT i)
|
||||
{
|
||||
PS_INPUT o;
|
||||
o.vPositionOs.xyzw = i.vPositionOs.xyzw;
|
||||
o.vNormalOs.xyz = i.vNormalOs.xyz;
|
||||
#if UNITY_VERSION >= 540
|
||||
o.vPositionPs = UnityObjectToClipPos(i.vPositionOs.xyzw);
|
||||
#else
|
||||
o.vPositionPs = UnityObjectToClipPos(i.vPositionOs.xyzw);
|
||||
#endif
|
||||
|
||||
o.clipPos = (float3)0;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
PS_INPUT MainVsClip(VS_INPUT i)
|
||||
{
|
||||
PS_INPUT o;
|
||||
o.vPositionOs.xyzw = i.vPositionOs.xyzw;
|
||||
o.vNormalOs.xyz = i.vNormalOs.xyz;
|
||||
#if UNITY_VERSION >= 540
|
||||
o.vPositionPs = UnityObjectToClipPos(i.vPositionOs.xyzw);
|
||||
#else
|
||||
o.vPositionPs = UnityObjectToClipPos(i.vPositionOs.xyzw);
|
||||
#endif
|
||||
|
||||
o.clipPos = mul(_InverseRotation, mul(unity_ObjectToWorld, i.vPositionOs));
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
PS_INPUT Extrude(PS_INPUT vertex)
|
||||
{
|
||||
PS_INPUT extruded = vertex;
|
||||
|
||||
// Offset along normal in projection space
|
||||
float3 vNormalVs = mul((float3x3)UNITY_MATRIX_IT_MV, vertex.vNormalOs.xyz);
|
||||
float2 vOffsetPs = TransformViewToProjection(vNormalVs.xy);
|
||||
vOffsetPs.xy = normalize(vOffsetPs.xy);
|
||||
|
||||
// Calculate position
|
||||
#if UNITY_VERSION >= 540
|
||||
extruded.vPositionPs = UnityObjectToClipPos(vertex.vPositionOs.xyzw);
|
||||
#else
|
||||
extruded.vPositionPs = UnityObjectToClipPos(vertex.vPositionOs.xyzw);
|
||||
#endif
|
||||
extruded.vPositionPs.xy += vOffsetPs.xy * extruded.vPositionPs.w * g_flOutlineWidth;
|
||||
|
||||
return extruded;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
[maxvertexcount(18)]
|
||||
void ExtrudeGs(triangle PS_INPUT inputTriangle[3], inout TriangleStream<PS_INPUT> outputStream)
|
||||
{
|
||||
float3 a = normalize(inputTriangle[0].vPositionOs.xyz - inputTriangle[1].vPositionOs.xyz);
|
||||
float3 b = normalize(inputTriangle[1].vPositionOs.xyz - inputTriangle[2].vPositionOs.xyz);
|
||||
float3 c = normalize(inputTriangle[2].vPositionOs.xyz - inputTriangle[0].vPositionOs.xyz);
|
||||
|
||||
inputTriangle[0].vNormalOs = inputTriangle[0].vNormalOs + normalize(a - c) * g_flCornerAdjust;
|
||||
inputTriangle[1].vNormalOs = inputTriangle[1].vNormalOs + normalize(-a + b) * g_flCornerAdjust;
|
||||
inputTriangle[2].vNormalOs = inputTriangle[2].vNormalOs + normalize(-b + c) * g_flCornerAdjust;
|
||||
|
||||
PS_INPUT extrudedTriangle0 = Extrude(inputTriangle[0]);
|
||||
PS_INPUT extrudedTriangle1 = Extrude(inputTriangle[1]);
|
||||
PS_INPUT extrudedTriangle2 = Extrude(inputTriangle[2]);
|
||||
|
||||
outputStream.Append(inputTriangle[0]);
|
||||
outputStream.Append(extrudedTriangle0);
|
||||
outputStream.Append(inputTriangle[1]);
|
||||
outputStream.Append(extrudedTriangle0);
|
||||
outputStream.Append(extrudedTriangle1);
|
||||
outputStream.Append(inputTriangle[1]);
|
||||
|
||||
outputStream.Append(inputTriangle[1]);
|
||||
outputStream.Append(extrudedTriangle1);
|
||||
outputStream.Append(extrudedTriangle2);
|
||||
outputStream.Append(inputTriangle[1]);
|
||||
outputStream.Append(extrudedTriangle2);
|
||||
outputStream.Append(inputTriangle[2]);
|
||||
|
||||
outputStream.Append(inputTriangle[2]);
|
||||
outputStream.Append(extrudedTriangle2);
|
||||
outputStream.Append(inputTriangle[0]);
|
||||
outputStream.Append(extrudedTriangle2);
|
||||
outputStream.Append(extrudedTriangle0);
|
||||
outputStream.Append(inputTriangle[0]);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
fixed4 MainPs(PS_INPUT IN) : SV_Target
|
||||
{
|
||||
return _Color;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
fixed4 NullPs(PS_INPUT IN) : SV_Target
|
||||
{
|
||||
return float4(1.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
fixed4 MainPsClip(PS_INPUT IN) : SV_Target
|
||||
{
|
||||
float3 diff = abs(IN.clipPos - _GlobalClipCenter);
|
||||
if (diff.x > _GlobalClipExtents.x || diff.y > _GlobalClipExtents.y || diff.z > _GlobalClipExtents.z)
|
||||
discard;
|
||||
|
||||
return _Color;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
fixed4 NullPsClip (PS_INPUT IN) : SV_Target
|
||||
{
|
||||
float3 diff = abs(IN.clipPos - _GlobalClipCenter);
|
||||
if (diff.x > _GlobalClipExtents.x || diff.y > _GlobalClipExtents.y || diff.z > _GlobalClipExtents.z)
|
||||
discard;
|
||||
|
||||
return float4(1.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c45c396d3a3b42545a66f18564595594
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
96
Assets/XRI_Examples/HoverHighlight/Shaders/Silhouette.shader
Normal file
96
Assets/XRI_Examples/HoverHighlight/Shaders/Silhouette.shader
Normal file
@@ -0,0 +1,96 @@
|
||||
//======= Copyright (c) Valve Corporation, All rights reserved. ===============
|
||||
//
|
||||
// Purpose: Used to show the outline of the object
|
||||
//
|
||||
// Used with permission (3/20/17)
|
||||
// Copyright (C) 2017 Unity Technologies ApS - Fix for hard edges
|
||||
//=============================================================================
|
||||
|
||||
Shader "XRContent/Outline"
|
||||
{
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Properties
|
||||
{
|
||||
_Color( "Color", Color ) = ( .5, .5, .5, 1 )
|
||||
g_flOutlineWidth( "Outline width", Range ( .001, 0.03 ) ) = .005
|
||||
g_flCornerAdjust( "Corner Adjustment", Range(0, 2)) = .5
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
CGINCLUDE
|
||||
#include "Silhouette.cginc"
|
||||
ENDCG
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderType"="Outline" "Queue" = "Overlay+5000" }
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Render the object with stencil=1 to mask out the part that isn't the silhouette
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Pass
|
||||
{
|
||||
Tags { "LightMode" = "Always" }
|
||||
ColorMask 0
|
||||
Cull Off
|
||||
ZWrite Off
|
||||
ZTest Off
|
||||
Stencil
|
||||
{
|
||||
Ref 1
|
||||
Comp always
|
||||
Pass replace
|
||||
}
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex MainVs
|
||||
#pragma fragment NullPs
|
||||
ENDCG
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Render the outline by extruding along vertex normals and using the stencil mask previously rendered. Only render depth, so that the final pass executes
|
||||
// once per fragment (otherwise alpha blending will look bad).
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Pass
|
||||
{
|
||||
Tags { "LightMode" = "Always" }
|
||||
Cull Off
|
||||
ZWrite Off
|
||||
ZTest Off
|
||||
Stencil
|
||||
{
|
||||
Ref 1
|
||||
Comp notequal
|
||||
Pass keep
|
||||
Fail keep
|
||||
}
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex MainVs
|
||||
#pragma geometry ExtrudeGs
|
||||
#pragma fragment MainPs
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Tags{ "LightMode" = "Always" }
|
||||
ColorMask 0
|
||||
Cull Off
|
||||
ZWrite Off
|
||||
ZTest Off
|
||||
Stencil
|
||||
{
|
||||
Ref 0
|
||||
Comp always
|
||||
Pass replace
|
||||
}
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex MainVs
|
||||
#pragma fragment NullPs
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc7db40957fe9f44e9d67526bd229574
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,82 @@
|
||||
//======= Copyright (c) Valve Corporation, All rights reserved. ===============
|
||||
//
|
||||
// Purpose: Used to show the outline of the object
|
||||
//
|
||||
// Used with permission (3/20/17)
|
||||
// Copyright (C) 2017 Unity Technologies ApS - Fix for hard edges
|
||||
// Copyright (C) 2021 Unity Technologies ApS - Adjustment for URP Support
|
||||
//=============================================================================
|
||||
Shader "XRContent/OutlineURP"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_Color("Color", Color) = (.5, .5, .5, 1)
|
||||
g_flOutlineWidth("OutlineWidth", Range(.001, 0.03)) = .0005
|
||||
g_flCornerAdjust("Corner Adjustment", Range(0, 2)) = .5
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
#include "Silhouette.cginc"
|
||||
ENDCG
|
||||
|
||||
SubShader
|
||||
{
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Render the object with stencil=1 to mask out the part that isn't the silhouette
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Pass
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Opaque"
|
||||
"LightMode"="UniversalForward"
|
||||
}
|
||||
|
||||
ColorMask 0
|
||||
Cull Off
|
||||
ZWrite Off
|
||||
ZTest Off
|
||||
Stencil
|
||||
{
|
||||
Ref 1
|
||||
Comp always
|
||||
Pass replace
|
||||
}
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex MainVs
|
||||
#pragma fragment NullPs
|
||||
ENDCG
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Render the outline by extruding along vertex normals and using the stencil mask previously rendered. Only render depth, so that the final pass executes
|
||||
// once per fragment (otherwise alpha blending will look bad).
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Pass
|
||||
{
|
||||
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Opaque"
|
||||
}
|
||||
|
||||
Cull Off
|
||||
|
||||
ZTest LEqual
|
||||
Stencil
|
||||
{
|
||||
Ref 1
|
||||
Comp notequal
|
||||
Pass keep
|
||||
Fail keep
|
||||
}
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex MainVs
|
||||
#pragma geometry ExtrudeGs
|
||||
#pragma fragment MainPs
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce233b3e0a3274b4db21f582cb7abaa4
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
Shader "XRContent/TransparentPulse"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_Color ("Color", Color) = (1,1,1,1)
|
||||
_MainTex ("Texture", 2D) = "white" {}
|
||||
|
||||
_PulseSpeed ("Pulse Speed", Float) = 30.0
|
||||
_PulseMaxAlpha ("Max Pulse Alpha", Range (0, 1)) = 0.5
|
||||
_PulseMinAlpha ("Min Pulse Alpha", Range (0, 1)) = 0
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags {"Queue"="Transparent" "RenderType"="Transparent"}
|
||||
LOD 100
|
||||
ZWrite On
|
||||
Offset -1,-1
|
||||
Blend One OneMinusSrcAlpha
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
float4 _MainTex_ST;
|
||||
fixed4 _Color;
|
||||
float _PulseSpeed;
|
||||
float _PulseMinAlpha;
|
||||
float _PulseMaxAlpha;
|
||||
|
||||
float _DistanceFadeFactor;
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o;
|
||||
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_OUTPUT(v2f, o);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag (v2f i) : SV_Target
|
||||
{
|
||||
fixed4 col = tex2D(_MainTex, i.uv) * _Color;
|
||||
float pulsePhase = 0.5 * (sin(_Time * _PulseSpeed) + 1.0); // Map time to sin wave from 0 - 1
|
||||
float pulseAlpha = _PulseMinAlpha + (pulsePhase)*(_PulseMaxAlpha - _PulseMinAlpha); // Remap wave to min/max alpha range
|
||||
col *= pulseAlpha;
|
||||
return col;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64dbf9ec24b89d54d96a3ec606b5c84c
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user