Exemplo n.º 1
0
    void Start()
    {
        // Disable the pointer graphic (until the user holds down on the touchpad)
        Pointer.enabled = false;

        // Ensure we mark the player as not teleporting
        CurrentTeleportState = TeleportStateNick.None;

        // Standard plane mesh used for "fade out" graphic when you teleport
        // This way you don't need to supply a simple plane mesh in the inspector
        PlaneMesh = new Mesh();
        Vector3[] verts = new Vector3[]
        {
            new Vector3(-1, -1, 0),
            new Vector3(-1, 1, 0),
            new Vector3(1, 1, 0),
            new Vector3(1, -1, 0)
        };
        int[] elts = new int[] { 0, 1, 2, 0, 2, 3 };
        PlaneMesh.vertices  = verts;
        PlaneMesh.triangles = elts;
        PlaneMesh.RecalculateBounds();

        if (FadeMaterial != null)
        {
            FadeMaterialInstance = new Material(FadeMaterial);
        }
        // Set some standard variables
        MaterialFadeID    = Shader.PropertyToID("_Fade");
        EnabledAnimatorID = Animator.StringToHash("Enabled");

        RoomBorder = GetComponent <BorderRenderer>();

        Vector3 p0, p1, p2, p3;

        if (GetChaperoneBounds(out p0, out p1, out p2, out p3))
        {
            // Rotate to match camera rig rotation
            var originRotationMatrix = Matrix4x4.TRS(Vector3.zero, OriginTransform.rotation, Vector3.one);

            BorderPointSet p = new BorderPointSet(new Vector3[] {
                originRotationMatrix *p0,
                originRotationMatrix *p1,
                originRotationMatrix *p2,
                originRotationMatrix *p3,
                originRotationMatrix *p0,
            });
            RoomBorder.Points = new BorderPointSet[]
            {
                p
            };
        }

        RoomBorder.enabled = false;
    }
