示例#1
0
        public void UpdatePositionAndRotation(VR_Controller controller, AimRaycastInfo info)
        {
            if (!marker.activeInHierarchy)
            {
                marker.SetActive(true);
            }

            marker.transform.position = info.hitPoint;
            marker.transform.up       = info.normal;


            Vector2 controllerInput     = controller.Input.GetJoystickInput().normalized;
            Vector3 controllerDirection = new Vector3(controllerInput.x, 0.0f, controllerInput.y);

            //get controller pointing direction in world space
            controllerDirection = controller.transform.TransformDirection(controllerDirection);

            //get marker forward in local space
            Vector3 forward = marker.transform.InverseTransformDirection(marker.transform.forward);

            //find the angle diference betwen the controller pointing direction and marker current forward
            float angle = Vector2.SignedAngle(new Vector2(controllerDirection.x, controllerDirection.z), new Vector2(forward.x, forward.z));

            //rotate marker in local space to match controller pointing direction
            marker.transform.Rotate(Vector3.up, angle, Space.Self);
        }
示例#2
0
        private void PostTeleportUpdate()
        {
            teleportMarker.Hide();
            lastActiveController = null;
            lastRaycastInfo      = null;

            currentTeleportState = TeleporState.WaitingInput;
        }
        private AimRaycastInfo ProcessHitInfo(RaycastHit hitInfo, List <Vector3> validPoints)
        {
            Vector3 start = hitInfo.point + (hitInfo.normal * characterController.radius * characterRadiusOffset) + hitInfo.normal;
            Vector3 end   = start + (hitInfo.normal * characterController.height);

            AimRaycastInfo info = new AimRaycastInfo();

            info.hitPoint    = hitInfo.point;
            info.normal      = hitInfo.normal;
            info.validPoints = validPoints;
            //check if the character can fit in this place
            info.suitableForTeleporting = GetSlopeAngle(info.normal) < slopeLimit && !Physics.CheckCapsule(start, end, characterController.radius * characterRadiusOffset, validLayerMask.value, QueryTriggerInteraction.Ignore);

            return(info);
        }
示例#4
0
        //wait for the player to decide where to teleport
        private void PreTeleportUpdate()
        {
            UpdateActiveController();

            //there is no active controller try to do a teleport
            if (activeController == null)
            {
                //if we can teleport to the last AimRaycast
                if (IsAimRaycastInfoSuitableForTeleporting(lastRaycastInfo))
                {
                    DoTeleport(lastRaycastInfo);
                }

                //clean the line inmediatly
                teleportLineRender.CleanRender();

                //go to post teleport
                currentTeleportState = TeleporState.PostTeleport;
                return;
            }

            Ray controllerRay = new Ray(activeController.transform.position, activeController.transform.forward);

            //use the aimhandler to generate all the line points
            List <Vector3> points = aimHandler.GetAllPoints(controllerRay);
            //use the raycaster
            AimRaycastInfo info = aimRaycaster.Raycast(points, activeController.transform);

            if (info != null)
            {
                teleportLineRender.Render(info.validPoints, info.suitableForTeleporting);
            }
            else
            {
                teleportLineRender.Render(points, false);
            }

            if (IsAimRaycastInfoSuitableForTeleporting(info))
            {
                teleportMarker.UpdatePositionAndRotation(activeController, info);
            }
            else
            {
                teleportMarker.Hide();
            }

            lastRaycastInfo = info;
        }
        public virtual AimRaycastInfo Raycast(List <Vector3> points, Transform rayController)
        {
            //get rayController angle
            Vector3 rayControllerForward = rayController.forward;
            Vector3 unalteredForward     = new Vector3(rayController.forward.x, 0.0f, rayController.forward.z).normalized;
            float   angle = Vector3.Angle(rayController.forward, unalteredForward);

            //check if we are on a valid angle
            if (angle > validAngle)
            {
                AimRaycastInfo info = new AimRaycastInfo();
                info.hitPoint = Vector3.zero;
                info.normal   = Vector3.zero;
                //clamp ray to a distance
                info.validPoints            = ClampToDistance(points, invalidRayDistance);
                info.suitableForTeleporting = false;

                return(info);
            }

            //the points are valid?
            if (points.Count <= 1)
            {
                return(null);
            }

            RaycastHit hitInfo;

            if (points.Count == 2)
            {
                if (Physics.Linecast(points[0], points[1], out hitInfo, validLayerMask.value, QueryTriggerInteraction.Ignore))
                {
                    return(ProcessHitInfo(hitInfo, new List <Vector3> {
                        points[0], hitInfo.point
                    }));
                }

                return(null);
            }


            List <Vector3> validPoints = new List <Vector3>();

            int subdivision  = Mathf.CeilToInt(points.Count / collisionAccuracy);
            int currentIndex = 0;
            int nextIndex    = subdivision;

            for (int n = 0; n < subdivision; n++)
            {
                //check for collision in this segment
                if (Physics.Linecast(points[currentIndex], points[nextIndex], validLayerMask.value, QueryTriggerInteraction.Ignore))
                {
                    //found a collision in this segment
                    //find collision in all points inside this segment
                    for (int j = currentIndex; j < nextIndex; j++)
                    {
                        validPoints.Add(points[j]);

                        if (Physics.Linecast(points[j], points[j + 1], out hitInfo, validLayerMask.value, QueryTriggerInteraction.Ignore))
                        {
                            validPoints.Add(hitInfo.point);
                            return(ProcessHitInfo(hitInfo, validPoints));
                        }
                    }
                }
                else
                {
                    //this segment dont has a collision, addall as valid points
                    for (int j = currentIndex; j <= nextIndex; j++)
                    {
                        validPoints.Add(points[j]);
                    }
                }

                //move to the next subdivision if we have one
                currentIndex += subdivision;
                nextIndex    += subdivision;

                //we found the end
                if (currentIndex >= points.Count)
                {
                    return(null);
                }
                if (nextIndex >= points.Count)
                {
                    nextIndex = points.Count - 1;
                }
            }

            return(null);
        }
示例#6
0
 private void DoTeleport(AimRaycastInfo info)
 {
     isTeleporting = true;
     teleportHandler.DoTeleport(characterController, teleportMarker.Marker.transform, delegate { isTeleporting = false; });
 }
示例#7
0
 private bool IsAimRaycastInfoSuitableForTeleporting(AimRaycastInfo info)
 {
     return(info != null && info.suitableForTeleporting);
 }