Advertisement
Guest User

asfdasfafsw

a guest
Aug 24th, 2016
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.82 KB | None | 0 0
  1. //=====================================================================================
  2. //
  3. // Purpose: Provide a mechanism for determining if a game world object is interactable
  4. //
  5. // This script should be attached to any object that needs touch, use or grab
  6. //
  7. // An optional highlight color can be set to change the object's appearance if it is
  8. // invoked.
  9. //
  10. //=====================================================================================
  11. namespace VRTK
  12. {
  13. using UnityEngine;
  14. using System.Collections;
  15. using System.Collections.Generic;
  16.  
  17.  
  18. public struct InteractableObjectEventArgs
  19. {
  20. public GameObject interactingObject;
  21. }
  22.  
  23. public delegate void InteractableObjectEventHandler(object sender, InteractableObjectEventArgs e);
  24.  
  25. public class VRTK_InteractableObject : MonoBehaviour
  26. {
  27. public enum GrabAttachType
  28. {
  29. Fixed_Joint,
  30. Spring_Joint,
  31. Track_Object,
  32. Child_Of_Controller
  33. }
  34.  
  35. public enum AllowedController
  36. {
  37. Both,
  38. Left_Only,
  39. Right_Only
  40. }
  41.  
  42. [Header("Touch Interactions", order = 1)]
  43. public bool highlightOnTouch = false;
  44. public Color touchHighlightColor = Color.clear;
  45. public Vector2 rumbleOnTouch = Vector2.zero;
  46. public AllowedController allowedTouchControllers = AllowedController.Both;
  47.  
  48. [Header("Grab Interactions", order = 2)]
  49. public bool isGrabbable = false;
  50. public bool isDroppable = true;
  51. public bool isSwappable = true;
  52. public bool holdButtonToGrab = true;
  53. public Vector2 rumbleOnGrab = Vector2.zero;
  54. public AllowedController allowedGrabControllers = AllowedController.Both;
  55. public bool precisionSnap;
  56. public Transform rightSnapHandle;
  57. public Transform leftSnapHandle;
  58.  
  59. [Header("Grab Mechanics", order = 3)]
  60. public GrabAttachType grabAttachMechanic = GrabAttachType.Fixed_Joint;
  61. public float detachThreshold = 500f;
  62. public float springJointStrength = 500f;
  63. public float springJointDamper = 50f;
  64. public float throwMultiplier = 1f;
  65. public float onGrabCollisionDelay = 0f;
  66.  
  67. [Header("Use Interactions", order = 4)]
  68. public bool isUsable = false;
  69. public bool holdButtonToUse = true;
  70. public bool pointerActivatesUseAction = false;
  71. public Vector2 rumbleOnUse = Vector2.zero;
  72. public AllowedController allowedUseControllers = AllowedController.Both;
  73.  
  74. public event InteractableObjectEventHandler InteractableObjectTouched;
  75. public event InteractableObjectEventHandler InteractableObjectUntouched;
  76. public event InteractableObjectEventHandler InteractableObjectGrabbed;
  77. public event InteractableObjectEventHandler InteractableObjectUngrabbed;
  78. public event InteractableObjectEventHandler InteractableObjectUsed;
  79. public event InteractableObjectEventHandler InteractableObjectUnused;
  80.  
  81. protected Rigidbody rb;
  82. protected GameObject touchingObject = null;
  83. protected GameObject grabbingObject = null;
  84. protected GameObject usingObject = null;
  85.  
  86. private int usingState = 0;
  87. private Dictionary<string, Color> originalObjectColours;
  88.  
  89. private Transform grabbedSnapHandle;
  90. private Transform trackPoint;
  91. private bool customTrackPoint = false;
  92.  
  93. private Transform previousParent;
  94. private bool previousKinematicState;
  95. private bool previousIsGrabbable;
  96.  
  97. public virtual void OnInteractableObjectTouched(InteractableObjectEventArgs e)
  98. {
  99. if (InteractableObjectTouched != null)
  100. InteractableObjectTouched(this, e);
  101. }
  102.  
  103. public virtual void OnInteractableObjectUntouched(InteractableObjectEventArgs e)
  104. {
  105. if (InteractableObjectUntouched != null)
  106. InteractableObjectUntouched(this, e);
  107. }
  108.  
  109. public virtual void OnInteractableObjectGrabbed(InteractableObjectEventArgs e)
  110. {
  111. if (InteractableObjectGrabbed != null)
  112. InteractableObjectGrabbed(this, e);
  113. }
  114.  
  115. public virtual void OnInteractableObjectUngrabbed(InteractableObjectEventArgs e)
  116. {
  117. if (InteractableObjectUngrabbed != null)
  118. InteractableObjectUngrabbed(this, e);
  119. }
  120.  
  121. public virtual void OnInteractableObjectUsed(InteractableObjectEventArgs e)
  122. {
  123. if (InteractableObjectUsed != null)
  124. InteractableObjectUsed(this, e);
  125. }
  126.  
  127. public virtual void OnInteractableObjectUnused(InteractableObjectEventArgs e)
  128. {
  129. if (InteractableObjectUnused != null)
  130. InteractableObjectUnused(this, e);
  131. }
  132.  
  133. public InteractableObjectEventArgs SetInteractableObjectEvent(GameObject interactingObject)
  134. {
  135. InteractableObjectEventArgs e;
  136. e.interactingObject = interactingObject;
  137. return e;
  138. }
  139.  
  140. public bool IsTouched()
  141. {
  142. return (touchingObject != null);
  143. }
  144.  
  145. public bool IsGrabbed()
  146. {
  147. return (grabbingObject != null);
  148. }
  149.  
  150. public bool IsUsing()
  151. {
  152. return (usingObject != null);
  153. }
  154.  
  155. public virtual void StartTouching(GameObject currentTouchingObject)
  156. {
  157. OnInteractableObjectTouched(SetInteractableObjectEvent(currentTouchingObject));
  158. touchingObject = currentTouchingObject;
  159. }
  160.  
  161. public virtual void StopTouching(GameObject previousTouchingObject)
  162. {
  163. OnInteractableObjectUntouched(SetInteractableObjectEvent(previousTouchingObject));
  164. touchingObject = null;
  165. }
  166.  
  167. public virtual void Grabbed(GameObject currentGrabbingObject)
  168. {
  169.  
  170. OnInteractableObjectGrabbed(SetInteractableObjectEvent(currentGrabbingObject));
  171. ForceReleaseGrab();
  172. RemoveTrackPoint();
  173. grabbingObject = currentGrabbingObject;
  174. SetTrackPoint(grabbingObject);
  175. if (!isSwappable)
  176. {
  177. previousIsGrabbable = isGrabbable;
  178. isGrabbable = false;
  179. }
  180. }
  181.  
  182. public virtual void Ungrabbed(GameObject previousGrabbingObject)
  183. {
  184. OnInteractableObjectUngrabbed(SetInteractableObjectEvent(previousGrabbingObject));
  185. RemoveTrackPoint();
  186. grabbedSnapHandle = null;
  187. grabbingObject = null;
  188. LoadPreviousState();
  189. }
  190.  
  191. public virtual void StartUsing(GameObject currentUsingObject)
  192. {
  193. OnInteractableObjectUsed(SetInteractableObjectEvent(currentUsingObject));
  194. usingObject = currentUsingObject;
  195. }
  196.  
  197. public virtual void StopUsing(GameObject previousUsingObject)
  198. {
  199. OnInteractableObjectUnused(SetInteractableObjectEvent(previousUsingObject));
  200. usingObject = null;
  201. }
  202.  
  203. public virtual void ToggleHighlight(bool toggle)
  204. {
  205. ToggleHighlight(toggle, Color.clear);
  206. }
  207.  
  208. public virtual void ToggleHighlight(bool toggle, Color globalHighlightColor)
  209. {
  210. if (highlightOnTouch)
  211. {
  212. if (toggle && !IsGrabbed() && !IsUsing())
  213. {
  214. Color color = (touchHighlightColor != Color.clear ? touchHighlightColor : globalHighlightColor);
  215. if (color != Color.clear)
  216. {
  217. var colorArray = BuildHighlightColorArray(color);
  218. ChangeColor(colorArray);
  219. }
  220. }
  221. else
  222. {
  223. if (originalObjectColours == null)
  224. {
  225. Debug.LogError("VRTK_InteractableObject has not had the Start() method called, if you are inheriting this class then call base.Start() in your Start() method.");
  226. return;
  227. }
  228. ChangeColor(originalObjectColours);
  229. }
  230. }
  231. }
  232.  
  233. public int UsingState
  234. {
  235. get { return usingState; }
  236. set { usingState = value; }
  237. }
  238.  
  239. public void PauseCollisions()
  240. {
  241. if (onGrabCollisionDelay > 0f)
  242. {
  243. if (this.GetComponent<Rigidbody>())
  244. {
  245. this.GetComponent<Rigidbody>().detectCollisions = false;
  246. }
  247. foreach (Rigidbody rb in this.GetComponentsInChildren<Rigidbody>())
  248. {
  249. rb.detectCollisions = false;
  250. }
  251. Invoke("UnpauseCollisions", onGrabCollisionDelay);
  252. }
  253. }
  254.  
  255. public bool AttachIsTrackObject()
  256. {
  257. return (grabAttachMechanic == GrabAttachType.Track_Object);
  258. }
  259.  
  260. public void ZeroVelocity()
  261. {
  262. if (this.GetComponent<Rigidbody>())
  263. {
  264. this.GetComponent<Rigidbody>().velocity = Vector3.zero;
  265. this.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
  266. }
  267. }
  268.  
  269. public void SaveCurrentState()
  270. {
  271. if (grabbingObject == null)
  272. {
  273. previousParent = this.transform.parent;
  274. previousKinematicState = rb.isKinematic;
  275. }
  276. }
  277.  
  278. public void ToggleKinematic(bool state)
  279. {
  280. rb.isKinematic = state;
  281. }
  282.  
  283. public GameObject GetGrabbingObject()
  284. {
  285. return grabbingObject;
  286. }
  287.  
  288. public bool IsValidInteractableController(GameObject actualController, AllowedController controllerCheck)
  289. {
  290. if (controllerCheck == AllowedController.Both)
  291. {
  292. return true;
  293. }
  294.  
  295. var controllerHand = DeviceFinder.GetControllerHandType(controllerCheck.ToString().Replace("_Only", ""));
  296. return (DeviceFinder.IsControllerOfHand(actualController, controllerHand));
  297. }
  298.  
  299. public void ForceStopInteracting()
  300. {
  301. if (touchingObject != null)
  302. {
  303. touchingObject.GetComponent<VRTK_InteractTouch>().ForceStopTouching();
  304. }
  305.  
  306. if (grabbingObject != null)
  307. {
  308. grabbingObject.GetComponent<VRTK_InteractTouch>().ForceStopTouching();
  309. grabbingObject.GetComponent<VRTK_InteractGrab>().ForceRelease();
  310. }
  311.  
  312. if (usingObject != null)
  313. {
  314. usingObject.GetComponent<VRTK_InteractTouch>().ForceStopTouching();
  315. usingObject.GetComponent<VRTK_InteractUse>().ForceStopUsing();
  316. }
  317. }
  318.  
  319. public void SetGrabbedSnapHandle(Transform handle)
  320. {
  321. grabbedSnapHandle = handle;
  322. }
  323.  
  324. protected virtual void Awake()
  325. {
  326. rb = this.GetComponent<Rigidbody>();
  327.  
  328. // If there is no rigid body, add one and set it to 'kinematic'.
  329. if (!rb)
  330. {
  331. rb = gameObject.AddComponent<Rigidbody>();
  332. rb.isKinematic = true;
  333. }
  334. rb.maxAngularVelocity = float.MaxValue;
  335. }
  336.  
  337. protected virtual void Start()
  338. {
  339. originalObjectColours = StoreOriginalColors();
  340. }
  341.  
  342. protected virtual void Update()
  343. {
  344. if (!this.gameObject.activeInHierarchy)
  345. {
  346. ForceStopInteracting();
  347. }
  348.  
  349. if (grabAttachMechanic == GrabAttachType.Track_Object)
  350. {
  351. CheckBreakDistance();
  352. }
  353. }
  354.  
  355. protected virtual void FixedUpdate()
  356. {
  357. if (grabAttachMechanic == GrabAttachType.Track_Object)
  358. {
  359. FixedUpdateTrackedObject();
  360. }
  361. }
  362.  
  363. protected virtual void OnDisable()
  364. {
  365. ForceStopInteracting();
  366. }
  367.  
  368. protected virtual void OnJointBreak(float force)
  369. {
  370. ForceReleaseGrab();
  371. }
  372.  
  373. protected virtual void LoadPreviousState()
  374. {
  375. if (this.gameObject.activeInHierarchy)
  376. {
  377. this.transform.parent = previousParent;
  378. }
  379. rb.isKinematic = previousKinematicState;
  380. if (!isSwappable)
  381. {
  382. isGrabbable = previousIsGrabbable;
  383. }
  384. }
  385.  
  386. private void ForceReleaseGrab()
  387. {
  388. if (grabbingObject)
  389. {
  390. grabbingObject.GetComponent<VRTK_InteractGrab>().ForceRelease();
  391. }
  392. }
  393.  
  394. private void UnpauseCollisions()
  395. {
  396. if (this.GetComponent<Rigidbody>())
  397. {
  398. this.GetComponent<Rigidbody>().detectCollisions = true;
  399. }
  400. foreach (Rigidbody rb in this.GetComponentsInChildren<Rigidbody>())
  401. {
  402. rb.detectCollisions = true;
  403. }
  404. }
  405.  
  406. private Renderer[] GetRendererArray()
  407. {
  408. return (GetComponents<Renderer>().Length > 0 ? GetComponents<Renderer>() : GetComponentsInChildren<Renderer>());
  409. }
  410.  
  411. private Dictionary<string, Color> StoreOriginalColors()
  412. {
  413. Dictionary<string, Color> colors = new Dictionary<string, Color>();
  414. foreach (Renderer renderer in GetRendererArray())
  415. {
  416. if (renderer.material.HasProperty("_Color"))
  417. {
  418. colors[renderer.gameObject.name] = renderer.material.color;
  419. }
  420. }
  421. return colors;
  422. }
  423.  
  424. private Dictionary<string, Color> BuildHighlightColorArray(Color color)
  425. {
  426. Dictionary<string, Color> colors = new Dictionary<string, Color>();
  427. foreach (Renderer renderer in GetRendererArray())
  428. {
  429. if (renderer.material.HasProperty("_Color"))
  430. {
  431. colors[renderer.gameObject.name] = color;
  432. }
  433. }
  434. return colors;
  435. }
  436.  
  437. private void ChangeColor(Dictionary<string, Color> colors)
  438. {
  439. foreach (Renderer renderer in GetRendererArray())
  440. {
  441. if (renderer.material.HasProperty("_Color") && colors.ContainsKey(renderer.gameObject.name))
  442. {
  443. renderer.material.color = colors[renderer.gameObject.name];
  444. }
  445. }
  446. }
  447.  
  448. private void CheckBreakDistance()
  449. {
  450. if (trackPoint)
  451. {
  452. float distance = Vector3.Distance(trackPoint.position, this.transform.position);
  453. if (distance > (detachThreshold / 1000))
  454. {
  455. ForceReleaseGrab();
  456. }
  457. }
  458. }
  459.  
  460. private void SetTrackPoint(GameObject point)
  461. {
  462. Transform controllerPoint = point.transform;
  463.  
  464. if (point.GetComponent<VRTK_InteractGrab>() && point.GetComponent<VRTK_InteractGrab>().controllerAttachPoint)
  465. {
  466. controllerPoint = point.GetComponent<VRTK_InteractGrab>().controllerAttachPoint.transform;
  467. }
  468.  
  469. if (grabAttachMechanic == GrabAttachType.Track_Object && precisionSnap)
  470. {
  471. trackPoint = new GameObject(string.Format("[{0}]TrackObject_PrecisionSnap_AttachPoint", this.gameObject.name)).transform;
  472. trackPoint.parent = point.transform;
  473. trackPoint.position = this.transform.position;
  474. trackPoint.rotation = this.transform.rotation;
  475. customTrackPoint = true;
  476. }
  477. else
  478. {
  479. trackPoint = controllerPoint;
  480. customTrackPoint = false;
  481. }
  482. }
  483.  
  484. private void RemoveTrackPoint()
  485. {
  486. if (customTrackPoint && trackPoint)
  487. {
  488. Destroy(trackPoint.gameObject);
  489. }
  490. else
  491. {
  492. trackPoint = null;
  493. }
  494. }
  495.  
  496. private void FixedUpdateTrackedObject()
  497. {
  498. if (trackPoint)
  499. {
  500. float maxDistanceDelta = 10f;
  501.  
  502. Quaternion rotationDelta;
  503. Vector3 positionDelta;
  504.  
  505. float angle;
  506. Vector3 axis;
  507.  
  508. if (grabbedSnapHandle != null)
  509. {
  510. rotationDelta = trackPoint.rotation * Quaternion.Inverse(grabbedSnapHandle.rotation);
  511. positionDelta = trackPoint.position - grabbedSnapHandle.position;
  512. }
  513. else
  514. {
  515. rotationDelta = trackPoint.rotation * Quaternion.Inverse(this.transform.rotation);
  516. positionDelta = trackPoint.position - this.transform.position;
  517. }
  518.  
  519. rotationDelta.ToAngleAxis(out angle, out axis);
  520.  
  521. angle = (angle > 180 ? angle -= 360 : angle);
  522.  
  523. if (angle != 0)
  524. {
  525. Vector3 angularTarget = angle * axis;
  526. rb.angularVelocity = Vector3.MoveTowards(rb.angularVelocity, angularTarget, maxDistanceDelta);
  527. }
  528.  
  529. Vector3 velocityTarget = positionDelta / Time.fixedDeltaTime;
  530. rb.velocity = Vector3.MoveTowards(rb.velocity, velocityTarget, maxDistanceDelta);
  531. }
  532. }
  533. }
  534. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement