//--------------------------------------------------------
|
// [Author]: 玩个游戏
|
// [ Date ]: Wednesday, September 06, 2017
|
//--------------------------------------------------------
|
using UnityEngine;
|
using System.Collections;
|
using UnityEngine.UI;
|
using System.Collections.Generic;
|
using UnityEngine.EventSystems;
|
using System;
|
|
|
public class BoundedDrag : MonoBehaviour, IEndDragHandler, IBeginDragHandler, IDragHandler
|
{
|
|
[SerializeField]
|
RectTransform m_Target;
|
public RectTransform target {
|
get { return m_Target; }
|
set {
|
m_Target = value;
|
}
|
}
|
|
public RectTransform rectTransform { get { return this.transform as RectTransform; } }
|
|
[SerializeField]
|
ScaleRange m_ScaleRange;
|
public ScaleRange scaleRange {
|
get { return m_ScaleRange; }
|
set { m_ScaleRange = value; }
|
}
|
|
[SerializeField]
|
float m_DefaultScale;
|
public float defaultScale { get { return m_DefaultScale; } }
|
|
[SerializeField]
|
float m_DestScale = 1f;
|
public float destScale {
|
get { return m_DestScale; }
|
set { m_DestScale = Mathf.Clamp(value, scaleRange.min, scaleRange.max); }
|
}
|
|
float refScale = 0f;
|
|
public float currentScale {
|
get {
|
return target.localScale.x;
|
}
|
set {
|
target.localScale = Vector3.one * Mathf.Clamp(value, scaleRange.min, scaleRange.max);
|
}
|
}
|
|
[SerializeField]
|
MoveArea m_MoveArea;
|
public MoveArea moveArea {
|
get { return m_MoveArea; }
|
set { m_MoveArea = value; }
|
}
|
|
[SerializeField]
|
Vector2 m_DestPosition = Vector2.zero;
|
public Vector2 destPosition {
|
get { return m_DestPosition; }
|
set { m_DestPosition = new Vector2(Mathf.Clamp(value.x, moveArea.Left * destScale, moveArea.Right * destScale), Mathf.Clamp(value.y, moveArea.Bottom * destScale, moveArea.Top * destScale)); }
|
}
|
|
Vector3 refPosition = Vector3.zero;
|
|
public Vector2 currentPosition {
|
get { return target.anchoredPosition; }
|
set { target.anchoredPosition = value; }
|
}
|
|
Vector2 startTouchPosition01;
|
Vector2 startGroundPosition;
|
|
Vector2 lastTouchPosition01;
|
Vector2 curTouchPosition01;
|
Vector2 lastTouchPosition02;
|
Vector2 curTouchPosition02;
|
|
[SerializeField]
|
Action m_OnBeginDrag;
|
public Action onBeginDrag {
|
get { return m_OnBeginDrag; }
|
}
|
|
bool m_Actionable = true;
|
public bool actionable {
|
get { return m_Actionable; }
|
set { m_Actionable = value; }
|
}
|
|
private void OnEnable()
|
{
|
destPosition = currentPosition = Vector3.zero;
|
}
|
|
public void OnBeginDrag(PointerEventData eventData)
|
{
|
|
#if UNITY_EDITOR || UNITY_STANDALONE
|
if (Input.GetKey(KeyCode.LeftControl) && eventData.button == PointerEventData.InputButton.Left)
|
{
|
TwoFingerHandleBegin();
|
}
|
else if (eventData.button == PointerEventData.InputButton.Left)
|
{
|
OneFingerHandleBegin(eventData);
|
}
|
#else
|
if (Input.touchCount == 2) {
|
TwoFingerHandleBegin();
|
}
|
if (Input.touchCount == 1) {
|
OneFingerHandleBegin(eventData);
|
}
|
#endif
|
onBeginDrag?.Invoke();
|
}
|
|
public void OnDrag(PointerEventData eventData)
|
{
|
#if UNITY_EDITOR || UNITY_STANDALONE
|
if (Input.GetKey(KeyCode.LeftControl) && eventData.button == PointerEventData.InputButton.Left)
|
{
|
TwoFingerHandle();
|
}
|
else if (eventData.button == PointerEventData.InputButton.Left)
|
{
|
OneFingerHandle(eventData);
|
}
|
#else
|
if (Input.touchCount == 2) {
|
TwoFingerHandle();
|
}
|
if (Input.touchCount == 1) {
|
OneFingerHandle(eventData);
|
}
|
#endif
|
}
|
|
public void OnEndDrag(PointerEventData eventData)
|
{
|
}
|
|
void LateUpdate()
|
{
|
if (!actionable)
|
{
|
return;
|
}
|
|
if (Mathf.Abs(currentScale - destScale) > 0.01f)
|
{
|
float newScale = Mathf.SmoothDamp(currentScale, destScale, ref refScale, 0.15f);
|
currentScale = newScale;
|
}
|
|
if (Vector2.Distance(currentPosition, destPosition) > 0.1f)
|
{
|
Vector2 newPosition = Vector3.SmoothDamp(currentPosition, destPosition, ref refPosition, 0.15f);
|
currentPosition = newPosition;
|
}
|
}
|
|
private void OneFingerHandleBegin(PointerEventData eventData)
|
{
|
startTouchPosition01 = Vector2.zero;
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out startTouchPosition01);
|
startGroundPosition = currentPosition;
|
|
}
|
|
private void OneFingerHandle(PointerEventData eventData)
|
{
|
Vector2 localMouse;
|
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out localMouse))
|
{
|
var pointerDelta = localMouse - startTouchPosition01;
|
destPosition = startGroundPosition + pointerDelta;
|
}
|
}
|
|
private void TwoFingerHandle()
|
{
|
// 方便PC调试逻辑
|
#if UNITY_EDITOR || UNITY_STANDALONE
|
curTouchPosition01 = new Vector2(Screen.width / 2, Screen.height / 2);
|
curTouchPosition02 = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
|
#else
|
Touch touchFirst = Input.touches[0];
|
Touch touchSecond = Input.touches[1];
|
curTouchPosition01 = touchFirst.position;
|
curTouchPosition02 = touchSecond.position;
|
#endif
|
|
float lastLength = Vector2.Distance(lastTouchPosition01, lastTouchPosition02);
|
float curLength = Vector2.Distance(curTouchPosition01, curTouchPosition02);
|
destScale *= curLength / Mathf.Clamp(lastLength, 1, float.MaxValue);
|
|
lastTouchPosition01 = curTouchPosition01;
|
lastTouchPosition02 = curTouchPosition02;
|
}
|
|
private void TwoFingerHandleBegin()
|
{
|
// 方便PC调试逻辑
|
#if UNITY_EDITOR || UNITY_STANDALONE
|
curTouchPosition01 = new Vector2(Screen.width / 2, Screen.height / 2);
|
curTouchPosition02 = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
|
#else
|
Touch touchFirst = Input.touches[0];
|
Touch touchSecond = Input.touches[1];
|
curTouchPosition01 = touchFirst.position;
|
curTouchPosition02 = touchSecond.position;
|
#endif
|
|
lastTouchPosition01 = curTouchPosition01;
|
lastTouchPosition02 = curTouchPosition02;
|
}
|
|
[Serializable]
|
public struct ScaleRange
|
{
|
public float min;
|
public float max;
|
}
|
|
[Serializable]
|
public struct MoveArea
|
{
|
public float Left;
|
public float Right;
|
public float Top;
|
public float Bottom;
|
|
public MoveArea(float _left, float _right, float _top, float _bottom)
|
{
|
this.Left = _left;
|
this.Right = _right;
|
this.Top = _top;
|
this.Bottom = _bottom;
|
}
|
|
}
|
}
|