RenderModel.cs 13 KB

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