RenderModel.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. //======= Copyright (c) Valve Corporation, All rights reserved. ===============
  2. using UnityEngine;
  3. using System.Collections;
  4. using System;
  5. namespace Valve.VR.InteractionSystem
  6. {
  7. public class RenderModel : MonoBehaviour
  8. {
  9. public GameObject handPrefab;
  10. protected GameObject handInstance;
  11. protected Renderer[] handRenderers;
  12. public bool displayHandByDefault = true;
  13. protected SteamVR_Behaviour_Skeleton handSkeleton;
  14. protected Animator handAnimator;
  15. protected string animatorParameterStateName = "AnimationState";
  16. protected int handAnimatorStateId = -1;
  17. [Space]
  18. public GameObject controllerPrefab;
  19. protected GameObject controllerInstance;
  20. protected Renderer[] controllerRenderers;
  21. protected SteamVR_RenderModel controllerRenderModel;
  22. public bool displayControllerByDefault = true;
  23. protected Material delayedSetMaterial;
  24. public event Action onControllerLoaded;
  25. protected SteamVR_Events.Action renderModelLoadedAction;
  26. protected SteamVR_Input_Sources inputSource;
  27. protected void Awake()
  28. {
  29. renderModelLoadedAction = SteamVR_Events.RenderModelLoadedAction(OnRenderModelLoaded);
  30. InitializeHand();
  31. InitializeController();
  32. }
  33. protected void InitializeHand()
  34. {
  35. if (handPrefab != null)
  36. {
  37. handInstance = GameObject.Instantiate(handPrefab);
  38. handInstance.transform.parent = this.transform;
  39. handInstance.transform.localPosition = Vector3.zero;
  40. handInstance.transform.localRotation = Quaternion.identity;
  41. handInstance.transform.localScale = handPrefab.transform.localScale;
  42. handSkeleton = handInstance.GetComponent<SteamVR_Behaviour_Skeleton>();
  43. handSkeleton.origin = Player.instance.trackingOriginTransform;
  44. handSkeleton.updatePose = false;
  45. handSkeleton.skeletonAction.onActiveChange += OnSkeletonActiveChange;
  46. handRenderers = handInstance.GetComponentsInChildren<Renderer>();
  47. if (displayHandByDefault == false)
  48. SetHandVisibility(false);
  49. handAnimator = handInstance.GetComponentInChildren<Animator>();
  50. if (handSkeleton.skeletonAction.activeBinding == false)
  51. {
  52. Debug.LogWarning("Skeleton action: " + handSkeleton.skeletonAction.GetPath() + " is not bound. Your controller may not support SteamVR Skeleton Input.");
  53. DestroyHand();
  54. }
  55. }
  56. }
  57. protected void InitializeController()
  58. {
  59. if (controllerPrefab != null)
  60. {
  61. controllerInstance = GameObject.Instantiate(controllerPrefab);
  62. controllerInstance.transform.parent = this.transform;
  63. controllerInstance.transform.localPosition = Vector3.zero;
  64. controllerInstance.transform.localRotation = Quaternion.identity;
  65. controllerInstance.transform.localScale = controllerPrefab.transform.localScale;
  66. controllerRenderModel = controllerInstance.GetComponent<SteamVR_RenderModel>();
  67. }
  68. }
  69. protected virtual void DestroyHand()
  70. {
  71. if (handSkeleton != null)
  72. handSkeleton.skeletonAction.onActiveChange -= OnSkeletonActiveChange;
  73. if (handInstance != null)
  74. {
  75. Destroy(handInstance);
  76. handRenderers = null;
  77. handInstance = null;
  78. handSkeleton = null;
  79. handAnimator = null;
  80. }
  81. }
  82. protected virtual void OnSkeletonActiveChange(SteamVR_Action_Skeleton changedAction, bool newState)
  83. {
  84. if (newState)
  85. {
  86. InitializeHand();
  87. }
  88. else
  89. {
  90. DestroyHand();
  91. }
  92. }
  93. protected void OnEnable()
  94. {
  95. renderModelLoadedAction.enabled = true;
  96. }
  97. protected void OnDisable()
  98. {
  99. renderModelLoadedAction.enabled = false;
  100. }
  101. protected void OnDestroy()
  102. {
  103. DestroyHand();
  104. }
  105. public SteamVR_Behaviour_Skeleton GetSkeleton()
  106. {
  107. return handSkeleton;
  108. }
  109. public virtual void SetInputSource(SteamVR_Input_Sources newInputSource)
  110. {
  111. inputSource = newInputSource;
  112. if (controllerRenderModel != null)
  113. controllerRenderModel.SetInputSource(inputSource);
  114. }
  115. public virtual void OnHandInitialized(int deviceIndex)
  116. {
  117. controllerRenderModel.SetInputSource(inputSource);
  118. controllerRenderModel.SetDeviceIndex(deviceIndex);
  119. }
  120. public void MatchHandToTransform(Transform match)
  121. {
  122. if (handInstance != null)
  123. {
  124. handInstance.transform.position = match.transform.position;
  125. handInstance.transform.rotation = match.transform.rotation;
  126. }
  127. }
  128. public void SetHandPosition(Vector3 newPosition)
  129. {
  130. if (handInstance != null)
  131. {
  132. handInstance.transform.position = newPosition;
  133. }
  134. }
  135. public void SetHandRotation(Quaternion newRotation)
  136. {
  137. if (handInstance != null)
  138. {
  139. handInstance.transform.rotation = newRotation;
  140. }
  141. }
  142. public Vector3 GetHandPosition()
  143. {
  144. if (handInstance != null)
  145. {
  146. return handInstance.transform.position;
  147. }
  148. return Vector3.zero;
  149. }
  150. public Quaternion GetHandRotation()
  151. {
  152. if (handInstance != null)
  153. {
  154. return handInstance.transform.rotation;
  155. }
  156. return Quaternion.identity;
  157. }
  158. private void OnRenderModelLoaded(SteamVR_RenderModel loadedRenderModel, bool success)
  159. {
  160. if (controllerRenderModel == loadedRenderModel)
  161. {
  162. controllerRenderers = controllerInstance.GetComponentsInChildren<Renderer>();
  163. if (displayControllerByDefault == false)
  164. SetControllerVisibility(false);
  165. if (delayedSetMaterial != null)
  166. SetControllerMaterial(delayedSetMaterial);
  167. if (onControllerLoaded != null)
  168. onControllerLoaded.Invoke();
  169. }
  170. }
  171. public void SetVisibility(bool state, bool overrideDefault = false)
  172. {
  173. if (state == false || displayControllerByDefault || overrideDefault)
  174. SetControllerVisibility(state);
  175. if (state == false || displayHandByDefault || overrideDefault)
  176. SetHandVisibility(state);
  177. }
  178. public void Show(bool overrideDefault = false)
  179. {
  180. SetVisibility(true, overrideDefault);
  181. }
  182. public void Hide()
  183. {
  184. SetVisibility(false);
  185. }
  186. public virtual void SetMaterial(Material material)
  187. {
  188. SetControllerMaterial(material);
  189. SetHandMaterial(material);
  190. }
  191. public void SetControllerMaterial(Material material)
  192. {
  193. if (controllerRenderers == null)
  194. {
  195. delayedSetMaterial = material;
  196. return;
  197. }
  198. for (int rendererIndex = 0; rendererIndex < controllerRenderers.Length; rendererIndex++)
  199. {
  200. controllerRenderers[rendererIndex].material = material;
  201. }
  202. }
  203. public void SetHandMaterial(Material material)
  204. {
  205. for (int rendererIndex = 0; rendererIndex < handRenderers.Length; rendererIndex++)
  206. {
  207. handRenderers[rendererIndex].material = material;
  208. }
  209. }
  210. public void SetControllerVisibility(bool state, bool permanent = false)
  211. {
  212. if (permanent)
  213. displayControllerByDefault = state;
  214. if (controllerRenderers == null)
  215. return;
  216. for (int rendererIndex = 0; rendererIndex < controllerRenderers.Length; rendererIndex++)
  217. {
  218. controllerRenderers[rendererIndex].enabled = state;
  219. }
  220. }
  221. public void SetHandVisibility(bool state, bool permanent = false)
  222. {
  223. if (permanent)
  224. displayHandByDefault = state;
  225. if (handRenderers == null)
  226. return;
  227. for (int rendererIndex = 0; rendererIndex < handRenderers.Length; rendererIndex++)
  228. {
  229. handRenderers[rendererIndex].enabled = state;
  230. }
  231. }
  232. public bool IsHandVisibile()
  233. {
  234. if (handRenderers == null)
  235. return false;
  236. for (int rendererIndex = 0; rendererIndex < handRenderers.Length; rendererIndex++)
  237. {
  238. if (handRenderers[rendererIndex].enabled)
  239. return true;
  240. }
  241. return false;
  242. }
  243. public bool IsControllerVisibile()
  244. {
  245. if (controllerRenderers == null)
  246. return false;
  247. for (int rendererIndex = 0; rendererIndex < controllerRenderers.Length; rendererIndex++)
  248. {
  249. if (controllerRenderers[rendererIndex].enabled)
  250. return true;
  251. }
  252. return false;
  253. }
  254. public Transform GetBone(int boneIndex)
  255. {
  256. if (handSkeleton != null)
  257. {
  258. return handSkeleton.GetBone(boneIndex);
  259. }
  260. return null;
  261. }
  262. public Vector3 GetBonePosition(int boneIndex, bool local = false)
  263. {
  264. if (handSkeleton != null)
  265. {
  266. return handSkeleton.GetBonePosition(boneIndex, local);
  267. }
  268. return Vector3.zero;
  269. }
  270. public Vector3 GetControllerPosition(string componentName = null)
  271. {
  272. if (controllerRenderModel != null)
  273. return controllerRenderModel.GetComponentTransform(componentName).position;
  274. return Vector3.zero;
  275. }
  276. public Quaternion GetBoneRotation(int boneIndex, bool local = false)
  277. {
  278. if (handSkeleton != null)
  279. {
  280. return handSkeleton.GetBoneRotation(boneIndex, local);
  281. }
  282. return Quaternion.identity;
  283. }
  284. public void SetSkeletonRangeOfMotion(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds = 0.1f)
  285. {
  286. if (handSkeleton != null)
  287. {
  288. handSkeleton.SetRangeOfMotion(newRangeOfMotion, blendOverSeconds);
  289. }
  290. }
  291. public EVRSkeletalMotionRange GetSkeletonRangeOfMotion
  292. {
  293. get
  294. {
  295. if (handSkeleton != null)
  296. return handSkeleton.rangeOfMotion;
  297. else
  298. return EVRSkeletalMotionRange.WithController;
  299. }
  300. }
  301. public void SetTemporarySkeletonRangeOfMotion(SkeletalMotionRangeChange temporaryRangeOfMotionChange, float blendOverSeconds = 0.1f)
  302. {
  303. if (handSkeleton != null)
  304. {
  305. handSkeleton.SetTemporaryRangeOfMotion((EVRSkeletalMotionRange)temporaryRangeOfMotionChange, blendOverSeconds);
  306. }
  307. }
  308. public void ResetTemporarySkeletonRangeOfMotion(float blendOverSeconds = 0.1f)
  309. {
  310. if (handSkeleton != null)
  311. {
  312. handSkeleton.ResetTemporaryRangeOfMotion(blendOverSeconds);
  313. }
  314. }
  315. public void SetAnimationState(int stateValue)
  316. {
  317. if (handSkeleton != null)
  318. {
  319. if (handSkeleton.isBlending == false)
  320. handSkeleton.BlendToAnimation();
  321. if (CheckAnimatorInit())
  322. handAnimator.SetInteger(handAnimatorStateId, stateValue);
  323. }
  324. }
  325. public void StopAnimation()
  326. {
  327. if (handSkeleton != null)
  328. {
  329. if (handSkeleton.isBlending == false)
  330. handSkeleton.BlendToSkeleton();
  331. if (CheckAnimatorInit())
  332. handAnimator.SetInteger(handAnimatorStateId, 0);
  333. }
  334. }
  335. private bool CheckAnimatorInit()
  336. {
  337. if (handAnimatorStateId == -1 && handAnimator != null)
  338. {
  339. if (handAnimator.gameObject.activeInHierarchy && handAnimator.isInitialized)
  340. {
  341. AnimatorControllerParameter[] parameters = handAnimator.parameters;
  342. for (int parameterIndex = 0; parameterIndex < parameters.Length; parameterIndex++)
  343. {
  344. if (string.Equals(parameters[parameterIndex].name, animatorParameterStateName, StringComparison.CurrentCultureIgnoreCase))
  345. handAnimatorStateId = parameters[parameterIndex].nameHash;
  346. }
  347. }
  348. }
  349. return handAnimatorStateId != -1 && handAnimator != null && handAnimator.isInitialized;
  350. }
  351. }
  352. }