TargetLaser.cs 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189
  1. //======= Copyright (c) Valve Corporation, All rights reserved. ===============
  2. //
  3. // Purpose: Handles Target position selection
  4. // Modified:Jingyi
  5. //
  6. //=============================================================================
  7. using UnityEngine;
  8. using UnityEngine.Events;
  9. using System.Collections;
  10. namespace Valve.VR.InteractionSystem
  11. {
  12. //-------------------------------------------------------------------------
  13. public class TargetLaser : MonoBehaviour
  14. {
  15. public SteamVR_Action_Boolean teleportAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("InteractUI");
  16. public bool autoDrive;
  17. public Vector3 targetPosition;
  18. public GameObject TargetFlag;
  19. public GameObject TargetFlagPrefab;
  20. //--------------------------------------------
  21. public LayerMask traceLayerMask;
  22. public LayerMask floorFixupTraceLayerMask;
  23. public float floorFixupMaximumTraceDistance = 1.0f;
  24. public Material areaVisibleMaterial;
  25. public Material areaLockedMaterial;
  26. public Material areaHighlightedMaterial;
  27. public Material pointVisibleMaterial;
  28. public Material pointLockedMaterial;
  29. public Material pointHighlightedMaterial;
  30. public Transform destinationReticleTransform;
  31. public Transform invalidReticleTransform;
  32. public GameObject playAreaPreviewCorner;
  33. public GameObject playAreaPreviewSide;
  34. public Color pointerValidColor;
  35. public Color pointerInvalidColor;
  36. public Color pointerLockedColor;
  37. public bool showPlayAreaMarker = true;
  38. public float teleportFadeTime = 0.1f;
  39. public float meshFadeTime = 0.2f;
  40. public float arcDistance = 10.0f;
  41. [Header( "Effects" )]
  42. public Transform onActivateObjectTransform;
  43. public Transform onDeactivateObjectTransform;
  44. public float activateObjectTime = 1.0f;
  45. public float deactivateObjectTime = 1.0f;
  46. [Header( "Audio Sources" )]
  47. public AudioSource pointerAudioSource;
  48. public AudioSource loopingAudioSource;
  49. public AudioSource headAudioSource;
  50. public AudioSource reticleAudioSource;
  51. [Header( "Sounds" )]
  52. public AudioClip teleportSound;
  53. public AudioClip pointerStartSound;
  54. public AudioClip pointerLoopSound;
  55. public AudioClip pointerStopSound;
  56. public AudioClip goodHighlightSound;
  57. public AudioClip badHighlightSound;
  58. [Header( "Debug" )]
  59. public bool debugFloor = false;
  60. public bool showOffsetReticle = false;
  61. public Transform offsetReticleTransform;
  62. public MeshRenderer floorDebugSphere;
  63. public LineRenderer floorDebugLine;
  64. private LineRenderer pointerLineRenderer;
  65. private GameObject teleportPointerObject;
  66. private Transform pointerStartTransform;
  67. private Hand pointerHand = null;
  68. private Player player = null;
  69. private TeleportArc teleportArc = null;
  70. private bool visible = false;
  71. private TeleportMarkerBase[] teleportMarkers;
  72. private TeleportMarkerBase pointedAtTeleportMarker;
  73. private TeleportMarkerBase teleportingToMarker;
  74. private Vector3 pointedAtPosition;
  75. private Vector3 prevPointedAtPosition;
  76. private bool teleporting = false;
  77. private float currentFadeTime = 0.0f;
  78. private float meshAlphaPercent = 1.0f;
  79. private float pointerShowStartTime = 0.0f;
  80. private float pointerHideStartTime = 0.0f;
  81. private bool meshFading = false;
  82. private float fullTintAlpha;
  83. private float invalidReticleMinScale = 0.2f;
  84. private float invalidReticleMaxScale = 1.0f;
  85. private float invalidReticleMinScaleDistance = 0.4f;
  86. private float invalidReticleMaxScaleDistance = 2.0f;
  87. private Vector3 invalidReticleScale = Vector3.one;
  88. private Quaternion invalidReticleTargetRotation = Quaternion.identity;
  89. private Transform playAreaPreviewTransform;
  90. private Transform[] playAreaPreviewCorners;
  91. private Transform[] playAreaPreviewSides;
  92. private float loopingAudioMaxVolume = 0.0f;
  93. private Coroutine hintCoroutine = null;
  94. private bool originalHoverLockState = false;
  95. private Interactable originalHoveringInteractable = null;
  96. private AllowTeleportWhileAttachedToHand allowTeleportWhileAttached = null;
  97. private Vector3 startingFeetOffset = Vector3.zero;
  98. private bool movedFeetFarEnough = false;
  99. SteamVR_Events.Action chaperoneInfoInitializedAction;
  100. // Events
  101. public static SteamVR_Events.Event< float > ChangeScene = new SteamVR_Events.Event< float >();
  102. public static SteamVR_Events.Action< float > ChangeSceneAction( UnityAction< float > action ) { return new SteamVR_Events.Action< float >( ChangeScene, action ); }
  103. public static SteamVR_Events.Event< TeleportMarkerBase > Player = new SteamVR_Events.Event< TeleportMarkerBase >();
  104. public static SteamVR_Events.Action< TeleportMarkerBase > PlayerAction( UnityAction< TeleportMarkerBase > action ) { return new SteamVR_Events.Action< TeleportMarkerBase >( Player, action ); }
  105. public static SteamVR_Events.Event< TeleportMarkerBase > PlayerPre = new SteamVR_Events.Event< TeleportMarkerBase >();
  106. public static SteamVR_Events.Action< TeleportMarkerBase > PlayerPreAction( UnityAction< TeleportMarkerBase > action ) { return new SteamVR_Events.Action< TeleportMarkerBase >( PlayerPre, action ); }
  107. //-------------------------------------------------
  108. private static TargetLaser _instance;
  109. public static TargetLaser instance
  110. {
  111. get
  112. {
  113. if ( _instance == null )
  114. {
  115. _instance = GameObject.FindObjectOfType<TargetLaser>();
  116. }
  117. return _instance;
  118. }
  119. }
  120. //-------------------------------------------------
  121. void Awake()
  122. {
  123. _instance = this;
  124. chaperoneInfoInitializedAction = ChaperoneInfo.InitializedAction( OnChaperoneInfoInitialized );
  125. pointerLineRenderer = GetComponentInChildren<LineRenderer>();
  126. teleportPointerObject = pointerLineRenderer.gameObject;
  127. #if UNITY_URP
  128. fullTintAlpha = 0.5f;
  129. #else
  130. int tintColorID = Shader.PropertyToID("_TintColor");
  131. fullTintAlpha = pointVisibleMaterial.GetColor(tintColorID).a;
  132. #endif
  133. teleportArc = GetComponent<TeleportArc>();
  134. teleportArc.traceLayerMask = traceLayerMask;
  135. loopingAudioMaxVolume = loopingAudioSource.volume;
  136. playAreaPreviewCorner.SetActive( false );
  137. playAreaPreviewSide.SetActive( false );
  138. float invalidReticleStartingScale = invalidReticleTransform.localScale.x;
  139. invalidReticleMinScale *= invalidReticleStartingScale;
  140. invalidReticleMaxScale *= invalidReticleStartingScale;
  141. }
  142. //-------------------------------------------------
  143. void Start()
  144. {
  145. teleportMarkers = GameObject.FindObjectsOfType<TeleportMarkerBase>();
  146. HidePointer();
  147. player = InteractionSystem.Player.instance;
  148. if ( player == null )
  149. {
  150. Debug.LogError("<b>[SteamVR Interaction]</b> Teleport: No Player instance found in map.", this);
  151. Destroy( this.gameObject );
  152. return;
  153. }
  154. CheckForSpawnPoint();
  155. //Invoke( "ShowTeleportHint", 5.0f );
  156. }
  157. //-------------------------------------------------
  158. void OnEnable()
  159. {
  160. chaperoneInfoInitializedAction.enabled = true;
  161. OnChaperoneInfoInitialized(); // In case it's already initialized
  162. }
  163. //-------------------------------------------------
  164. void OnDisable()
  165. {
  166. chaperoneInfoInitializedAction.enabled = false;
  167. HidePointer();
  168. }
  169. //-------------------------------------------------
  170. private void CheckForSpawnPoint()
  171. {
  172. foreach ( TeleportMarkerBase teleportMarker in teleportMarkers )
  173. {
  174. TeleportPoint teleportPoint = teleportMarker as TeleportPoint;
  175. if ( teleportPoint && teleportPoint.playerSpawnPoint )
  176. {
  177. teleportingToMarker = teleportMarker;
  178. TeleportPlayer();
  179. break;
  180. }
  181. }
  182. }
  183. //-------------------------------------------------
  184. public void HideTeleportPointer()
  185. {
  186. if ( pointerHand != null )
  187. {
  188. HidePointer();
  189. }
  190. }
  191. //-------------------------------------------------
  192. void Update()
  193. {
  194. Hand oldPointerHand = pointerHand;
  195. Hand newPointerHand = null;
  196. foreach ( Hand hand in player.hands )
  197. {
  198. if ( visible )
  199. {
  200. if ( WasTeleportButtonReleased( hand ) )
  201. {
  202. if ( pointerHand == hand ) //This is the pointer hand
  203. {
  204. TryTeleportPlayer();
  205. }
  206. }
  207. }
  208. if ( WasTeleportButtonPressed( hand ) )
  209. {
  210. newPointerHand = hand;
  211. }
  212. }
  213. //If something is attached to the hand that is preventing teleport
  214. if ( allowTeleportWhileAttached && !allowTeleportWhileAttached.teleportAllowed )
  215. {
  216. HidePointer();
  217. }
  218. else
  219. {
  220. if ( !visible && newPointerHand != null )
  221. {
  222. //Begin showing the pointer
  223. ShowPointer( newPointerHand, oldPointerHand );
  224. }
  225. else if ( visible )
  226. {
  227. if ( newPointerHand == null && !IsTeleportButtonDown( pointerHand ) )
  228. {
  229. //Hide the pointer
  230. HidePointer();
  231. }
  232. else if ( newPointerHand != null )
  233. {
  234. //Move the pointer to a new hand
  235. ShowPointer( newPointerHand, oldPointerHand );
  236. }
  237. }
  238. }
  239. if ( visible )
  240. {
  241. UpdatePointer();
  242. if ( meshFading )
  243. {
  244. UpdateTeleportColors();
  245. }
  246. if ( onActivateObjectTransform.gameObject.activeSelf && Time.time - pointerShowStartTime > activateObjectTime )
  247. {
  248. onActivateObjectTransform.gameObject.SetActive( false );
  249. }
  250. }
  251. else
  252. {
  253. if ( onDeactivateObjectTransform.gameObject.activeSelf && Time.time - pointerHideStartTime > deactivateObjectTime )
  254. {
  255. onDeactivateObjectTransform.gameObject.SetActive( false );
  256. }
  257. }
  258. }
  259. //-------------------------------------------------
  260. private void UpdatePointer()
  261. {
  262. Vector3 pointerStart = pointerStartTransform.position;
  263. Vector3 pointerEnd;
  264. Vector3 pointerDir = pointerStartTransform.forward;
  265. bool hitSomething = false;
  266. bool showPlayAreaPreview = false;
  267. Vector3 playerFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
  268. Vector3 arcVelocity = pointerDir * arcDistance;
  269. TeleportMarkerBase hitTeleportMarker = null;
  270. //Check pointer angle
  271. float dotUp = Vector3.Dot( pointerDir, Vector3.up );
  272. float dotForward = Vector3.Dot( pointerDir, player.hmdTransform.forward );
  273. bool pointerAtBadAngle = false;
  274. if ( ( dotForward > 0 && dotUp > 0.75f ) || ( dotForward < 0.0f && dotUp > 0.5f ) )
  275. {
  276. pointerAtBadAngle = true;
  277. }
  278. //Trace to see if the pointer hit anything
  279. RaycastHit hitInfo;
  280. teleportArc.SetArcData( pointerStart, arcVelocity, true, pointerAtBadAngle );
  281. if ( teleportArc.DrawArc( out hitInfo ) )
  282. {
  283. hitSomething = true;
  284. hitTeleportMarker = hitInfo.collider.GetComponentInParent<TeleportMarkerBase>();
  285. }
  286. if ( pointerAtBadAngle )
  287. {
  288. hitTeleportMarker = null;
  289. }
  290. HighlightSelected( hitTeleportMarker );
  291. if ( hitTeleportMarker != null ) //Hit a teleport marker
  292. {
  293. if ( hitTeleportMarker.locked )
  294. {
  295. teleportArc.SetColor( pointerLockedColor );
  296. #if (UNITY_5_4)
  297. pointerLineRenderer.SetColors( pointerLockedColor, pointerLockedColor );
  298. #else
  299. pointerLineRenderer.startColor = pointerLockedColor;
  300. pointerLineRenderer.endColor = pointerLockedColor;
  301. #endif
  302. destinationReticleTransform.gameObject.SetActive( false );
  303. }
  304. else
  305. {
  306. teleportArc.SetColor( pointerValidColor );
  307. #if (UNITY_5_4)
  308. pointerLineRenderer.SetColors( pointerValidColor, pointerValidColor );
  309. #else
  310. pointerLineRenderer.startColor = pointerValidColor;
  311. pointerLineRenderer.endColor = pointerValidColor;
  312. #endif
  313. destinationReticleTransform.gameObject.SetActive( hitTeleportMarker.showReticle );
  314. }
  315. offsetReticleTransform.gameObject.SetActive( true );
  316. invalidReticleTransform.gameObject.SetActive( false );
  317. pointedAtTeleportMarker = hitTeleportMarker;
  318. pointedAtPosition = hitInfo.point;
  319. if ( showPlayAreaMarker )
  320. {
  321. //Show the play area marker if this is a teleport area
  322. TeleportArea teleportArea = pointedAtTeleportMarker as TeleportArea;
  323. if ( teleportArea != null && !teleportArea.locked && playAreaPreviewTransform != null )
  324. {
  325. Vector3 offsetToUse = playerFeetOffset;
  326. //Adjust the actual offset to prevent the play area marker from moving too much
  327. if ( !movedFeetFarEnough )
  328. {
  329. float distanceFromStartingOffset = Vector3.Distance( playerFeetOffset, startingFeetOffset );
  330. if ( distanceFromStartingOffset < 0.1f )
  331. {
  332. offsetToUse = startingFeetOffset;
  333. }
  334. else if ( distanceFromStartingOffset < 0.4f )
  335. {
  336. offsetToUse = Vector3.Lerp( startingFeetOffset, playerFeetOffset, ( distanceFromStartingOffset - 0.1f ) / 0.3f );
  337. }
  338. else
  339. {
  340. movedFeetFarEnough = true;
  341. }
  342. }
  343. playAreaPreviewTransform.position = pointedAtPosition + offsetToUse;
  344. showPlayAreaPreview = true;
  345. }
  346. }
  347. pointerEnd = hitInfo.point;
  348. }
  349. else //Hit neither
  350. {
  351. destinationReticleTransform.gameObject.SetActive( false );
  352. offsetReticleTransform.gameObject.SetActive( false );
  353. teleportArc.SetColor( pointerInvalidColor );
  354. #if (UNITY_5_4)
  355. pointerLineRenderer.SetColors( pointerInvalidColor, pointerInvalidColor );
  356. #else
  357. pointerLineRenderer.startColor = pointerInvalidColor;
  358. pointerLineRenderer.endColor = pointerInvalidColor;
  359. #endif
  360. invalidReticleTransform.gameObject.SetActive( !pointerAtBadAngle );
  361. //Orient the invalid reticle to the normal of the trace hit point
  362. Vector3 normalToUse = hitInfo.normal;
  363. float angle = Vector3.Angle( hitInfo.normal, Vector3.up );
  364. if ( angle < 15.0f )
  365. {
  366. normalToUse = Vector3.up;
  367. }
  368. invalidReticleTargetRotation = Quaternion.FromToRotation( Vector3.up, normalToUse );
  369. invalidReticleTransform.rotation = Quaternion.Slerp( invalidReticleTransform.rotation, invalidReticleTargetRotation, 0.1f );
  370. //Scale the invalid reticle based on the distance from the player
  371. float distanceFromPlayer = Vector3.Distance( hitInfo.point, player.hmdTransform.position );
  372. float invalidReticleCurrentScale = Util.RemapNumberClamped( distanceFromPlayer, invalidReticleMinScaleDistance, invalidReticleMaxScaleDistance, invalidReticleMinScale, invalidReticleMaxScale );
  373. invalidReticleScale.x = invalidReticleCurrentScale;
  374. invalidReticleScale.y = invalidReticleCurrentScale;
  375. invalidReticleScale.z = invalidReticleCurrentScale;
  376. invalidReticleTransform.transform.localScale = invalidReticleScale;
  377. pointedAtTeleportMarker = null;
  378. if ( hitSomething )
  379. {
  380. pointerEnd = hitInfo.point;
  381. }
  382. else
  383. {
  384. pointerEnd = teleportArc.GetArcPositionAtTime( teleportArc.arcDuration );
  385. }
  386. //Debug floor
  387. if ( debugFloor )
  388. {
  389. floorDebugSphere.gameObject.SetActive( false );
  390. floorDebugLine.gameObject.SetActive( false );
  391. }
  392. }
  393. if ( playAreaPreviewTransform != null )
  394. {
  395. playAreaPreviewTransform.gameObject.SetActive( showPlayAreaPreview );
  396. }
  397. if ( !showOffsetReticle )
  398. {
  399. offsetReticleTransform.gameObject.SetActive( false );
  400. }
  401. destinationReticleTransform.position = pointedAtPosition;
  402. invalidReticleTransform.position = pointerEnd;
  403. onActivateObjectTransform.position = pointerEnd;
  404. onDeactivateObjectTransform.position = pointerEnd;
  405. offsetReticleTransform.position = pointerEnd - playerFeetOffset;
  406. reticleAudioSource.transform.position = pointedAtPosition;
  407. pointerLineRenderer.SetPosition( 0, pointerStart );
  408. pointerLineRenderer.SetPosition( 1, pointerEnd );
  409. }
  410. //-------------------------------------------------
  411. void FixedUpdate()
  412. {
  413. if ( !visible )
  414. {
  415. return;
  416. }
  417. if ( debugFloor )
  418. {
  419. //Debug floor
  420. TeleportArea teleportArea = pointedAtTeleportMarker as TeleportArea;
  421. if ( teleportArea != null )
  422. {
  423. if ( floorFixupMaximumTraceDistance > 0.0f )
  424. {
  425. floorDebugSphere.gameObject.SetActive( true );
  426. floorDebugLine.gameObject.SetActive( true );
  427. RaycastHit raycastHit;
  428. Vector3 traceDir = Vector3.down;
  429. traceDir.x = 0.01f;
  430. if ( Physics.Raycast( pointedAtPosition + 0.05f * traceDir, traceDir, out raycastHit, floorFixupMaximumTraceDistance, floorFixupTraceLayerMask ) )
  431. {
  432. floorDebugSphere.transform.position = raycastHit.point;
  433. floorDebugSphere.material.color = Color.green;
  434. #if (UNITY_5_4)
  435. floorDebugLine.SetColors( Color.green, Color.green );
  436. #else
  437. floorDebugLine.startColor = Color.green;
  438. floorDebugLine.endColor = Color.green;
  439. #endif
  440. floorDebugLine.SetPosition( 0, pointedAtPosition );
  441. floorDebugLine.SetPosition( 1, raycastHit.point );
  442. }
  443. else
  444. {
  445. Vector3 rayEnd = pointedAtPosition + ( traceDir * floorFixupMaximumTraceDistance );
  446. floorDebugSphere.transform.position = rayEnd;
  447. floorDebugSphere.material.color = Color.red;
  448. #if (UNITY_5_4)
  449. floorDebugLine.SetColors( Color.red, Color.red );
  450. #else
  451. floorDebugLine.startColor = Color.red;
  452. floorDebugLine.endColor = Color.red;
  453. #endif
  454. floorDebugLine.SetPosition( 0, pointedAtPosition );
  455. floorDebugLine.SetPosition( 1, rayEnd );
  456. }
  457. }
  458. }
  459. }
  460. }
  461. //-------------------------------------------------
  462. private void OnChaperoneInfoInitialized()
  463. {
  464. ChaperoneInfo chaperone = ChaperoneInfo.instance;
  465. if ( chaperone.initialized && chaperone.roomscale )
  466. {
  467. //Set up the render model for the play area bounds
  468. if ( playAreaPreviewTransform == null )
  469. {
  470. playAreaPreviewTransform = new GameObject( "PlayAreaPreviewTransform" ).transform;
  471. playAreaPreviewTransform.parent = transform;
  472. Util.ResetTransform( playAreaPreviewTransform );
  473. playAreaPreviewCorner.SetActive( true );
  474. playAreaPreviewCorners = new Transform[4];
  475. playAreaPreviewCorners[0] = playAreaPreviewCorner.transform;
  476. playAreaPreviewCorners[1] = Instantiate( playAreaPreviewCorners[0] );
  477. playAreaPreviewCorners[2] = Instantiate( playAreaPreviewCorners[0] );
  478. playAreaPreviewCorners[3] = Instantiate( playAreaPreviewCorners[0] );
  479. playAreaPreviewCorners[0].transform.parent = playAreaPreviewTransform;
  480. playAreaPreviewCorners[1].transform.parent = playAreaPreviewTransform;
  481. playAreaPreviewCorners[2].transform.parent = playAreaPreviewTransform;
  482. playAreaPreviewCorners[3].transform.parent = playAreaPreviewTransform;
  483. playAreaPreviewSide.SetActive( true );
  484. playAreaPreviewSides = new Transform[4];
  485. playAreaPreviewSides[0] = playAreaPreviewSide.transform;
  486. playAreaPreviewSides[1] = Instantiate( playAreaPreviewSides[0] );
  487. playAreaPreviewSides[2] = Instantiate( playAreaPreviewSides[0] );
  488. playAreaPreviewSides[3] = Instantiate( playAreaPreviewSides[0] );
  489. playAreaPreviewSides[0].transform.parent = playAreaPreviewTransform;
  490. playAreaPreviewSides[1].transform.parent = playAreaPreviewTransform;
  491. playAreaPreviewSides[2].transform.parent = playAreaPreviewTransform;
  492. playAreaPreviewSides[3].transform.parent = playAreaPreviewTransform;
  493. }
  494. float x = chaperone.playAreaSizeX;
  495. float z = chaperone.playAreaSizeZ;
  496. playAreaPreviewSides[0].localPosition = new Vector3( 0.0f, 0.0f, 0.5f * z - 0.25f );
  497. playAreaPreviewSides[1].localPosition = new Vector3( 0.0f, 0.0f, -0.5f * z + 0.25f );
  498. playAreaPreviewSides[2].localPosition = new Vector3( 0.5f * x - 0.25f, 0.0f, 0.0f );
  499. playAreaPreviewSides[3].localPosition = new Vector3( -0.5f * x + 0.25f, 0.0f, 0.0f );
  500. playAreaPreviewSides[0].localScale = new Vector3( x - 0.5f, 1.0f, 1.0f );
  501. playAreaPreviewSides[1].localScale = new Vector3( x - 0.5f, 1.0f, 1.0f );
  502. playAreaPreviewSides[2].localScale = new Vector3( z - 0.5f, 1.0f, 1.0f );
  503. playAreaPreviewSides[3].localScale = new Vector3( z - 0.5f, 1.0f, 1.0f );
  504. playAreaPreviewSides[0].localRotation = Quaternion.Euler( 0.0f, 0.0f, 0.0f );
  505. playAreaPreviewSides[1].localRotation = Quaternion.Euler( 0.0f, 180.0f, 0.0f );
  506. playAreaPreviewSides[2].localRotation = Quaternion.Euler( 0.0f, 90.0f, 0.0f );
  507. playAreaPreviewSides[3].localRotation = Quaternion.Euler( 0.0f, 270.0f, 0.0f );
  508. playAreaPreviewCorners[0].localPosition = new Vector3( 0.5f * x - 0.25f, 0.0f, 0.5f * z - 0.25f );
  509. playAreaPreviewCorners[1].localPosition = new Vector3( 0.5f * x - 0.25f, 0.0f, -0.5f * z + 0.25f );
  510. playAreaPreviewCorners[2].localPosition = new Vector3( -0.5f * x + 0.25f, 0.0f, -0.5f * z + 0.25f );
  511. playAreaPreviewCorners[3].localPosition = new Vector3( -0.5f * x + 0.25f, 0.0f, 0.5f * z - 0.25f );
  512. playAreaPreviewCorners[0].localRotation = Quaternion.Euler( 0.0f, 0.0f, 0.0f );
  513. playAreaPreviewCorners[1].localRotation = Quaternion.Euler( 0.0f, 90.0f, 0.0f );
  514. playAreaPreviewCorners[2].localRotation = Quaternion.Euler( 0.0f, 180.0f, 0.0f );
  515. playAreaPreviewCorners[3].localRotation = Quaternion.Euler( 0.0f, 270.0f, 0.0f );
  516. playAreaPreviewTransform.gameObject.SetActive( false );
  517. }
  518. }
  519. //-------------------------------------------------
  520. private void HidePointer()
  521. {
  522. if ( visible )
  523. {
  524. pointerHideStartTime = Time.time;
  525. }
  526. visible = false;
  527. if ( pointerHand )
  528. {
  529. if ( ShouldOverrideHoverLock() )
  530. {
  531. //Restore the original hovering interactable on the hand
  532. if ( originalHoverLockState == true )
  533. {
  534. pointerHand.HoverLock( originalHoveringInteractable );
  535. }
  536. else
  537. {
  538. pointerHand.HoverUnlock( null );
  539. }
  540. }
  541. //Stop looping sound
  542. loopingAudioSource.Stop();
  543. PlayAudioClip( pointerAudioSource, pointerStopSound );
  544. }
  545. teleportPointerObject.SetActive( false );
  546. teleportArc.Hide();
  547. foreach ( TeleportMarkerBase teleportMarker in teleportMarkers )
  548. {
  549. if ( teleportMarker != null && teleportMarker.markerActive && teleportMarker.gameObject != null )
  550. {
  551. teleportMarker.gameObject.SetActive( false );
  552. }
  553. }
  554. destinationReticleTransform.gameObject.SetActive( false );
  555. invalidReticleTransform.gameObject.SetActive( false );
  556. offsetReticleTransform.gameObject.SetActive( false );
  557. if ( playAreaPreviewTransform != null )
  558. {
  559. playAreaPreviewTransform.gameObject.SetActive( false );
  560. }
  561. if ( onActivateObjectTransform.gameObject.activeSelf )
  562. {
  563. onActivateObjectTransform.gameObject.SetActive( false );
  564. }
  565. onDeactivateObjectTransform.gameObject.SetActive( true );
  566. pointerHand = null;
  567. }
  568. //-------------------------------------------------
  569. private void ShowPointer( Hand newPointerHand, Hand oldPointerHand )
  570. {
  571. if ( !visible )
  572. {
  573. pointedAtTeleportMarker = null;
  574. pointerShowStartTime = Time.time;
  575. visible = true;
  576. meshFading = true;
  577. teleportPointerObject.SetActive( false );
  578. teleportArc.Show();
  579. foreach ( TeleportMarkerBase teleportMarker in teleportMarkers )
  580. {
  581. if ( teleportMarker.markerActive && teleportMarker.ShouldActivate( player.feetPositionGuess ) )
  582. {
  583. teleportMarker.gameObject.SetActive( true );
  584. teleportMarker.Highlight( false );
  585. }
  586. }
  587. startingFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
  588. movedFeetFarEnough = false;
  589. if ( onDeactivateObjectTransform.gameObject.activeSelf )
  590. {
  591. onDeactivateObjectTransform.gameObject.SetActive( false );
  592. }
  593. onActivateObjectTransform.gameObject.SetActive( true );
  594. loopingAudioSource.clip = pointerLoopSound;
  595. loopingAudioSource.loop = true;
  596. loopingAudioSource.Play();
  597. loopingAudioSource.volume = 0.0f;
  598. }
  599. if ( oldPointerHand )
  600. {
  601. if ( ShouldOverrideHoverLock() )
  602. {
  603. //Restore the original hovering interactable on the hand
  604. if ( originalHoverLockState == true )
  605. {
  606. oldPointerHand.HoverLock( originalHoveringInteractable );
  607. }
  608. else
  609. {
  610. oldPointerHand.HoverUnlock( null );
  611. }
  612. }
  613. }
  614. pointerHand = newPointerHand;
  615. if ( visible && oldPointerHand != pointerHand )
  616. {
  617. PlayAudioClip( pointerAudioSource, pointerStartSound );
  618. }
  619. if ( pointerHand )
  620. {
  621. pointerStartTransform = GetPointerStartTransform( pointerHand );
  622. if ( pointerHand.currentAttachedObject != null )
  623. {
  624. allowTeleportWhileAttached = pointerHand.currentAttachedObject.GetComponent<AllowTeleportWhileAttachedToHand>();
  625. }
  626. //Keep track of any existing hovering interactable on the hand
  627. originalHoverLockState = pointerHand.hoverLocked;
  628. originalHoveringInteractable = pointerHand.hoveringInteractable;
  629. if ( ShouldOverrideHoverLock() )
  630. {
  631. pointerHand.HoverLock( null );
  632. }
  633. pointerAudioSource.transform.SetParent( pointerStartTransform );
  634. pointerAudioSource.transform.localPosition = Vector3.zero;
  635. loopingAudioSource.transform.SetParent( pointerStartTransform );
  636. loopingAudioSource.transform.localPosition = Vector3.zero;
  637. }
  638. }
  639. //-------------------------------------------------
  640. private void UpdateTeleportColors()
  641. {
  642. float deltaTime = Time.time - pointerShowStartTime;
  643. if ( deltaTime > meshFadeTime )
  644. {
  645. meshAlphaPercent = 1.0f;
  646. meshFading = false;
  647. }
  648. else
  649. {
  650. meshAlphaPercent = Mathf.Lerp( 0.0f, 1.0f, deltaTime / meshFadeTime );
  651. }
  652. //Tint color for the teleport points
  653. foreach ( TeleportMarkerBase teleportMarker in teleportMarkers )
  654. {
  655. teleportMarker.SetAlpha( fullTintAlpha * meshAlphaPercent, meshAlphaPercent );
  656. }
  657. }
  658. //-------------------------------------------------
  659. private void PlayAudioClip( AudioSource source, AudioClip clip )
  660. {
  661. source.clip = clip;
  662. source.Play();
  663. }
  664. //-------------------------------------------------
  665. private void PlayPointerHaptic( bool validLocation )
  666. {
  667. if ( pointerHand != null )
  668. {
  669. if ( validLocation )
  670. {
  671. pointerHand.TriggerHapticPulse( 800 );
  672. }
  673. else
  674. {
  675. pointerHand.TriggerHapticPulse( 100 );
  676. }
  677. }
  678. }
  679. //-------------------------------------------------
  680. private void TryTeleportPlayer()
  681. {
  682. if ( visible && !teleporting )
  683. {
  684. if ( pointedAtTeleportMarker != null && pointedAtTeleportMarker.locked == false )
  685. {
  686. //Pointing at an unlocked teleport marker
  687. teleportingToMarker = pointedAtTeleportMarker;
  688. InitiateTeleportFade();
  689. CancelTeleportHint();
  690. }
  691. }
  692. }
  693. //-------------------------------------------------
  694. // Modified
  695. private void InitiateTeleportFade()
  696. {
  697. teleporting = true;
  698. currentFadeTime = teleportFadeTime;
  699. TeleportPoint teleportPoint = teleportingToMarker as TeleportPoint;
  700. if ( teleportPoint != null && teleportPoint.teleportType == TeleportPoint.TeleportPointType.SwitchToNewScene )
  701. {
  702. currentFadeTime *= 3.0f;
  703. Teleport.ChangeScene.Send( currentFadeTime );
  704. }
  705. // SteamVR_Fade.Start( Color.clear, 0 );
  706. // SteamVR_Fade.Start( Color.black, currentFadeTime );
  707. headAudioSource.transform.SetParent( player.hmdTransform );
  708. headAudioSource.transform.localPosition = Vector3.zero;
  709. PlayAudioClip( headAudioSource, teleportSound );
  710. Invoke( "TeleportPlayer", currentFadeTime );
  711. }
  712. //-------------------------------------------------
  713. // Modified
  714. private void TeleportPlayer()
  715. {
  716. teleporting = false;
  717. Teleport.PlayerPre.Send( pointedAtTeleportMarker );
  718. SteamVR_Fade.Start( Color.clear, currentFadeTime );
  719. TeleportPoint teleportPoint = teleportingToMarker as TeleportPoint;
  720. Vector3 teleportPosition = pointedAtPosition;
  721. if ( teleportPoint != null )
  722. {
  723. teleportPosition = teleportPoint.transform.position;
  724. //Teleport to a new scene
  725. if ( teleportPoint.teleportType == TeleportPoint.TeleportPointType.SwitchToNewScene )
  726. {
  727. teleportPoint.TeleportToScene();
  728. return;
  729. }
  730. }
  731. // Find the actual floor position below the navigation mesh
  732. TeleportArea teleportArea = teleportingToMarker as TeleportArea;
  733. if ( teleportArea != null )
  734. {
  735. if ( floorFixupMaximumTraceDistance > 0.0f )
  736. {
  737. RaycastHit raycastHit;
  738. if ( Physics.Raycast( teleportPosition + 0.05f * Vector3.down, Vector3.down, out raycastHit, floorFixupMaximumTraceDistance, floorFixupTraceLayerMask ) )
  739. {
  740. teleportPosition = raycastHit.point;
  741. }
  742. }
  743. }
  744. // if ( teleportingToMarker.ShouldMovePlayer() )
  745. // {
  746. // Vector3 playerFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
  747. // player.trackingOriginTransform.position = teleportPosition + playerFeetOffset;
  748. // if (player.leftHand.currentAttachedObjectInfo.HasValue)
  749. // player.leftHand.ResetAttachedTransform(player.leftHand.currentAttachedObjectInfo.Value);
  750. // if (player.rightHand.currentAttachedObjectInfo.HasValue)
  751. // player.rightHand.ResetAttachedTransform(player.rightHand.currentAttachedObjectInfo.Value);
  752. // }
  753. // else
  754. // {
  755. // teleportingToMarker.TeleportPlayer( pointedAtPosition );
  756. // }
  757. if(InteractionManagement.Instance.Robot_Locked){
  758. InteractionManagement.Instance.SetPlayerText("The Robot is locked",5,false);
  759. }
  760. else{
  761. targetPosition = teleportPosition;
  762. autoDrive = true;
  763. InteractionManagement.Instance.SetPlayerText("Start Auto Driving",5,false);
  764. // crete a target flag
  765. GameObject.Destroy(TargetFlag);
  766. TargetFlag = GameObject.Instantiate(TargetFlagPrefab);
  767. TargetFlag.transform.position = targetPosition;
  768. }
  769. //Teleport.Player.Send( pointedAtTeleportMarker );
  770. }
  771. //-------------------------------------------------
  772. private void HighlightSelected( TeleportMarkerBase hitTeleportMarker )
  773. {
  774. if ( pointedAtTeleportMarker != hitTeleportMarker ) //Pointing at a new teleport marker
  775. {
  776. if ( pointedAtTeleportMarker != null )
  777. {
  778. pointedAtTeleportMarker.Highlight( false );
  779. }
  780. if ( hitTeleportMarker != null )
  781. {
  782. hitTeleportMarker.Highlight( true );
  783. prevPointedAtPosition = pointedAtPosition;
  784. PlayPointerHaptic( !hitTeleportMarker.locked );
  785. PlayAudioClip( reticleAudioSource, goodHighlightSound );
  786. loopingAudioSource.volume = loopingAudioMaxVolume;
  787. }
  788. else if ( pointedAtTeleportMarker != null )
  789. {
  790. PlayAudioClip( reticleAudioSource, badHighlightSound );
  791. loopingAudioSource.volume = 0.0f;
  792. }
  793. }
  794. else if ( hitTeleportMarker != null ) //Pointing at the same teleport marker
  795. {
  796. if ( Vector3.Distance( prevPointedAtPosition, pointedAtPosition ) > 1.0f )
  797. {
  798. prevPointedAtPosition = pointedAtPosition;
  799. PlayPointerHaptic( !hitTeleportMarker.locked );
  800. }
  801. }
  802. }
  803. //-------------------------------------------------
  804. public void ShowTeleportHint()
  805. {
  806. CancelTeleportHint();
  807. hintCoroutine = StartCoroutine( TeleportHintCoroutine() );
  808. }
  809. //-------------------------------------------------
  810. public void CancelTeleportHint()
  811. {
  812. if ( hintCoroutine != null )
  813. {
  814. ControllerButtonHints.HideTextHint(player.leftHand, teleportAction);
  815. ControllerButtonHints.HideTextHint(player.rightHand, teleportAction);
  816. StopCoroutine( hintCoroutine );
  817. hintCoroutine = null;
  818. }
  819. CancelInvoke( "ShowTeleportHint" );
  820. }
  821. //-------------------------------------------------
  822. private IEnumerator TeleportHintCoroutine()
  823. {
  824. float prevBreakTime = Time.time;
  825. float prevHapticPulseTime = Time.time;
  826. while ( true )
  827. {
  828. bool pulsed = false;
  829. //Show the hint on each eligible hand
  830. foreach ( Hand hand in player.hands )
  831. {
  832. bool showHint = IsEligibleForTeleport( hand );
  833. bool isShowingHint = !string.IsNullOrEmpty( ControllerButtonHints.GetActiveHintText( hand, teleportAction) );
  834. if ( showHint )
  835. {
  836. if ( !isShowingHint )
  837. {
  838. ControllerButtonHints.ShowTextHint( hand, teleportAction, "Teleport" );
  839. prevBreakTime = Time.time;
  840. prevHapticPulseTime = Time.time;
  841. }
  842. if ( Time.time > prevHapticPulseTime + 0.05f )
  843. {
  844. //Haptic pulse for a few seconds
  845. pulsed = true;
  846. hand.TriggerHapticPulse( 500 );
  847. }
  848. }
  849. else if ( !showHint && isShowingHint )
  850. {
  851. ControllerButtonHints.HideTextHint( hand, teleportAction);
  852. }
  853. }
  854. if ( Time.time > prevBreakTime + 3.0f )
  855. {
  856. //Take a break for a few seconds
  857. yield return new WaitForSeconds( 3.0f );
  858. prevBreakTime = Time.time;
  859. }
  860. if ( pulsed )
  861. {
  862. prevHapticPulseTime = Time.time;
  863. }
  864. yield return null;
  865. }
  866. }
  867. //-------------------------------------------------
  868. public bool IsEligibleForTeleport( Hand hand )
  869. {
  870. if ( hand == null )
  871. {
  872. return false;
  873. }
  874. if ( !hand.gameObject.activeInHierarchy )
  875. {
  876. return false;
  877. }
  878. if ( hand.hoveringInteractable != null )
  879. {
  880. return false;
  881. }
  882. if ( hand.noSteamVRFallbackCamera == null )
  883. {
  884. if ( hand.isActive == false)
  885. {
  886. return false;
  887. }
  888. //Something is attached to the hand
  889. if ( hand.currentAttachedObject != null )
  890. {
  891. AllowTeleportWhileAttachedToHand allowTeleportWhileAttachedToHand = hand.currentAttachedObject.GetComponent<AllowTeleportWhileAttachedToHand>();
  892. if ( allowTeleportWhileAttachedToHand != null && allowTeleportWhileAttachedToHand.teleportAllowed == true )
  893. {
  894. return true;
  895. }
  896. else
  897. {
  898. return false;
  899. }
  900. }
  901. }
  902. return true;
  903. }
  904. //-------------------------------------------------
  905. private bool ShouldOverrideHoverLock()
  906. {
  907. if ( !allowTeleportWhileAttached || allowTeleportWhileAttached.overrideHoverLock )
  908. {
  909. return true;
  910. }
  911. return false;
  912. }
  913. //-------------------------------------------------
  914. private bool WasTeleportButtonReleased( Hand hand )
  915. {
  916. if ( IsEligibleForTeleport( hand ) )
  917. {
  918. if ( hand.noSteamVRFallbackCamera != null )
  919. {
  920. return Input.GetKeyUp( KeyCode.T );
  921. }
  922. else
  923. {
  924. return teleportAction.GetStateUp(hand.handType);
  925. //return hand.controller.GetPressUp( SteamVR_Controller.ButtonMask.Touchpad );
  926. }
  927. }
  928. return false;
  929. }
  930. //-------------------------------------------------
  931. private bool IsTeleportButtonDown( Hand hand )
  932. {
  933. if ( IsEligibleForTeleport( hand ) )
  934. {
  935. if ( hand.noSteamVRFallbackCamera != null )
  936. {
  937. return Input.GetKey( KeyCode.T );
  938. }
  939. else
  940. {
  941. return teleportAction.GetState(hand.handType);
  942. }
  943. }
  944. return false;
  945. }
  946. //-------------------------------------------------
  947. private bool WasTeleportButtonPressed( Hand hand )
  948. {
  949. if ( IsEligibleForTeleport( hand ) )
  950. {
  951. if ( hand.noSteamVRFallbackCamera != null )
  952. {
  953. return Input.GetKeyDown( KeyCode.T );
  954. }
  955. else
  956. {
  957. return teleportAction.GetStateDown(hand.handType);
  958. //return hand.controller.GetPressDown( SteamVR_Controller.ButtonMask.Touchpad );
  959. }
  960. }
  961. return false;
  962. }
  963. //-------------------------------------------------
  964. private Transform GetPointerStartTransform( Hand hand )
  965. {
  966. if ( hand.noSteamVRFallbackCamera != null )
  967. {
  968. return hand.noSteamVRFallbackCamera.transform;
  969. }
  970. else
  971. {
  972. return hand.transform;
  973. }
  974. }
  975. }
  976. }