12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151 |
- //======= Copyright (c) Valve Corporation, All rights reserved. ===============
- //
- // Purpose: Handles all the teleport logic
- //
- //=============================================================================
- using UnityEngine;
- using UnityEngine.Events;
- using System.Collections;
- namespace Valve.VR.InteractionSystem
- {
- //-------------------------------------------------------------------------
- public class Teleport : MonoBehaviour
- {
- public LayerMask traceLayerMask;
- public LayerMask floorFixupTraceLayerMask;
- public float floorFixupMaximumTraceDistance = 1.0f;
- public Material areaVisibleMaterial;
- public Material areaLockedMaterial;
- public Material areaHighlightedMaterial;
- public Material pointVisibleMaterial;
- public Material pointLockedMaterial;
- public Material pointHighlightedMaterial;
- public Transform destinationReticleTransform;
- public Transform invalidReticleTransform;
- public GameObject playAreaPreviewCorner;
- public GameObject playAreaPreviewSide;
- public Color pointerValidColor;
- public Color pointerInvalidColor;
- public Color pointerLockedColor;
- public bool showPlayAreaMarker = true;
- public float teleportFadeTime = 0.1f;
- public float meshFadeTime = 0.2f;
- public float arcDistance = 10.0f;
- [Header( "Effects" )]
- public Transform onActivateObjectTransform;
- public Transform onDeactivateObjectTransform;
- public float activateObjectTime = 1.0f;
- public float deactivateObjectTime = 1.0f;
- [Header( "Audio Sources" )]
- public AudioSource pointerAudioSource;
- public AudioSource loopingAudioSource;
- public AudioSource headAudioSource;
- public AudioSource reticleAudioSource;
- [Header( "Sounds" )]
- public AudioClip teleportSound;
- public AudioClip pointerStartSound;
- public AudioClip pointerLoopSound;
- public AudioClip pointerStopSound;
- public AudioClip goodHighlightSound;
- public AudioClip badHighlightSound;
- [Header( "Debug" )]
- public bool debugFloor = false;
- public bool showOffsetReticle = false;
- public Transform offsetReticleTransform;
- public MeshRenderer floorDebugSphere;
- public LineRenderer floorDebugLine;
- private LineRenderer pointerLineRenderer;
- private GameObject teleportPointerObject;
- private Transform pointerStartTransform;
- private Hand pointerHand = null;
- private Player player = null;
- private TeleportArc teleportArc = null;
- private bool visible = false;
- private TeleportMarkerBase[] teleportMarkers;
- private TeleportMarkerBase pointedAtTeleportMarker;
- private TeleportMarkerBase teleportingToMarker;
- private Vector3 pointedAtPosition;
- private Vector3 prevPointedAtPosition;
- private bool teleporting = false;
- private float currentFadeTime = 0.0f;
- private float meshAlphaPercent = 1.0f;
- private float pointerShowStartTime = 0.0f;
- private float pointerHideStartTime = 0.0f;
- private bool meshFading = false;
- private float fullTintAlpha;
- private float invalidReticleMinScale = 0.2f;
- private float invalidReticleMaxScale = 1.0f;
- private float invalidReticleMinScaleDistance = 0.4f;
- private float invalidReticleMaxScaleDistance = 2.0f;
- private Vector3 invalidReticleScale = Vector3.one;
- private Quaternion invalidReticleTargetRotation = Quaternion.identity;
- private Transform playAreaPreviewTransform;
- private Transform[] playAreaPreviewCorners;
- private Transform[] playAreaPreviewSides;
- private float loopingAudioMaxVolume = 0.0f;
- private Coroutine hintCoroutine = null;
- private bool originalHoverLockState = false;
- private Interactable originalHoveringInteractable = null;
- private AllowTeleportWhileAttachedToHand allowTeleportWhileAttached = null;
- private Vector3 startingFeetOffset = Vector3.zero;
- private bool movedFeetFarEnough = false;
- SteamVR_Events.Action chaperoneInfoInitializedAction;
- // Events
- public static SteamVR_Events.Event< float > ChangeScene = new SteamVR_Events.Event< float >();
- public static SteamVR_Events.Action< float > ChangeSceneAction( UnityAction< float > action ) { return new SteamVR_Events.Action< float >( ChangeScene, action ); }
- public static SteamVR_Events.Event< TeleportMarkerBase > Player = new SteamVR_Events.Event< TeleportMarkerBase >();
- public static SteamVR_Events.Action< TeleportMarkerBase > PlayerAction( UnityAction< TeleportMarkerBase > action ) { return new SteamVR_Events.Action< TeleportMarkerBase >( Player, action ); }
- public static SteamVR_Events.Event< TeleportMarkerBase > PlayerPre = new SteamVR_Events.Event< TeleportMarkerBase >();
- public static SteamVR_Events.Action< TeleportMarkerBase > PlayerPreAction( UnityAction< TeleportMarkerBase > action ) { return new SteamVR_Events.Action< TeleportMarkerBase >( PlayerPre, action ); }
- //-------------------------------------------------
- private static Teleport _instance;
- public static Teleport instance
- {
- get
- {
- if ( _instance == null )
- {
- _instance = GameObject.FindObjectOfType<Teleport>();
- }
- return _instance;
- }
- }
- //-------------------------------------------------
- void Awake()
- {
- _instance = this;
- chaperoneInfoInitializedAction = ChaperoneInfo.InitializedAction( OnChaperoneInfoInitialized );
- pointerLineRenderer = GetComponentInChildren<LineRenderer>();
- teleportPointerObject = pointerLineRenderer.gameObject;
- int tintColorID = Shader.PropertyToID( "_TintColor" );
- fullTintAlpha = pointVisibleMaterial.GetColor( tintColorID ).a;
- teleportArc = GetComponent<TeleportArc>();
- teleportArc.traceLayerMask = traceLayerMask;
- loopingAudioMaxVolume = loopingAudioSource.volume;
- playAreaPreviewCorner.SetActive( false );
- playAreaPreviewSide.SetActive( false );
- float invalidReticleStartingScale = invalidReticleTransform.localScale.x;
- invalidReticleMinScale *= invalidReticleStartingScale;
- invalidReticleMaxScale *= invalidReticleStartingScale;
- }
- //-------------------------------------------------
- void Start()
- {
- teleportMarkers = GameObject.FindObjectsOfType<TeleportMarkerBase>();
- HidePointer();
- player = InteractionSystem.Player.instance;
- if ( player == null )
- {
- Debug.LogError( "Teleport: No Player instance found in map." );
- Destroy( this.gameObject );
- return;
- }
- CheckForSpawnPoint();
- Invoke( "ShowTeleportHint", 5.0f );
- }
- //-------------------------------------------------
- void OnEnable()
- {
- chaperoneInfoInitializedAction.enabled = true;
- OnChaperoneInfoInitialized(); // In case it's already initialized
- }
- //-------------------------------------------------
- void OnDisable()
- {
- chaperoneInfoInitializedAction.enabled = false;
- HidePointer();
- }
- //-------------------------------------------------
- private void CheckForSpawnPoint()
- {
- foreach ( TeleportMarkerBase teleportMarker in teleportMarkers )
- {
- TeleportPoint teleportPoint = teleportMarker as TeleportPoint;
- if ( teleportPoint && teleportPoint.playerSpawnPoint )
- {
- teleportingToMarker = teleportMarker;
- TeleportPlayer();
- break;
- }
- }
- }
- //-------------------------------------------------
- public void HideTeleportPointer()
- {
- if ( pointerHand != null )
- {
- HidePointer();
- }
- }
- //-------------------------------------------------
- void Update()
- {
- Hand oldPointerHand = pointerHand;
- Hand newPointerHand = null;
- foreach ( Hand hand in player.hands )
- {
- if ( visible )
- {
- if ( WasTeleportButtonReleased( hand ) )
- {
- if ( pointerHand == hand ) //This is the pointer hand
- {
- TryTeleportPlayer();
- }
- }
- }
- if ( WasTeleportButtonPressed( hand ) )
- {
- newPointerHand = hand;
- }
- }
- //If something is attached to the hand that is preventing teleport
- if ( allowTeleportWhileAttached && !allowTeleportWhileAttached.teleportAllowed )
- {
- HidePointer();
- }
- else
- {
- if ( !visible && newPointerHand != null )
- {
- //Begin showing the pointer
- ShowPointer( newPointerHand, oldPointerHand );
- }
- else if ( visible )
- {
- if ( newPointerHand == null && !IsTeleportButtonDown( pointerHand ) )
- {
- //Hide the pointer
- HidePointer();
- }
- else if ( newPointerHand != null )
- {
- //Move the pointer to a new hand
- ShowPointer( newPointerHand, oldPointerHand );
- }
- }
- }
- if ( visible )
- {
- UpdatePointer();
- if ( meshFading )
- {
- UpdateTeleportColors();
- }
- if ( onActivateObjectTransform.gameObject.activeSelf && Time.time - pointerShowStartTime > activateObjectTime )
- {
- onActivateObjectTransform.gameObject.SetActive( false );
- }
- }
- else
- {
- if ( onDeactivateObjectTransform.gameObject.activeSelf && Time.time - pointerHideStartTime > deactivateObjectTime )
- {
- onDeactivateObjectTransform.gameObject.SetActive( false );
- }
- }
- }
- //-------------------------------------------------
- private void UpdatePointer()
- {
- Vector3 pointerStart = pointerStartTransform.position;
- Vector3 pointerEnd;
- Vector3 pointerDir = pointerStartTransform.forward;
- bool hitSomething = false;
- bool showPlayAreaPreview = false;
- Vector3 playerFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
- Vector3 arcVelocity = pointerDir * arcDistance;
- TeleportMarkerBase hitTeleportMarker = null;
- //Check pointer angle
- float dotUp = Vector3.Dot( pointerDir, Vector3.up );
- float dotForward = Vector3.Dot( pointerDir, player.hmdTransform.forward );
- bool pointerAtBadAngle = false;
- if ( ( dotForward > 0 && dotUp > 0.75f ) || ( dotForward < 0.0f && dotUp > 0.5f ) )
- {
- pointerAtBadAngle = true;
- }
- //Trace to see if the pointer hit anything
- RaycastHit hitInfo;
- teleportArc.SetArcData( pointerStart, arcVelocity, true, pointerAtBadAngle );
- if ( teleportArc.DrawArc( out hitInfo ) )
- {
- hitSomething = true;
- hitTeleportMarker = hitInfo.collider.GetComponentInParent<TeleportMarkerBase>();
- }
- if ( pointerAtBadAngle )
- {
- hitTeleportMarker = null;
- }
- HighlightSelected( hitTeleportMarker );
- if ( hitTeleportMarker != null ) //Hit a teleport marker
- {
- if ( hitTeleportMarker.locked )
- {
- teleportArc.SetColor( pointerLockedColor );
- #if (UNITY_5_4)
- pointerLineRenderer.SetColors( pointerLockedColor, pointerLockedColor );
- #else
- pointerLineRenderer.startColor = pointerLockedColor;
- pointerLineRenderer.endColor = pointerLockedColor;
- #endif
- destinationReticleTransform.gameObject.SetActive( false );
- }
- else
- {
- teleportArc.SetColor( pointerValidColor );
- #if (UNITY_5_4)
- pointerLineRenderer.SetColors( pointerValidColor, pointerValidColor );
- #else
- pointerLineRenderer.startColor = pointerValidColor;
- pointerLineRenderer.endColor = pointerValidColor;
- #endif
- destinationReticleTransform.gameObject.SetActive( hitTeleportMarker.showReticle );
- }
- offsetReticleTransform.gameObject.SetActive( true );
- invalidReticleTransform.gameObject.SetActive( false );
- pointedAtTeleportMarker = hitTeleportMarker;
- pointedAtPosition = hitInfo.point;
- if ( showPlayAreaMarker )
- {
- //Show the play area marker if this is a teleport area
- TeleportArea teleportArea = pointedAtTeleportMarker as TeleportArea;
- if ( teleportArea != null && !teleportArea.locked && playAreaPreviewTransform != null )
- {
- Vector3 offsetToUse = playerFeetOffset;
- //Adjust the actual offset to prevent the play area marker from moving too much
- if ( !movedFeetFarEnough )
- {
- float distanceFromStartingOffset = Vector3.Distance( playerFeetOffset, startingFeetOffset );
- if ( distanceFromStartingOffset < 0.1f )
- {
- offsetToUse = startingFeetOffset;
- }
- else if ( distanceFromStartingOffset < 0.4f )
- {
- offsetToUse = Vector3.Lerp( startingFeetOffset, playerFeetOffset, ( distanceFromStartingOffset - 0.1f ) / 0.3f );
- }
- else
- {
- movedFeetFarEnough = true;
- }
- }
- playAreaPreviewTransform.position = pointedAtPosition + offsetToUse;
- showPlayAreaPreview = true;
- }
- }
- pointerEnd = hitInfo.point;
- }
- else //Hit neither
- {
- destinationReticleTransform.gameObject.SetActive( false );
- offsetReticleTransform.gameObject.SetActive( false );
- teleportArc.SetColor( pointerInvalidColor );
- #if (UNITY_5_4)
- pointerLineRenderer.SetColors( pointerInvalidColor, pointerInvalidColor );
- #else
- pointerLineRenderer.startColor = pointerInvalidColor;
- pointerLineRenderer.endColor = pointerInvalidColor;
- #endif
- invalidReticleTransform.gameObject.SetActive( !pointerAtBadAngle );
- //Orient the invalid reticle to the normal of the trace hit point
- Vector3 normalToUse = hitInfo.normal;
- float angle = Vector3.Angle( hitInfo.normal, Vector3.up );
- if ( angle < 15.0f )
- {
- normalToUse = Vector3.up;
- }
- invalidReticleTargetRotation = Quaternion.FromToRotation( Vector3.up, normalToUse );
- invalidReticleTransform.rotation = Quaternion.Slerp( invalidReticleTransform.rotation, invalidReticleTargetRotation, 0.1f );
- //Scale the invalid reticle based on the distance from the player
- float distanceFromPlayer = Vector3.Distance( hitInfo.point, player.hmdTransform.position );
- float invalidReticleCurrentScale = Util.RemapNumberClamped( distanceFromPlayer, invalidReticleMinScaleDistance, invalidReticleMaxScaleDistance, invalidReticleMinScale, invalidReticleMaxScale );
- invalidReticleScale.x = invalidReticleCurrentScale;
- invalidReticleScale.y = invalidReticleCurrentScale;
- invalidReticleScale.z = invalidReticleCurrentScale;
- invalidReticleTransform.transform.localScale = invalidReticleScale;
- pointedAtTeleportMarker = null;
- if ( hitSomething )
- {
- pointerEnd = hitInfo.point;
- }
- else
- {
- pointerEnd = teleportArc.GetArcPositionAtTime( teleportArc.arcDuration );
- }
- //Debug floor
- if ( debugFloor )
- {
- floorDebugSphere.gameObject.SetActive( false );
- floorDebugLine.gameObject.SetActive( false );
- }
- }
- if ( playAreaPreviewTransform != null )
- {
- playAreaPreviewTransform.gameObject.SetActive( showPlayAreaPreview );
- }
- if ( !showOffsetReticle )
- {
- offsetReticleTransform.gameObject.SetActive( false );
- }
- destinationReticleTransform.position = pointedAtPosition;
- invalidReticleTransform.position = pointerEnd;
- onActivateObjectTransform.position = pointerEnd;
- onDeactivateObjectTransform.position = pointerEnd;
- offsetReticleTransform.position = pointerEnd - playerFeetOffset;
- reticleAudioSource.transform.position = pointedAtPosition;
- pointerLineRenderer.SetPosition( 0, pointerStart );
- pointerLineRenderer.SetPosition( 1, pointerEnd );
- }
- //-------------------------------------------------
- void FixedUpdate()
- {
- if ( !visible )
- {
- return;
- }
- if ( debugFloor )
- {
- //Debug floor
- TeleportArea teleportArea = pointedAtTeleportMarker as TeleportArea;
- if ( teleportArea != null )
- {
- if ( floorFixupMaximumTraceDistance > 0.0f )
- {
- floorDebugSphere.gameObject.SetActive( true );
- floorDebugLine.gameObject.SetActive( true );
- RaycastHit raycastHit;
- Vector3 traceDir = Vector3.down;
- traceDir.x = 0.01f;
- if ( Physics.Raycast( pointedAtPosition + 0.05f * traceDir, traceDir, out raycastHit, floorFixupMaximumTraceDistance, floorFixupTraceLayerMask ) )
- {
- floorDebugSphere.transform.position = raycastHit.point;
- floorDebugSphere.material.color = Color.green;
- #if (UNITY_5_4)
- floorDebugLine.SetColors( Color.green, Color.green );
- #else
- floorDebugLine.startColor = Color.green;
- floorDebugLine.endColor = Color.green;
- #endif
- floorDebugLine.SetPosition( 0, pointedAtPosition );
- floorDebugLine.SetPosition( 1, raycastHit.point );
- }
- else
- {
- Vector3 rayEnd = pointedAtPosition + ( traceDir * floorFixupMaximumTraceDistance );
- floorDebugSphere.transform.position = rayEnd;
- floorDebugSphere.material.color = Color.red;
- #if (UNITY_5_4)
- floorDebugLine.SetColors( Color.red, Color.red );
- #else
- floorDebugLine.startColor = Color.red;
- floorDebugLine.endColor = Color.red;
- #endif
- floorDebugLine.SetPosition( 0, pointedAtPosition );
- floorDebugLine.SetPosition( 1, rayEnd );
- }
- }
- }
- }
- }
- //-------------------------------------------------
- private void OnChaperoneInfoInitialized()
- {
- ChaperoneInfo chaperone = ChaperoneInfo.instance;
- if ( chaperone.initialized && chaperone.roomscale )
- {
- //Set up the render model for the play area bounds
- if ( playAreaPreviewTransform == null )
- {
- playAreaPreviewTransform = new GameObject( "PlayAreaPreviewTransform" ).transform;
- playAreaPreviewTransform.parent = transform;
- Util.ResetTransform( playAreaPreviewTransform );
- playAreaPreviewCorner.SetActive( true );
- playAreaPreviewCorners = new Transform[4];
- playAreaPreviewCorners[0] = playAreaPreviewCorner.transform;
- playAreaPreviewCorners[1] = Instantiate( playAreaPreviewCorners[0] );
- playAreaPreviewCorners[2] = Instantiate( playAreaPreviewCorners[0] );
- playAreaPreviewCorners[3] = Instantiate( playAreaPreviewCorners[0] );
- playAreaPreviewCorners[0].transform.parent = playAreaPreviewTransform;
- playAreaPreviewCorners[1].transform.parent = playAreaPreviewTransform;
- playAreaPreviewCorners[2].transform.parent = playAreaPreviewTransform;
- playAreaPreviewCorners[3].transform.parent = playAreaPreviewTransform;
- playAreaPreviewSide.SetActive( true );
- playAreaPreviewSides = new Transform[4];
- playAreaPreviewSides[0] = playAreaPreviewSide.transform;
- playAreaPreviewSides[1] = Instantiate( playAreaPreviewSides[0] );
- playAreaPreviewSides[2] = Instantiate( playAreaPreviewSides[0] );
- playAreaPreviewSides[3] = Instantiate( playAreaPreviewSides[0] );
- playAreaPreviewSides[0].transform.parent = playAreaPreviewTransform;
- playAreaPreviewSides[1].transform.parent = playAreaPreviewTransform;
- playAreaPreviewSides[2].transform.parent = playAreaPreviewTransform;
- playAreaPreviewSides[3].transform.parent = playAreaPreviewTransform;
- }
- float x = chaperone.playAreaSizeX;
- float z = chaperone.playAreaSizeZ;
- playAreaPreviewSides[0].localPosition = new Vector3( 0.0f, 0.0f, 0.5f * z - 0.25f );
- playAreaPreviewSides[1].localPosition = new Vector3( 0.0f, 0.0f, -0.5f * z + 0.25f );
- playAreaPreviewSides[2].localPosition = new Vector3( 0.5f * x - 0.25f, 0.0f, 0.0f );
- playAreaPreviewSides[3].localPosition = new Vector3( -0.5f * x + 0.25f, 0.0f, 0.0f );
- playAreaPreviewSides[0].localScale = new Vector3( x - 0.5f, 1.0f, 1.0f );
- playAreaPreviewSides[1].localScale = new Vector3( x - 0.5f, 1.0f, 1.0f );
- playAreaPreviewSides[2].localScale = new Vector3( z - 0.5f, 1.0f, 1.0f );
- playAreaPreviewSides[3].localScale = new Vector3( z - 0.5f, 1.0f, 1.0f );
- playAreaPreviewSides[0].localRotation = Quaternion.Euler( 0.0f, 0.0f, 0.0f );
- playAreaPreviewSides[1].localRotation = Quaternion.Euler( 0.0f, 180.0f, 0.0f );
- playAreaPreviewSides[2].localRotation = Quaternion.Euler( 0.0f, 90.0f, 0.0f );
- playAreaPreviewSides[3].localRotation = Quaternion.Euler( 0.0f, 270.0f, 0.0f );
- playAreaPreviewCorners[0].localPosition = new Vector3( 0.5f * x - 0.25f, 0.0f, 0.5f * z - 0.25f );
- playAreaPreviewCorners[1].localPosition = new Vector3( 0.5f * x - 0.25f, 0.0f, -0.5f * z + 0.25f );
- playAreaPreviewCorners[2].localPosition = new Vector3( -0.5f * x + 0.25f, 0.0f, -0.5f * z + 0.25f );
- playAreaPreviewCorners[3].localPosition = new Vector3( -0.5f * x + 0.25f, 0.0f, 0.5f * z - 0.25f );
- playAreaPreviewCorners[0].localRotation = Quaternion.Euler( 0.0f, 0.0f, 0.0f );
- playAreaPreviewCorners[1].localRotation = Quaternion.Euler( 0.0f, 90.0f, 0.0f );
- playAreaPreviewCorners[2].localRotation = Quaternion.Euler( 0.0f, 180.0f, 0.0f );
- playAreaPreviewCorners[3].localRotation = Quaternion.Euler( 0.0f, 270.0f, 0.0f );
- playAreaPreviewTransform.gameObject.SetActive( false );
- }
- }
- //-------------------------------------------------
- private void HidePointer()
- {
- if ( visible )
- {
- pointerHideStartTime = Time.time;
- }
- visible = false;
- if ( pointerHand )
- {
- if ( ShouldOverrideHoverLock() )
- {
- //Restore the original hovering interactable on the hand
- if ( originalHoverLockState == true )
- {
- pointerHand.HoverLock( originalHoveringInteractable );
- }
- else
- {
- pointerHand.HoverUnlock( null );
- }
- }
- //Stop looping sound
- loopingAudioSource.Stop();
- PlayAudioClip( pointerAudioSource, pointerStopSound );
- }
- teleportPointerObject.SetActive( false );
- teleportArc.Hide();
- foreach ( TeleportMarkerBase teleportMarker in teleportMarkers )
- {
- if ( teleportMarker != null && teleportMarker.markerActive && teleportMarker.gameObject != null )
- {
- teleportMarker.gameObject.SetActive( false );
- }
- }
- destinationReticleTransform.gameObject.SetActive( false );
- invalidReticleTransform.gameObject.SetActive( false );
- offsetReticleTransform.gameObject.SetActive( false );
- if ( playAreaPreviewTransform != null )
- {
- playAreaPreviewTransform.gameObject.SetActive( false );
- }
- if ( onActivateObjectTransform.gameObject.activeSelf )
- {
- onActivateObjectTransform.gameObject.SetActive( false );
- }
- onDeactivateObjectTransform.gameObject.SetActive( true );
- pointerHand = null;
- }
- //-------------------------------------------------
- private void ShowPointer( Hand newPointerHand, Hand oldPointerHand )
- {
- if ( !visible )
- {
- pointedAtTeleportMarker = null;
- pointerShowStartTime = Time.time;
- visible = true;
- meshFading = true;
- teleportPointerObject.SetActive( false );
- teleportArc.Show();
- foreach ( TeleportMarkerBase teleportMarker in teleportMarkers )
- {
- if ( teleportMarker.markerActive && teleportMarker.ShouldActivate( player.feetPositionGuess ) )
- {
- teleportMarker.gameObject.SetActive( true );
- teleportMarker.Highlight( false );
- }
- }
- startingFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
- movedFeetFarEnough = false;
- if ( onDeactivateObjectTransform.gameObject.activeSelf )
- {
- onDeactivateObjectTransform.gameObject.SetActive( false );
- }
- onActivateObjectTransform.gameObject.SetActive( true );
- loopingAudioSource.clip = pointerLoopSound;
- loopingAudioSource.loop = true;
- loopingAudioSource.Play();
- loopingAudioSource.volume = 0.0f;
- }
- if ( oldPointerHand )
- {
- if ( ShouldOverrideHoverLock() )
- {
- //Restore the original hovering interactable on the hand
- if ( originalHoverLockState == true )
- {
- oldPointerHand.HoverLock( originalHoveringInteractable );
- }
- else
- {
- oldPointerHand.HoverUnlock( null );
- }
- }
- }
- pointerHand = newPointerHand;
- if ( visible && oldPointerHand != pointerHand )
- {
- PlayAudioClip( pointerAudioSource, pointerStartSound );
- }
- if ( pointerHand )
- {
- pointerStartTransform = GetPointerStartTransform( pointerHand );
- if ( pointerHand.currentAttachedObject != null )
- {
- allowTeleportWhileAttached = pointerHand.currentAttachedObject.GetComponent<AllowTeleportWhileAttachedToHand>();
- }
- //Keep track of any existing hovering interactable on the hand
- originalHoverLockState = pointerHand.hoverLocked;
- originalHoveringInteractable = pointerHand.hoveringInteractable;
- if ( ShouldOverrideHoverLock() )
- {
- pointerHand.HoverLock( null );
- }
- pointerAudioSource.transform.SetParent( pointerStartTransform );
- pointerAudioSource.transform.localPosition = Vector3.zero;
- loopingAudioSource.transform.SetParent( pointerStartTransform );
- loopingAudioSource.transform.localPosition = Vector3.zero;
- }
- }
- //-------------------------------------------------
- private void UpdateTeleportColors()
- {
- float deltaTime = Time.time - pointerShowStartTime;
- if ( deltaTime > meshFadeTime )
- {
- meshAlphaPercent = 1.0f;
- meshFading = false;
- }
- else
- {
- meshAlphaPercent = Mathf.Lerp( 0.0f, 1.0f, deltaTime / meshFadeTime );
- }
- //Tint color for the teleport points
- foreach ( TeleportMarkerBase teleportMarker in teleportMarkers )
- {
- teleportMarker.SetAlpha( fullTintAlpha * meshAlphaPercent, meshAlphaPercent );
- }
- }
- //-------------------------------------------------
- private void PlayAudioClip( AudioSource source, AudioClip clip )
- {
- source.clip = clip;
- source.Play();
- }
- //-------------------------------------------------
- private void PlayPointerHaptic( bool validLocation )
- {
- if ( pointerHand.controller != null )
- {
- if ( validLocation )
- {
- pointerHand.controller.TriggerHapticPulse( 800 );
- }
- else
- {
- pointerHand.controller.TriggerHapticPulse( 100 );
- }
- }
- }
- //-------------------------------------------------
- private void TryTeleportPlayer()
- {
- if ( visible && !teleporting )
- {
- if ( pointedAtTeleportMarker != null && pointedAtTeleportMarker.locked == false )
- {
- //Pointing at an unlocked teleport marker
- teleportingToMarker = pointedAtTeleportMarker;
- InitiateTeleportFade();
- CancelTeleportHint();
- }
- }
- }
- //-------------------------------------------------
- private void InitiateTeleportFade()
- {
- teleporting = true;
- currentFadeTime = teleportFadeTime;
- TeleportPoint teleportPoint = teleportingToMarker as TeleportPoint;
- if ( teleportPoint != null && teleportPoint.teleportType == TeleportPoint.TeleportPointType.SwitchToNewScene )
- {
- currentFadeTime *= 3.0f;
- Teleport.ChangeScene.Send( currentFadeTime );
- }
- SteamVR_Fade.Start( Color.clear, 0 );
- SteamVR_Fade.Start( Color.black, currentFadeTime );
- headAudioSource.transform.SetParent( player.hmdTransform );
- headAudioSource.transform.localPosition = Vector3.zero;
- PlayAudioClip( headAudioSource, teleportSound );
- Invoke( "TeleportPlayer", currentFadeTime );
- }
- //-------------------------------------------------
- private void TeleportPlayer()
- {
- teleporting = false;
- Teleport.PlayerPre.Send( pointedAtTeleportMarker );
- SteamVR_Fade.Start( Color.clear, currentFadeTime );
- TeleportPoint teleportPoint = teleportingToMarker as TeleportPoint;
- Vector3 teleportPosition = pointedAtPosition;
- if ( teleportPoint != null )
- {
- teleportPosition = teleportPoint.transform.position;
- //Teleport to a new scene
- if ( teleportPoint.teleportType == TeleportPoint.TeleportPointType.SwitchToNewScene )
- {
- teleportPoint.TeleportToScene();
- return;
- }
- }
- // Find the actual floor position below the navigation mesh
- TeleportArea teleportArea = teleportingToMarker as TeleportArea;
- if ( teleportArea != null )
- {
- if ( floorFixupMaximumTraceDistance > 0.0f )
- {
- RaycastHit raycastHit;
- if ( Physics.Raycast( teleportPosition + 0.05f * Vector3.down, Vector3.down, out raycastHit, floorFixupMaximumTraceDistance, floorFixupTraceLayerMask ) )
- {
- teleportPosition = raycastHit.point;
- }
- }
- }
- if ( teleportingToMarker.ShouldMovePlayer() )
- {
- Vector3 playerFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
- player.trackingOriginTransform.position = teleportPosition + playerFeetOffset;
- }
- else
- {
- teleportingToMarker.TeleportPlayer( pointedAtPosition );
- }
- Teleport.Player.Send( pointedAtTeleportMarker );
- }
- //-------------------------------------------------
- private void HighlightSelected( TeleportMarkerBase hitTeleportMarker )
- {
- if ( pointedAtTeleportMarker != hitTeleportMarker ) //Pointing at a new teleport marker
- {
- if ( pointedAtTeleportMarker != null )
- {
- pointedAtTeleportMarker.Highlight( false );
- }
- if ( hitTeleportMarker != null )
- {
- hitTeleportMarker.Highlight( true );
- prevPointedAtPosition = pointedAtPosition;
- PlayPointerHaptic( !hitTeleportMarker.locked );
- PlayAudioClip( reticleAudioSource, goodHighlightSound );
- loopingAudioSource.volume = loopingAudioMaxVolume;
- }
- else if ( pointedAtTeleportMarker != null )
- {
- PlayAudioClip( reticleAudioSource, badHighlightSound );
- loopingAudioSource.volume = 0.0f;
- }
- }
- else if ( hitTeleportMarker != null ) //Pointing at the same teleport marker
- {
- if ( Vector3.Distance( prevPointedAtPosition, pointedAtPosition ) > 1.0f )
- {
- prevPointedAtPosition = pointedAtPosition;
- PlayPointerHaptic( !hitTeleportMarker.locked );
- }
- }
- }
- //-------------------------------------------------
- public void ShowTeleportHint()
- {
- CancelTeleportHint();
- hintCoroutine = StartCoroutine( TeleportHintCoroutine() );
- }
- //-------------------------------------------------
- public void CancelTeleportHint()
- {
- if ( hintCoroutine != null )
- {
- foreach ( Hand hand in player.hands )
- {
- ControllerButtonHints.HideTextHint( hand, EVRButtonId.k_EButton_SteamVR_Touchpad );
- }
- StopCoroutine( hintCoroutine );
- hintCoroutine = null;
- }
- CancelInvoke( "ShowTeleportHint" );
- }
- //-------------------------------------------------
- private IEnumerator TeleportHintCoroutine()
- {
- float prevBreakTime = Time.time;
- float prevHapticPulseTime = Time.time;
- while ( true )
- {
- bool pulsed = false;
- //Show the hint on each eligible hand
- foreach ( Hand hand in player.hands )
- {
- bool showHint = IsEligibleForTeleport( hand );
- bool isShowingHint = !string.IsNullOrEmpty( ControllerButtonHints.GetActiveHintText( hand, EVRButtonId.k_EButton_SteamVR_Touchpad ) );
- if ( showHint )
- {
- if ( !isShowingHint )
- {
- ControllerButtonHints.ShowTextHint( hand, EVRButtonId.k_EButton_SteamVR_Touchpad, "Teleport" );
- prevBreakTime = Time.time;
- prevHapticPulseTime = Time.time;
- }
- if ( Time.time > prevHapticPulseTime + 0.05f )
- {
- //Haptic pulse for a few seconds
- pulsed = true;
- hand.controller.TriggerHapticPulse( 500 );
- }
- }
- else if ( !showHint && isShowingHint )
- {
- ControllerButtonHints.HideTextHint( hand, EVRButtonId.k_EButton_SteamVR_Touchpad );
- }
- }
- if ( Time.time > prevBreakTime + 3.0f )
- {
- //Take a break for a few seconds
- yield return new WaitForSeconds( 3.0f );
- prevBreakTime = Time.time;
- }
- if ( pulsed )
- {
- prevHapticPulseTime = Time.time;
- }
- yield return null;
- }
- }
- //-------------------------------------------------
- public bool IsEligibleForTeleport( Hand hand )
- {
- if ( hand == null )
- {
- return false;
- }
- if ( !hand.gameObject.activeInHierarchy )
- {
- return false;
- }
- if ( hand.hoveringInteractable != null )
- {
- return false;
- }
- if ( hand.noSteamVRFallbackCamera == null )
- {
- if ( hand.controller == null )
- {
- return false;
- }
- //Something is attached to the hand
- if ( hand.currentAttachedObject != null )
- {
- AllowTeleportWhileAttachedToHand allowTeleportWhileAttachedToHand = hand.currentAttachedObject.GetComponent<AllowTeleportWhileAttachedToHand>();
- if ( allowTeleportWhileAttachedToHand != null && allowTeleportWhileAttachedToHand.teleportAllowed == true )
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- return true;
- }
- //-------------------------------------------------
- private bool ShouldOverrideHoverLock()
- {
- if ( !allowTeleportWhileAttached || allowTeleportWhileAttached.overrideHoverLock )
- {
- return true;
- }
- return false;
- }
- //-------------------------------------------------
- private bool WasTeleportButtonReleased( Hand hand )
- {
- if ( IsEligibleForTeleport( hand ) )
- {
- if ( hand.noSteamVRFallbackCamera != null )
- {
- return Input.GetKeyUp( KeyCode.T );
- }
- else
- {
- return hand.controller.GetPressUp( SteamVR_Controller.ButtonMask.Touchpad );
- }
- }
- return false;
- }
- //-------------------------------------------------
- private bool IsTeleportButtonDown( Hand hand )
- {
- if ( IsEligibleForTeleport( hand ) )
- {
- if ( hand.noSteamVRFallbackCamera != null )
- {
- return Input.GetKey( KeyCode.T );
- }
- else
- {
- return hand.controller.GetPress( SteamVR_Controller.ButtonMask.Touchpad );
- }
- }
- return false;
- }
- //-------------------------------------------------
- private bool WasTeleportButtonPressed( Hand hand )
- {
- if ( IsEligibleForTeleport( hand ) )
- {
- if ( hand.noSteamVRFallbackCamera != null )
- {
- return Input.GetKeyDown( KeyCode.T );
- }
- else
- {
- return hand.controller.GetPressDown( SteamVR_Controller.ButtonMask.Touchpad );
- }
- }
- return false;
- }
- //-------------------------------------------------
- private Transform GetPointerStartTransform( Hand hand )
- {
- if ( hand.noSteamVRFallbackCamera != null )
- {
- return hand.noSteamVRFallbackCamera.transform;
- }
- else
- {
- return pointerHand.GetAttachmentTransform( "Attach_ControllerTip" );
- }
- }
- }
- }
|