From 8de7305349a12f9b596568da2ad7f67279c0a94d Mon Sep 17 00:00:00 2001 From: Afeijia <2226012958@qq.com> Date: Sun, 20 Aug 2023 10:56:03 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BE=B9=E7=BC=98=E9=AB=98=E4=BA=AE=E5=8F=8A?= =?UTF-8?q?=E6=9F=9C=E9=97=A8=E5=BC=80=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GQ_TongXin/Assets/Materials/HighLight_VR.cs | 194 ++++++++++++++++++ .../Assets/Materials/HighLight_VR.cs.meta | 11 + GQ_TongXin/Assets/Materials/Silhouette.shader | 183 +++++++++++++++++ .../Assets/Materials/Silhouette.shader.meta | 10 + .../Resources/SteamVR_HoverHighlight.mat | 29 +++ .../Resources/SteamVR_HoverHighlight.mat.meta | 8 + GQ_TongXin/Assets/Scripts/WJ/CabinetDevice.cs | 34 +++ .../Assets/Scripts/WJ/CabinetDevice.cs.meta | 11 + 8 files changed, 480 insertions(+) create mode 100644 GQ_TongXin/Assets/Materials/HighLight_VR.cs create mode 100644 GQ_TongXin/Assets/Materials/HighLight_VR.cs.meta create mode 100644 GQ_TongXin/Assets/Materials/Silhouette.shader create mode 100644 GQ_TongXin/Assets/Materials/Silhouette.shader.meta create mode 100644 GQ_TongXin/Assets/Resources/SteamVR_HoverHighlight.mat create mode 100644 GQ_TongXin/Assets/Resources/SteamVR_HoverHighlight.mat.meta create mode 100644 GQ_TongXin/Assets/Scripts/WJ/CabinetDevice.cs create mode 100644 GQ_TongXin/Assets/Scripts/WJ/CabinetDevice.cs.meta diff --git a/GQ_TongXin/Assets/Materials/HighLight_VR.cs b/GQ_TongXin/Assets/Materials/HighLight_VR.cs new file mode 100644 index 000000000..ededb4518 --- /dev/null +++ b/GQ_TongXin/Assets/Materials/HighLight_VR.cs @@ -0,0 +1,194 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +/// +/// 可交互脚本 +/// +public class HighLight_VR : MonoBehaviour +{ + [ContextMenu("Highlight")] + public void Highlight() + { + wasHovering = isHovering; + isHovering = true; + + if (highlightOnHover == true && wasHovering == false) + { + CreateHighlightRenderers(); + UpdateHighlightRenderers(); + } + } + + [ContextMenu("ShutDownHighlight")] + public void ShutDownHighlight() + { + wasHovering = isHovering; + isHovering = false; + + if (highlightOnHover && highlightHolder != null) + Destroy(highlightHolder); + } + public void OnMouseEnter() + { + wasHovering = isHovering; + isHovering = true; + + if (highlightOnHover == true && wasHovering == false) + { + CreateHighlightRenderers(); + UpdateHighlightRenderers(); + } + } + + public void OnMouseExit() + { + wasHovering = isHovering; + isHovering = false; + + if (highlightOnHover && highlightHolder != null) + Destroy(highlightHolder); + } + + public bool highlightOnHover = true; + protected MeshRenderer[] highlightRenderers; + protected MeshRenderer[] existingRenderers; + protected GameObject highlightHolder; + protected SkinnedMeshRenderer[] highlightSkinnedRenderers; + protected SkinnedMeshRenderer[] existingSkinnedRenderers; + protected static Material highlightMat; + + public GameObject[] hideHighlight; + + public bool isDestroying { get; protected set; } + public bool isHovering { get; protected set; } + public bool wasHovering { get; protected set; } + protected virtual bool ShouldIgnoreHighlight(Component component) + { + return ShouldIgnore(component.gameObject); + } + protected virtual bool ShouldIgnore(GameObject check) + { + for (int ignoreIndex = 0; ignoreIndex < hideHighlight.Length; ignoreIndex++) + { + if (check == hideHighlight[ignoreIndex]) + return true; + } + return false; + } + + protected virtual void Start() + { + highlightMat = (Material)Resources.Load("SteamVR_HoverHighlight", typeof(Material)); + if (highlightMat == null) + Debug.LogError("[SteamVR Interaction] Hover Highlight Material is missing. Please create a material named 'SteamVR_HoverHighlight' and place it in a Resources folder", this); + + } + + protected virtual void CreateHighlightRenderers() + { + existingSkinnedRenderers = this.GetComponentsInChildren(true); + highlightHolder = new GameObject("Highlighter"); + highlightSkinnedRenderers = new SkinnedMeshRenderer[existingSkinnedRenderers.Length]; + + for (int skinnedIndex = 0; skinnedIndex < existingSkinnedRenderers.Length; skinnedIndex++) + { + SkinnedMeshRenderer existingSkinned = existingSkinnedRenderers[skinnedIndex]; + + if (ShouldIgnoreHighlight(existingSkinned)) + continue; + + GameObject newSkinnedHolder = new GameObject("SkinnedHolder"); + newSkinnedHolder.transform.parent = highlightHolder.transform; + SkinnedMeshRenderer newSkinned = newSkinnedHolder.AddComponent(); + Material[] materials = new Material[existingSkinned.sharedMaterials.Length]; + for (int materialIndex = 0; materialIndex < materials.Length; materialIndex++) + { + materials[materialIndex] = highlightMat; + } + + newSkinned.sharedMaterials = materials; + newSkinned.sharedMesh = existingSkinned.sharedMesh; + newSkinned.rootBone = existingSkinned.rootBone; + newSkinned.updateWhenOffscreen = existingSkinned.updateWhenOffscreen; + newSkinned.bones = existingSkinned.bones; + + highlightSkinnedRenderers[skinnedIndex] = newSkinned; + } + + MeshFilter[] existingFilters = this.GetComponentsInChildren(true); + existingRenderers = new MeshRenderer[existingFilters.Length]; + highlightRenderers = new MeshRenderer[existingFilters.Length]; + + for (int filterIndex = 0; filterIndex < existingFilters.Length; filterIndex++) + { + MeshFilter existingFilter = existingFilters[filterIndex]; + MeshRenderer existingRenderer = existingFilter.GetComponent(); + + if (existingFilter == null || existingRenderer == null || ShouldIgnoreHighlight(existingFilter)) + continue; + + GameObject newFilterHolder = new GameObject("FilterHolder"); + newFilterHolder.transform.parent = highlightHolder.transform; + MeshFilter newFilter = newFilterHolder.AddComponent(); + newFilter.sharedMesh = existingFilter.sharedMesh; + MeshRenderer newRenderer = newFilterHolder.AddComponent(); + + Material[] materials = new Material[existingRenderer.sharedMaterials.Length]; + for (int materialIndex = 0; materialIndex < materials.Length; materialIndex++) + { + materials[materialIndex] = highlightMat; + } + newRenderer.sharedMaterials = materials; + + highlightRenderers[filterIndex] = newRenderer; + existingRenderers[filterIndex] = existingRenderer; + } + } + + protected virtual void UpdateHighlightRenderers() + { + if (highlightHolder == null) + return; + + for (int skinnedIndex = 0; skinnedIndex < existingSkinnedRenderers.Length; skinnedIndex++) + { + SkinnedMeshRenderer existingSkinned = existingSkinnedRenderers[skinnedIndex]; + SkinnedMeshRenderer highlightSkinned = highlightSkinnedRenderers[skinnedIndex]; + + if (existingSkinned != null && highlightSkinned != null /*&& attachedToHand == false*/) + { + highlightSkinned.transform.position = existingSkinned.transform.position; + highlightSkinned.transform.rotation = existingSkinned.transform.rotation; + highlightSkinned.transform.localScale = existingSkinned.transform.lossyScale; + highlightSkinned.localBounds = existingSkinned.localBounds; + highlightSkinned.enabled = isHovering && existingSkinned.enabled && existingSkinned.gameObject.activeInHierarchy; + + int blendShapeCount = existingSkinned.sharedMesh.blendShapeCount; + for (int blendShapeIndex = 0; blendShapeIndex < blendShapeCount; blendShapeIndex++) + { + highlightSkinned.SetBlendShapeWeight(blendShapeIndex, existingSkinned.GetBlendShapeWeight(blendShapeIndex)); + } + } + else if (highlightSkinned != null) + highlightSkinned.enabled = false; + + } + + for (int rendererIndex = 0; rendererIndex < highlightRenderers.Length; rendererIndex++) + { + MeshRenderer existingRenderer = existingRenderers[rendererIndex]; + MeshRenderer highlightRenderer = highlightRenderers[rendererIndex]; + + if (existingRenderer != null && highlightRenderer != null /*&& attachedToHand == false*/) + { + highlightRenderer.transform.position = existingRenderer.transform.position; + highlightRenderer.transform.rotation = existingRenderer.transform.rotation; + highlightRenderer.transform.localScale = existingRenderer.transform.lossyScale; + highlightRenderer.enabled = isHovering && existingRenderer.enabled && existingRenderer.gameObject.activeInHierarchy; + } + else if (highlightRenderer != null) + highlightRenderer.enabled = false; + } + } +} \ No newline at end of file diff --git a/GQ_TongXin/Assets/Materials/HighLight_VR.cs.meta b/GQ_TongXin/Assets/Materials/HighLight_VR.cs.meta new file mode 100644 index 000000000..8cf8ed1ce --- /dev/null +++ b/GQ_TongXin/Assets/Materials/HighLight_VR.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0819b1ac6535ba14e946e42278883071 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/GQ_TongXin/Assets/Materials/Silhouette.shader b/GQ_TongXin/Assets/Materials/Silhouette.shader new file mode 100644 index 000000000..244a5bf7b --- /dev/null +++ b/GQ_TongXin/Assets/Materials/Silhouette.shader @@ -0,0 +1,183 @@ +//======= Copyright (c) Valve Corporation, All rights reserved. =============== +// +// Purpose: Used to show the outline of the object +// +//============================================================================= +// UNITY_SHADER_NO_UPGRADE +Shader "Valve/VR/Silhouette" +{ + //------------------------------------------------------------------------------------------------------------------------------------------------------------- + Properties + { + g_vOutlineColor( "Outline Color", Color ) = ( .5, .5, .5, 1 ) + g_flOutlineWidth( "Outline width", Range ( .001, 0.03 ) ) = .005 + g_flCornerAdjust( "Corner Adjustment", Range( 0, 2 ) ) = .5 + } + + //------------------------------------------------------------------------------------------------------------------------------------------------------------- + CGINCLUDE + + //------------------------------------------------------------------------------------------------------------------------------------------------------------- + #pragma target 5.0 + + //------------------------------------------------------------------------------------------------------------------------------------------------------------- + #include "UnityCG.cginc" + + //------------------------------------------------------------------------------------------------------------------------------------------------------------- + float4 g_vOutlineColor; + float g_flOutlineWidth; + float g_flCornerAdjust; + + //------------------------------------------------------------------------------------------------------------------------------------------------------------- + struct VS_INPUT + { + float4 vPositionOs : POSITION; + float3 vNormalOs : NORMAL; + }; + + //------------------------------------------------------------------------------------------------------------------------------------------------------------- + struct PS_INPUT + { + float4 vPositionOs : TEXCOORD0; + float3 vNormalOs : TEXCOORD1; + 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 = mul( UNITY_MATRIX_MVP, i.vPositionOs.xyzw ); +#endif + 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 = mul( UNITY_MATRIX_MVP, 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 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 i ) : SV_Target + { + return g_vOutlineColor; + } + + //------------------------------------------------------------------------------------------------------------------------------------------------------------- + fixed4 NullPs( PS_INPUT i ) : SV_Target + { + return float4( 1.0, 0.0, 1.0, 1.0 ); + } + + ENDCG + + SubShader + { + Tags { "RenderType"="Outline" "Queue" = "Geometry-1" } + + //------------------------------------------------------------------------------------------------------------------------------------------------------------- + // 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 + 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 On + Stencil + { + Ref 1 + Comp notequal + Pass keep + Fail keep + } + + CGPROGRAM + #pragma vertex MainVs + #pragma geometry ExtrudeGs + #pragma fragment MainPs + ENDCG + } + } +} \ No newline at end of file diff --git a/GQ_TongXin/Assets/Materials/Silhouette.shader.meta b/GQ_TongXin/Assets/Materials/Silhouette.shader.meta new file mode 100644 index 000000000..8b31f0df7 --- /dev/null +++ b/GQ_TongXin/Assets/Materials/Silhouette.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 68bee786f96b1a348a1d983d02d3b803 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/GQ_TongXin/Assets/Resources/SteamVR_HoverHighlight.mat b/GQ_TongXin/Assets/Resources/SteamVR_HoverHighlight.mat new file mode 100644 index 000000000..fda7f539b --- /dev/null +++ b/GQ_TongXin/Assets/Resources/SteamVR_HoverHighlight.mat @@ -0,0 +1,29 @@ +%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: SteamVR_HoverHighlight + m_Shader: {fileID: 4800000, guid: 68bee786f96b1a348a1d983d02d3b803, type: 3} + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: [] + m_Ints: [] + m_Floats: + - g_flCornerAdjust: 0.7 + - g_flOutlineWidth: 0.01 + m_Colors: + - g_vOutlineColor: {r: 0.20064259, g: 1, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/GQ_TongXin/Assets/Resources/SteamVR_HoverHighlight.mat.meta b/GQ_TongXin/Assets/Resources/SteamVR_HoverHighlight.mat.meta new file mode 100644 index 000000000..b647bbee5 --- /dev/null +++ b/GQ_TongXin/Assets/Resources/SteamVR_HoverHighlight.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1fde6efbbc10ae144a119b8266db6843 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/GQ_TongXin/Assets/Scripts/WJ/CabinetDevice.cs b/GQ_TongXin/Assets/Scripts/WJ/CabinetDevice.cs new file mode 100644 index 000000000..560af58fe --- /dev/null +++ b/GQ_TongXin/Assets/Scripts/WJ/CabinetDevice.cs @@ -0,0 +1,34 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class CabinetDevice : MonoBehaviour +{ + public Vector3 open_angle; + public List door_list = new List(); + // Start is called before the first frame update + void Start() + { + for (int i = 0; i < transform.childCount; i++) + { + if(transform.GetChild(i).name.Contains("Object")|| transform.GetChild(i).name.Contains("object")) + { + door_list.Add(transform.GetChild(i)); + } + } + } + + // Update is called once per frame + void Update() + { + UpdateDoorState(open); + } + public bool open; + /// + /// ¹״̬ + /// + public void UpdateDoorState(bool open) + { + door_list.ForEach(t => { t.localEulerAngles = open ? open_angle : Vector3.zero; }); + } +} diff --git a/GQ_TongXin/Assets/Scripts/WJ/CabinetDevice.cs.meta b/GQ_TongXin/Assets/Scripts/WJ/CabinetDevice.cs.meta new file mode 100644 index 000000000..813a83bdb --- /dev/null +++ b/GQ_TongXin/Assets/Scripts/WJ/CabinetDevice.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d910e458938e0c42bbc237f96c79230 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: