123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- using UnityEngine;
- namespace SC.XR.Unity.Module_Keyboard
- {
- public class KeyboardFollower : FollowerBase
- {
- [Header("Following Settings")]
- public bool LinearFollowing;//Whether is linear movement.
- public Vector2 border_x; //x-axis boundary
- public Vector2 border_y; //y-axis boundary
- private Transform _slamHead;
- Vector2 initViewPoint;//The midpoint of the camera frame, the coordinates are (0.5f, 0.5f).
- Vector3 viewPoint = Vector3.zero;// Panel coordinates are relative to the coordinates of the camera screen.
- private Vector3 velocity = Vector3.zero;
- bool isFollower = false;
- Vector3 originPos = Vector3.zero;
- Vector3 desPos = Vector3.zero;
- float journeyLength = 0f;
- Vector3 offsetPos;
- Quaternion offsetRotation;
- protected override void OnEnable()
- {
- base.OnEnable();
- }
- private void Start()
- {
- InitTrans();
- }
- protected override void LateUpdate()
- {
- if (StopFollower == false)
- {
- if (IsFollower())
- {
- if (LinearFollowing)
- {
- LinearFollow();
- }
- else
- {
- Follow();
- }
- }
- }
- }
- void InitTrans()
- {
- if (!this.StopFollower && (Camera.main != null))
- {
- _slamHead = Camera.main.transform;
- transform.position = CalculateWindowPosition(Camera.main.transform);
- transform.rotation = CalculateWindowRotation(Camera.main.transform);
- initViewPoint = Camera.main.WorldToViewportPoint(_slamHead.position + (_slamHead.forward * WindowDistance));//The coordinates of the midpoint of the camera screen.
- }
- }
- protected bool IsFollower()
- {
- if ( Camera.main == null)
- {
- return false;
- }
- viewPoint = Camera.main.WorldToViewportPoint(transform.position);// The coordinates of the panel on the camera screen.
- if (viewPoint.x > initViewPoint.x + border_x.x + CalculateWindowOffsetX() || viewPoint.x < initViewPoint.x + border_x.y + CalculateWindowOffsetX() || viewPoint.y < initViewPoint.y + border_y.y + CalculateWindowOffsetY() || viewPoint.y > initViewPoint.y + border_y.x + CalculateWindowOffsetY())// Boundary judgment
- {
- isFollower = true;
- }
- else if (Mathf.Abs(viewPoint.x - initViewPoint.x - CalculateWindowOffsetX()) < 0.05f && Mathf.Abs(viewPoint.y - initViewPoint.y - CalculateWindowOffsetY()) < 0.09f)
- {
- isFollower = false;
- }
- return isFollower;
- }
- //Nonlinear Following by default
- protected override void Follow()
- {
- transform.position = Vector3.Lerp(transform.position, CalculateWindowPosition(Camera.main.transform), WindowFollowSpeed * Time.deltaTime);
- //transform.position = Vector3.SmoothDamp(transform.position, CalculateWindowPosition(Camera.main.transform), ref velocity, WindowFollowSpeed);
- transform.rotation = Quaternion.Slerp(transform.rotation, CalculateWindowRotation(Camera.main.transform), WindowFollowSpeed * Time.deltaTime);
- }
- //For Linear Following, turn down the WindowFollowSpeed to around 0.5 at distance = 1 for best experience
- protected void LinearFollow()
- {
- originPos = transform.position;
- desPos = CalculateWindowPosition(Camera.main.transform);
- journeyLength = Vector3.Distance(originPos, desPos);
- transform.position = Vector3.Lerp(originPos, desPos, (Time.fixedDeltaTime) / journeyLength * WindowFollowSpeed);
- transform.rotation = Quaternion.Slerp(transform.rotation, CalculateWindowRotation(Camera.main.transform), (Time.fixedDeltaTime) / journeyLength * WindowFollowSpeed);
- }
- protected override Vector3 CalculateWindowPosition(Transform cameraTransform)
- {
- Vector3 position = cameraTransform.position + (Vector3.ProjectOnPlane(cameraTransform.forward, Vector3.up).normalized * WindowDistance);
- Vector3 horizontalOffset = cameraTransform.right * windowOffset.x;
- Vector3 verticalOffset = cameraTransform.up * windowOffset.y;
- switch (windowAnchor)
- {
- case TextAnchor.UpperLeft: position += verticalOffset - horizontalOffset; break;
- case TextAnchor.UpperCenter: position += verticalOffset; break;
- case TextAnchor.UpperRight: position += verticalOffset + horizontalOffset; break;
- case TextAnchor.MiddleLeft: position -= horizontalOffset; break;
- case TextAnchor.MiddleRight: position += horizontalOffset; break;
- case TextAnchor.MiddleCenter: position += horizontalOffset + verticalOffset; break;
- case TextAnchor.LowerLeft: position -= verticalOffset + horizontalOffset; break;
- case TextAnchor.LowerCenter: position -= verticalOffset; break;
- case TextAnchor.LowerRight: position -= verticalOffset - horizontalOffset; break;
- }
- return position;
- }
- protected override Quaternion CalculateWindowRotation(Transform cameraTransform)
- {
- Quaternion rotation = Quaternion.Euler(0, cameraTransform.rotation.eulerAngles.y, 0);
- switch (windowAnchor)
- {
- case TextAnchor.UpperLeft: rotation *= windowHorizontalRotationInverse * windowVerticalRotationInverse; break;
- case TextAnchor.UpperCenter: rotation *= windowHorizontalRotationInverse; break;
- case TextAnchor.UpperRight: rotation *= windowHorizontalRotationInverse * windowVerticalRotation; break;
- case TextAnchor.MiddleLeft: rotation *= windowVerticalRotationInverse; break;
- case TextAnchor.MiddleRight: rotation *= windowVerticalRotation; break;
- case TextAnchor.LowerLeft: rotation *= windowHorizontalRotation * windowVerticalRotationInverse; break;
- case TextAnchor.LowerCenter: rotation *= windowHorizontalRotation; break;
- case TextAnchor.LowerRight: rotation *= windowHorizontalRotation * windowVerticalRotation; break;
- }
- return rotation;
- }
-
- }
- }
|