SpatialButton_Thick.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. using System;
  2. using System.CodeDom;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using UnityEngine.Events;
  7. using UnityEngine.UI;
  8. using EZXR.Glass.Inputs;
  9. using UnityEditor;
  10. using EZXR.Glass.Core;
  11. namespace EZXR.Glass.UI
  12. {
  13. /// <summary>
  14. /// 有厚度的按钮,hover的时候会有半透明浮层在指尖位置,随着指尖按下浮层会有被按下去的效果
  15. /// </summary>
  16. public class SpatialButton_Thick : SpatialButton
  17. {
  18. public Transform _iconMesh;
  19. public MeshRenderer _iconRenderer;
  20. [SerializeField]
  21. private Texture2D icon;
  22. /// <summary>
  23. /// 按钮的图标
  24. /// </summary>
  25. public Texture2D Icon
  26. {
  27. get
  28. {
  29. return icon;
  30. }
  31. set
  32. {
  33. icon = value;
  34. SetIconMaterial();
  35. }
  36. }
  37. public Vector3 iconSize = new Vector3(0.1f, 0.1f, 0.1f);
  38. protected MaterialPropertyBlock icon_MaterialPropertyBlock;
  39. /// <summary>
  40. /// 浮层式Button的浮层,当用指尖进入触发区的时候显示此浮层
  41. /// </summary>
  42. public GameObject buttonHover;
  43. protected MeshRenderer buttonHoverRenderer;
  44. protected MaterialPropertyBlock buttonHover_MaterialPropertyBlock;
  45. /// <summary>
  46. /// 浮层顶部圆环的粗细
  47. /// </summary>
  48. public float circleHoverThick = 0.01f;
  49. // Start is called before the first frame update
  50. protected override void Start()
  51. {
  52. base.Start();
  53. if (Application.isPlaying)
  54. {
  55. //buttonHover.SetActive(false);
  56. SetIconMaterial();
  57. SetButtonHoverMaterial();
  58. }
  59. else
  60. {
  61. #if UNITY_EDITOR
  62. icon_MaterialPropertyBlock = new MaterialPropertyBlock();
  63. _iconRenderer?.GetPropertyBlock(icon_MaterialPropertyBlock);
  64. buttonHoverRenderer = buttonHover?.GetComponent<MeshRenderer>();
  65. buttonHover_MaterialPropertyBlock = new MaterialPropertyBlock();
  66. buttonHoverRenderer?.GetPropertyBlock(buttonHover_MaterialPropertyBlock);
  67. #endif
  68. }
  69. }
  70. protected override void Update()
  71. {
  72. base.Update();
  73. if (!Application.isPlaying)
  74. {
  75. #if UNITY_EDITOR
  76. _iconRenderer.sortingOrder = sortingOrder + 1;
  77. SetIconMaterial();
  78. SetButtonHoverMaterial();
  79. //设置UI尺寸
  80. _iconMesh.localScale = new Vector3(iconSize.x / size.x, iconSize.y / size.y, 0.0001f);
  81. #endif
  82. }
  83. }
  84. void SetIconMaterial()
  85. {
  86. //确保icon_MaterialPropertyBlock不为空
  87. if (icon_MaterialPropertyBlock == null)
  88. {
  89. icon_MaterialPropertyBlock = new MaterialPropertyBlock();
  90. _iconRenderer.GetPropertyBlock(icon_MaterialPropertyBlock);
  91. }
  92. //icon有更改的话同步修改到Material
  93. if (icon != null)
  94. {
  95. _iconRenderer.gameObject.SetActive(true);
  96. icon_MaterialPropertyBlock.SetTexture("_MainTex", icon);
  97. }
  98. else
  99. {
  100. _iconRenderer.gameObject.SetActive(false);
  101. //重置materialPropertyBlock,因为无法直接SetTexture为null
  102. icon_MaterialPropertyBlock.Clear();
  103. }
  104. _iconRenderer.SetPropertyBlock(icon_MaterialPropertyBlock);
  105. }
  106. void SetButtonHoverMaterial()
  107. {
  108. //确保buttonHover_MaterialPropertyBlock不为空
  109. if (buttonHover_MaterialPropertyBlock == null)
  110. {
  111. buttonHoverRenderer = buttonHover?.GetComponent<MeshRenderer>();
  112. buttonHover_MaterialPropertyBlock = new MaterialPropertyBlock();
  113. buttonHoverRenderer?.GetPropertyBlock(buttonHover_MaterialPropertyBlock);
  114. }
  115. buttonHover_MaterialPropertyBlock.SetFloat("_Thickness", circleHoverThick);
  116. buttonHover_MaterialPropertyBlock.SetFloat("_Radius", 0.25f - circleHoverThick);
  117. buttonHoverRenderer.SetPropertyBlock(buttonHover_MaterialPropertyBlock);
  118. }
  119. /// <inheritdoc />
  120. public override void OnPointerHoverEnter(Spatial.InteractiveMode interactiveMode = Spatial.InteractiveMode.None)
  121. {
  122. Debug.Log("OnPointerHoverEnter: " + gameObject.name);
  123. //显示浮层
  124. buttonHover.SetActive(true);
  125. _iconMesh.localPosition = new Vector3(0, 0, _mesh.localScale.z / 2.0f / size.z);
  126. }
  127. /// <inheritdoc />
  128. public override void OnPointerHoverExit()
  129. {
  130. Debug.Log("OnPointerHoverExit: " + gameObject.name);
  131. ////隐藏浮层
  132. //buttonHover.SetActive(false);
  133. _iconMesh.localPosition = new Vector3(0, 0, _mesh.localScale.z / 2.0f / size.z);
  134. //_iconMesh.localPosition = new Vector3(0, 0, 0.00001f);
  135. }
  136. /// <inheritdoc />
  137. public override void OnPointerPressing()
  138. {
  139. Debug.Log("OnPointerPressing: " + gameObject.name);
  140. //将算出的距离直接赋给按键的scale(因为此处按键本身就是按照实际尺寸进行的缩放,所以计算出的length就是scale.z)
  141. _mesh.localScale = new Vector3(_mesh.localScale.x, _mesh.localScale.y, clampLength);
  142. _iconMesh.localPosition = new Vector3(0, 0, _mesh.localScale.z / 2.0f / size.z);
  143. }
  144. /// <inheritdoc />
  145. public override void OnPointerDown()
  146. {
  147. Debug.Log("OnPointerDown: " + gameObject.name);
  148. //将按键按到底
  149. _mesh.localScale = new Vector3(_mesh.localScale.x, _mesh.localScale.y, heightMin);
  150. _iconMesh.localPosition = new Vector3(0, 0, _mesh.localScale.z / 2.0f / size.z);
  151. }
  152. /// <inheritdoc />
  153. public override void OnPointerUp()
  154. {
  155. Debug.Log("OnPointerUp: " + gameObject.name);
  156. _mesh.localScale = new Vector3(_mesh.localScale.x, _mesh.localScale.y, heightMax);
  157. _iconMesh.localPosition = new Vector3(0, 0, _mesh.localScale.z / 2.0f / size.z);
  158. }
  159. }
  160. }