Exemplo n.º 2
0
    void Update()
    {
        // If we are currently teleporting (ie handling the fade in/out transition)...
        if (CurrentTeleportState == TeleportStateNick.Teleporting)
        {
            // Wait until half of the teleport time has passed before the next event (note: both the switch from fade
            // out to fade in and the switch from fade in to stop the animation is half of the fade duration)
            if (Time.time - TeleportTimeMarker >= TeleportFadeDuration / 2)
            {
                if (FadingIn)
                {
                    // We have finished fading in
                    CurrentTeleportState = TeleportStateNick.None;
                }
                else
                {
                    // We have finished fading out - time to teleport!
                    Vector3 offset = OriginTransform.position - HeadTransform.position;
                    offset.y = 0;
                    OriginTransform.position = Pointer.SelectedPoint + offset;
                }

                TeleportTimeMarker = Time.time;
                FadingIn           = !FadingIn;
            }
        }
        // At this point, we are NOT actively teleporting.  So now we care about controller input.
        else if (CurrentTeleportState == TeleportStateNick.Selecting)
        {
            Debug.Assert(ActiveController != null);

            // Here, there is an active controller - that is, the user is holding down on the trackpad.
            // Poll controller for pertinent button data
            int  index          = (int)ActiveController.controller.index;
            var  device         = SteamVR_Controller.Input(index);
            bool shouldTeleport = device.GetPressUp(SteamVR_Controller.ButtonMask.Touchpad);
            bool shouldCancel   = device.GetPressUp(SteamVR_Controller.ButtonMask.Grip);
            if (shouldTeleport || shouldCancel)
            {
                // If the user has decided to teleport (ie lets go of touchpad) then remove all visual indicators
                // related to selecting things and actually teleport
                // If the user has decided to cancel (ie squeezes grip button) then remove visual indicators and do nothing
                if (shouldTeleport && Pointer.PointOnNavMesh)
                {
                    // Begin teleport sequence
                    CurrentTeleportState = TeleportStateNick.Teleporting;
                    TeleportTimeMarker   = Time.time;
                }
                else
                {
                    CurrentTeleportState = TeleportStateNick.None;
                }

                // Reset active controller, disable pointer, disable visual indicators
                ActiveController   = null;
                Pointer.enabled    = false;
                RoomBorder.enabled = false;
                //RoomBorder.Transpose = Matrix4x4.TRS(OriginTransform.position, Quaternion.identity, Vector3.one);
                if (NavmeshAnimator != null)
                {
                    NavmeshAnimator.SetBool(EnabledAnimatorID, false);
                }

                Pointer.transform.parent     = null;
                Pointer.transform.position   = Vector3.zero;
                Pointer.transform.rotation   = Quaternion.identity;
                Pointer.transform.localScale = Vector3.one;
            }
            else
            {
                // The user is still deciding where to teleport and has the touchpad held down.
                // Note: rendering of the parabolic pointer / marker is done in ParabolicPointer
                Vector3 offset = HeadTransform.position - OriginTransform.position;
                offset.y = 0;

                // Render representation of where the chaperone bounds will be after teleporting
                RoomBorder.enabled   = Pointer.PointOnNavMesh;
                RoomBorder.Transpose = Matrix4x4.TRS(Pointer.SelectedPoint - offset, Quaternion.identity, Vector3.one);

                // Haptic feedback click every [HaptickClickAngleStep] degrees
                if (Pointer.CurrentParabolaAngleY >= 45) // Don't click when at max degrees
                {
                    LastClickAngle = Pointer.CurrentPointVector;
                }

                float angleClickDiff = Vector3.Angle(LastClickAngle, Pointer.CurrentPointVector);
                if (IsClicking && Mathf.Abs(angleClickDiff) > HapticClickAngleStep)
                {
                    LastClickAngle = Pointer.CurrentPointVector;
                    if (Pointer.PointOnNavMesh)
                    {
                        device.TriggerHapticPulse();
                    }
                }

                // Trigger a stronger haptic pulse when "entering" a teleportable surface
                if (Pointer.PointOnNavMesh && !IsClicking)
                {
                    IsClicking = true;
                    device.TriggerHapticPulse(750);
                    LastClickAngle = Pointer.CurrentPointVector;
                }
                else if (!Pointer.PointOnNavMesh && IsClicking)
                {
                    IsClicking = false;
                }
            }
        }
        else //CurrentTeleportState == TeleportState.None
        {
            // At this point the user is not holding down on the touchpad at all or has canceled a teleport and hasn't
            // let go of the touchpad.  So we wait for the user to press the touchpad and enable visual indicators
            // if necessary.
            foreach (Valve.VR.InteractionSystem.Hand obj in Controllers)
            {
                if (obj.controller == null)
                {
                    continue;
                }

                int index = (int)obj.controller.index;
                if (index == -1)
                {
                    continue;
                }

                var device = SteamVR_Controller.Input(index);
                if (device.GetPressDown(SteamVR_Controller.ButtonMask.Touchpad))
                {
                    // Set active controller to this controller, and enable the parabolic pointer and visual indicators
                    // that the user can use to determine where they are able to teleport.
                    ActiveController = obj;

                    Pointer.transform.parent        = obj.transform;
                    Pointer.transform.localPosition = Vector3.zero;
                    Pointer.transform.localRotation = Quaternion.identity;
                    Pointer.transform.localScale    = Vector3.one;
                    Pointer.enabled = true;

                    CurrentTeleportState = TeleportStateNick.Selecting;

                    if (NavmeshAnimator != null)
                    {
                        NavmeshAnimator.SetBool(EnabledAnimatorID, true);
                    }

                    Pointer.ForceUpdateCurrentAngle();
                    LastClickAngle = Pointer.CurrentPointVector;
                    IsClicking     = Pointer.PointOnNavMesh;
                }
            }
        }
    }