예제 #1
0
    //-------------------------------------------------
    private void ShowPointer(NVRHand newPointerHand, NVRHand 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);
                }
            }

            //NVRReplace//startingFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
            startingFeetOffset = player.transform.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)
        {
            //NVRReplace
            Debug.LogWarning("Skipping ShouldOverrideHoverLock() on Teleportation - 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);

            //NVRReplace
            //if ( pointerHand.currentAttachedObject != null )
            if (pointerHand.CurrentlyInteracting != null)
            {
                //NVRReplace//allowTeleportWhileAttached = pointerHand.currentAttachedObject.GetComponent<AllowTeleportWhileAttachedToHand>();
                allowTeleportWhileAttached = pointerHand.CurrentlyInteracting.GetComponent <AllowTeleportWhileAttachedToHand>();
            }

            //NVRReplace
            //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;
        }
    }
예제 #2
0
    //-------------------------------------------------
    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 playerFeetOffset = player.transform.position - player.feetPositionGuess;

        Vector3 arcVelocity = pointerDir * arcDistance;

        TeleportMarkerBase hitTeleportMarker = null;

        //Check pointer angle
        float dotUp = Vector3.Dot(pointerDir, Vector3.up);
        //NVRReplace//float dotForward = Vector3.Dot( pointerDir, player.hmdTransform.forward );
        float dotForward        = Vector3.Dot(pointerDir, player.Head.transform.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
                VHONTeleportArea teleportArea = pointedAtTeleportMarker as VHONTeleportArea;
                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
            //NVRReplace//float distanceFromPlayer = Vector3.Distance( hitInfo.point, player.hmdTransform.position );
            float distanceFromPlayer         = Vector3.Distance(hitInfo.point, player.Head.transform.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 TeleportDone(TeleportMarkerBase teleportMarkerBase)
 {
     onTeleportedHere.Invoke();
 }
    private void UpdatePointer()
    {
        if (Controller.GetAxis().y - trackPadStart.y > .2)
        {
            teleport = true;
        }
        else
        {
            teleport = false;
        }
        Vector3 pointerStart = trackedObj.transform.position;
        Vector3 pointerEnd;
        Vector3 pointerDir       = trackedObj.transform.forward;
        bool    hitSomething     = false;
        Vector3 playerFeetOffset = playerTrackingOriginTransform.position - feetPositionGuess;

        Vector3 arcVelocity = pointerDir * arcDistance;

        TeleportMarkerBase hitTeleportMarker = null;

        //Check pointer angle
        float dotUp             = Vector3.Dot(pointerDir, Vector3.up);
        float dotForward        = Vector3.Dot(pointerDir, playerHMD.transform.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;
        }

        if (teleport)
        {
            teleportArc.SetColor(pointerTeleportColor);
            teleportPointMaterial.SetColor("_TintColor", pointerTeleportColor);
        }
        else
        {
            teleportArc.SetColor(pointerValidColor);
            teleportPointMaterial.SetColor("_TintColor", pointerValidColor);
        }


        /////////////////////////
        ////////////////////////
        ///////////////
        ////////////
        /////////
        ///////
        /////////////////LOOK AT teleportPointerObject for line color

        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;
        }

        float distanceFromPlayer = Vector3.Distance(hitInfo.point, playerHMD.transform.position);

        if (hitSomething)
        {
            pointerEnd = hitInfo.point;
        }
        else
        {
            pointerEnd = teleportArc.GetArcPositionAtTime(teleportArc.arcDuration);
        }

        invalidReticleTransform.position = pointerEnd;

        //pointerLineRenderer.SetPosition(0, pointerStart);
        // pointerLineRenderer.SetPosition(1, pointerEnd);
    }
예제 #5
0
    public void Teleported(TeleportMarkerBase teleportMarkerBase)
    {
        // This method needs to be called whenever a teleport was completed. For this some changes need to be made to the Steam VR code :-(
        // The changes are described in the Readme file of the Github repo.

        // Debug.LogWarning("Teleported!");

        if (player != null)
        {
            // Assign the appropriate tag for raycasting:

            string tagForRaycast;

            if (teleportingShape == TeleportingShape.ShapeRings)
            {
                tagForRaycast = ringTag;
            }
            else
            {
                tagForRaycast = squareTag;
            }


            // Calculate the POV for line of site origin
            Vector3 PointOfView = player.feetPositionGuess;
            PointOfView.y += player.eyeHeight;


            // Store the player's position
            Vector3 playerPosition = player.trackingOriginTransform.position;

            // Cycle to each of the raycast positions to determine if the teleport point needs to be positioned underneath it
            for (int i = 0; i < raycastPositions.Count; i++)
            {
                Vector3 currentPosition = playerPosition + raycastPositions[i];
                Vector3 down            = Vector3.down;

                // Get the teleportpoint associated with this raycastPosition (by index)
                TeleportPoint teleportPoint = teleportPoints[i];

                RaycastHit hit;

                // Assume the teleportpoint needs to be parked unless all conditions are met (terrain angle low enough, raycast hits an object tagged "Terrain")
                bool parkTeleportSpot = true;

                if (Physics.Raycast(currentPosition, down, out hit, yOffsetRaycast * 4) && hit.transform.tag == tagForRaycast)
                {
                    // Check for fixed Teleportpoints here
                    //
                    // TODO

                    // move a teleportpoint to this position when it hits the terrain / floor

                    if (teleportingShape == TeleportingShape.ShapeRings)
                    {
                        // step 1: check the angle, using code from http://thehiddensignal.com/unity-angle-of-sloped-ground-under-player/

                        Vector3 temp             = Vector3.Cross(hit.normal, Vector3.down);
                        Vector3 groundSlopeDir   = Vector3.Cross(temp, hit.normal);
                        float   groundSlopeAngle = Vector3.Angle(hit.normal, Vector3.up);

                        // step 2: if within maximum allowed angle then place teleport spot
                        if (groundSlopeAngle < maximumTerrainAngle)
                        {
                            // The yOffsetTeleportPoints may be needed, for example if you use Microsplat with tessellation enabled.
                            // Otherwise the teleportpoint may sink too far into the ground.
                            teleportPoint.transform.position = new Vector3(hit.point.x, hit.point.y + yOffsetTeleportPoints, hit.point.z);
                            parkTeleportSpot = false;
                        }
                    }
                    else
                    {
                        // For squares we don't don the angle check.

                        // The yOffsetTeleportPoints may be needed, for example if you use Microsplat with tessellation enabled.
                        // Otherwise the teleportpoint may sink too far into the ground.
                        teleportPoint.transform.position = new Vector3(hit.point.x, hit.point.y + yOffsetTeleportPoints, hit.point.z);
                        parkTeleportSpot = false;
                    }
                }

                if (lineOfSightPlacement && parkTeleportSpot == false)
                {
                    // This is where we check if the teleport point we are going to place hides behind an obstacle. If so the park it instead.
                    RaycastHit hitPOV;

                    // Get a direction from the Player (eyes) to the teleport point to be placed:
                    Vector3 direction = (teleportPoint.transform.position - PointOfView).normalized;

                    // Cast a ray from the Player (eyes) to the teleport point and see if we hit something:
                    if (Physics.Raycast(PointOfView, direction, out hitPOV, distance * 1, 5) && hitPOV.transform.tag != tagForRaycast)
                    {
                        // Looks like we hit something else than Floor or Terrain so park thsi teleport point instead
                        parkTeleportSpot = true;
                    }
                }

                if (checkProximity && parkTeleportSpot == false)
                {
                    // Here we'll check if the teleport point to be placed is near any of the manually placed teleport points.
                    // This can be an expensive operation however we're only doing it on each teleport action. If you want you can optimize it using the examples here:
                    // https://forum.unity.com/threads/different-ways-to-find-distance.285226/

                    // We collected the manually placed teleport points in the Awake function and now we'll check each of them for proximity.
                    // This can also become an expensive operation if a lot of teleport points have been placed in the level manually.
                    foreach (TeleportMarkerBase tmb in teleportMarkers)
                    {
                        float distance = Vector3.Distance(tmb.transform.position, teleportPoint.transform.position);

                        if (distance < proximity)
                        {
                            // Debug.Log("Skipping teleport point due to proximity of "+distance);
                            parkTeleportSpot = true;
                        }
                    }
                }

                if (parkTeleportSpot)
                {
                    // move teleport point [i] to parking spot which defaults to (0,0,0). Move it somewhere else if (0,0,0) is actually used in the scene.
                    teleportPoint.transform.position = parkingSpot;
                }
            }
        }
        else
        {
            Debug.LogError("<b>TeleportPointsTerrain.Teleported():</b> player == null");
        }
    }