Lusien_Lashans

резерв

Aug 14th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.08 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3.  
  4. /// <summary>
  5. /// Adaptation of the standard MouseOrbit script to use the finger drag gesture to rotate the current object using
  6. /// the fingers/mouse around a target object
  7. /// </summary>
  8. [AddComponentMenu( "FingerGestures/Toolbox/Camera/Orbit" )]
  9. public class TBOrbit : MonoBehaviour
  10. {
  11.     public enum PanMode
  12.     {
  13.         Disabled,
  14.         OneFinger,
  15.         TwoFingers
  16.     }
  17.  
  18.     /// <summary>
  19.     /// The object to orbit around
  20.     /// </summary>
  21.     public Transform target;
  22.  
  23.     /// <summary>
  24.     /// Initial camera distance to target
  25.     /// </summary>
  26.     public float initialDistance = 10.0f;
  27.  
  28.     /// <summary>
  29.     /// Minimum distance between camera and target
  30.     /// </summary>
  31.     public float minDistance = 1.0f;
  32.  
  33.     /// <summary>
  34.     /// Maximum distance between camera and target
  35.     /// </summary>
  36.     public float maxDistance = 30.0f;
  37.  
  38.     /// <summary>
  39.     /// Affects horizontal rotation speed (in degrees per cm)
  40.     /// </summary>
  41.     public float yawSensitivity = 45.0f;
  42.  
  43.     /// <summary>
  44.     /// Affects vertical rotation speed (in degrees per cm)
  45.     /// </summary>
  46.     public float pitchSensitivity = 45.0f;
  47.  
  48.     /// <summary>
  49.     /// Keep yaw angle value between minYaw and maxYaw?
  50.     /// </summary>
  51.     public bool clampYawAngle = false;
  52.     public float minYaw = -75;
  53.     public float maxYaw = 75;
  54.  
  55.     /// <summary>
  56.     /// Keep pitch angle value between minPitch and maxPitch?
  57.     /// </summary>
  58.     public bool clampPitchAngle = true;
  59.     public float minPitch = -20;
  60.     public float maxPitch = 80;
  61.  
  62.     /// <summary>
  63.     /// Allow the user to affect the orbit distance using the pinch zoom gesture
  64.     /// </summary>
  65.     public bool allowPinchZoom = true;
  66.  
  67.     /// <summary>
  68.     /// Affects pinch zoom speed
  69.     /// </summary>
  70.     public float pinchZoomSensitivity = 5.0f;
  71.  
  72.     /// <summary>
  73.     /// Use smooth camera motions?
  74.     /// </summary>
  75.     public bool smoothMotion = true;
  76.     public float smoothZoomSpeed = 5.0f;
  77.     public float smoothOrbitSpeed = 10.0f;
  78.  
  79.     /// <summary>
  80.     /// Two-Finger camera panning.
  81.     /// Panning will apply an offset to the pivot/camera target point
  82.     /// </summary>
  83.     public bool allowPanning = false;
  84.     public bool invertPanningDirections = false;
  85.     public float panningSensitivity = 1.0f;
  86.     public Transform panningPlane;  // reference transform used to apply the panning translation (using panningPlane.right and panningPlane.up vectors)
  87.     public bool smoothPanning = true;
  88.     public float smoothPanningSpeed = 12.0f;
  89.  
  90.     // collision test
  91.     public LayerMask collisionLayerMask;
  92.  
  93.     float distance = 10.0f;
  94.     float yaw = 0;
  95.     float pitch = 0;
  96.  
  97.     float idealDistance = 0;
  98.     float idealYaw = 0;
  99.     float idealPitch = 0;
  100.  
  101.     Vector3 idealPanOffset = Vector3.zero;
  102.     Vector3 panOffset = Vector3.zero;
  103.  
  104.     PinchRecognizer pinchRecognizer;
  105.  
  106.     public float Distance
  107.     {
  108.         get { return distance; }
  109.     }
  110.  
  111.     public float IdealDistance
  112.     {
  113.         get { return idealDistance; }
  114.         set { idealDistance = Mathf.Clamp( value, minDistance, maxDistance ); }
  115.     }
  116.  
  117.     public float Yaw
  118.     {
  119.         get { return yaw; }
  120.     }
  121.  
  122.     public float IdealYaw
  123.     {
  124.         get { return idealYaw; }
  125.         set { idealYaw = clampYawAngle ? ClampAngle( value, minYaw, maxYaw ) : value; }
  126.     }
  127.  
  128.     public float Pitch
  129.     {
  130.         get { return pitch; }
  131.     }
  132.  
  133.     public float IdealPitch
  134.     {
  135.         get { return idealPitch; }
  136.         set { idealPitch = clampPitchAngle ? ClampAngle( value, minPitch, maxPitch ) : value; }
  137.     }
  138.  
  139.     public Vector3 IdealPanOffset
  140.     {
  141.         get { return idealPanOffset; }
  142.         set { idealPanOffset = value; }
  143.     }
  144.  
  145.     public Vector3 PanOffset
  146.     {
  147.         get { return panOffset; }
  148.     }
  149.  
  150.     void InstallGestureRecognizers()
  151.     {
  152.         List<GestureRecognizer> recogniers = new List<GestureRecognizer>( GetComponents<GestureRecognizer>() );
  153.         DragRecognizer drag = recogniers.Find( r => r.EventMessageName == "OnDrag" ) as DragRecognizer;
  154.         DragRecognizer twoFingerDrag = recogniers.Find( r => r.EventMessageName == "OnTwoFingerDrag" ) as DragRecognizer;
  155.         PinchRecognizer pinch = recogniers.Find( r => r.EventMessageName == "OnPinch" ) as PinchRecognizer;
  156.  
  157.         // check if we need to automatically add a screenraycaster
  158.         if( OnlyRotateWhenDragStartsOnObject )
  159.         {
  160.             ScreenRaycaster raycaster = gameObject.GetComponent<ScreenRaycaster>();
  161.  
  162.             if( !raycaster )
  163.                 raycaster = gameObject.AddComponent<ScreenRaycaster>();
  164.         }
  165.  
  166.         if( !drag )
  167.         {
  168.             drag = gameObject.AddComponent<DragRecognizer>();
  169.             drag.RequiredFingerCount = 1;
  170.             drag.IsExclusive = true;
  171.             drag.MaxSimultaneousGestures = 1;
  172.             drag.SendMessageToSelection = GestureRecognizer.SelectionType.None;
  173.         }
  174.  
  175.         if( !pinch )
  176.             pinch = gameObject.AddComponent<PinchRecognizer>();
  177.  
  178.         if( !twoFingerDrag )
  179.         {
  180.             twoFingerDrag = gameObject.AddComponent<DragRecognizer>();
  181.             twoFingerDrag.RequiredFingerCount = 2;
  182.             twoFingerDrag.IsExclusive = true;
  183.             twoFingerDrag.MaxSimultaneousGestures = 1;
  184.             twoFingerDrag.ApplySameDirectionConstraint = true;
  185.             twoFingerDrag.EventMessageName = "OnTwoFingerDrag";
  186.         }
  187.     }
  188.  
  189.     void Start()
  190.     {
  191.         InstallGestureRecognizers();
  192.  
  193.         if( !panningPlane )
  194.             panningPlane = this.transform;
  195.  
  196.         Vector3 angles = transform.eulerAngles;
  197.  
  198.         distance = IdealDistance = initialDistance;
  199.         yaw = IdealYaw = angles.y;
  200.         pitch = IdealPitch = angles.x;
  201.  
  202.         // Make the rigid body not change rotation
  203.         if( GetComponent<Rigidbody>() )
  204.             GetComponent<Rigidbody>().freezeRotation = true;
  205.  
  206.         Apply();
  207.     }
  208.  
  209.     #region Gesture Event Messages
  210.  
  211.     float nextDragTime = 0;
  212.  
  213.     public bool OnlyRotateWhenDragStartsOnObject = false;
  214.  
  215.     void OnDrag( DragGesture gesture )
  216.     {
  217.         // don't rotate unless the drag started on our target object
  218.         if( OnlyRotateWhenDragStartsOnObject )
  219.         {
  220.             if( gesture.Phase == ContinuousGesturePhase.Started )
  221.             {
  222.                 if( !gesture.Recognizer.Raycaster )
  223.                 {
  224.                     Debug.LogWarning( "The drag recognizer on " + gesture.Recognizer.name + " has no ScreenRaycaster component set. This will prevent OnlyRotateWhenDragStartsOnObject flag from working." );
  225.                     OnlyRotateWhenDragStartsOnObject = false;
  226.                     return;
  227.                 }
  228.  
  229.                 if( target && !target.GetComponent<Collider>() )
  230.                 {
  231.                     Debug.LogWarning( "The target object has no collider set. OnlyRotateWhenDragStartsOnObject won't work." );
  232.                     OnlyRotateWhenDragStartsOnObject = false;
  233.                     return;
  234.                 }
  235.             }
  236.  
  237.             if( !target || gesture.StartSelection != target.gameObject )
  238.                 return;
  239.         }
  240.  
  241.         // wait for drag cooldown timer to wear off
  242.         //  used to avoid dragging right after a pinch or pan, when lifting off one finger but the other one is still on screen
  243.         if( Time.time < nextDragTime )
  244.             return;
  245.  
  246.         if( target )
  247.         {
  248.             IdealYaw += gesture.DeltaMove.x.Centimeters() * yawSensitivity;
  249.             IdealPitch -= gesture.DeltaMove.y.Centimeters() * pitchSensitivity;
  250.         }
  251.     }
  252.  
  253.     void OnPinch( PinchGesture gesture )
  254.     {
  255.         if( allowPinchZoom )
  256.         {
  257.             IdealDistance -= gesture.Delta.Centimeters() * pinchZoomSensitivity;
  258.             nextDragTime = Time.time + 0.25f;
  259.         }
  260.     }
  261.  
  262.     void OnTwoFingerDrag( DragGesture gesture )
  263.     {
  264.         if( allowPanning )
  265.         {
  266.             Vector3 move = -panningSensitivity * ( panningPlane.right * gesture.DeltaMove.x.Centimeters() + panningPlane.up * gesture.DeltaMove.y.Centimeters() );
  267.  
  268.             if( invertPanningDirections )
  269.                 IdealPanOffset -= move;
  270.             else
  271.                 IdealPanOffset += move;
  272.  
  273.             nextDragTime = Time.time + 0.25f;
  274.         }
  275.     }
  276.  
  277.     #endregion
  278.  
  279.     void Apply()
  280.     {
  281.         if( smoothMotion )
  282.         {
  283.             distance = Mathf.Lerp( distance, IdealDistance, Time.deltaTime * smoothZoomSpeed );
  284.             yaw = Mathf.Lerp( yaw, IdealYaw, Time.deltaTime * smoothOrbitSpeed );
  285.             pitch = Mathf.LerpAngle( pitch, IdealPitch, Time.deltaTime * smoothOrbitSpeed );
  286.         }
  287.         else
  288.         {
  289.             distance = IdealDistance;
  290.             yaw = IdealYaw;
  291.             pitch = IdealPitch;
  292.         }
  293.  
  294.         if( smoothPanning )
  295.             panOffset = Vector3.Lerp( panOffset, idealPanOffset, Time.deltaTime * smoothPanningSpeed );
  296.         else
  297.             panOffset = idealPanOffset;
  298.  
  299.         transform.rotation = Quaternion.Euler( pitch, yaw, 0 );
  300.  
  301.         Vector3 lookAtPos = ( target.position + panOffset );
  302.         Vector3 desiredPos = lookAtPos - distance * transform.forward;
  303.  
  304.         if( collisionLayerMask != 0 )
  305.         {
  306.             Vector3 dir = desiredPos - lookAtPos; // from target to camera
  307.             float dist = dir.magnitude;
  308.             dir.Normalize();
  309.  
  310.             RaycastHit hit;
  311.             if( Physics.Raycast( lookAtPos, dir, out hit, dist, collisionLayerMask ) )
  312.             {
  313.                 desiredPos = hit.point - dir * 0.1f;
  314.                 distance = hit.distance;
  315.             }
  316.         }
  317.  
  318.         transform.position = desiredPos;
  319.     }
  320.  
  321.     void LateUpdate()
  322.     {
  323.         Apply();
  324.     }
  325.  
  326.     static float ClampAngle( float angle, float min, float max )
  327.     {
  328.         if( angle < -360 )
  329.             angle += 360;
  330.  
  331.         if( angle > 360 )
  332.             angle -= 360;
  333.  
  334.         return Mathf.Clamp( angle, min, max );
  335.     }
  336.  
  337.     // recenter the camera
  338.     public void ResetPanning()
  339.     {
  340.         IdealPanOffset = Vector3.zero;
  341.     }
  342. }
Add Comment
Please, Sign In to add comment