示例
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
/// <summary>
/// 单指旋转模型,双指缩放模型
/// </summary>
public class UITouchTransform : MonoBehaviour
{
public Transform target;
public RectTransform rectTransform;
public Camera uicamera;
public float rotationSpeed = 1f;
public float minScale = 0.1f;
public float maxScale = 2f;
public float mouseScaleSpeed = 0.0001f;//鼠标操作缩放速度
public float touchScaleSpeed = 0.01f; //触摸缩放速度
public bool rotationX = true; //允许绕X轴旋转
public bool rotationY = true; //允许绕Y轴旋转
public bool allowScale = true; //是否允许缩放
private Vector3 lastPosition;
private float lastDistance = 0;
void Awake()
{
if (target == null)
target = transform;
if (rectTransform == null)
rectTransform = this.GetComponent<RectTransform>();
}
void Update()
{
if (Input.touchSupported) //设备是否支持触摸
{
int touchCount = Input.touchCount;
if (touchCount <= 0)
return;
if (touchCount == 1)
{
TouchRotation();
}
else
{
TouchScale();
}
}
else if (Input.mousePresent) //是否探测到鼠标
{
if (Input.GetKey(KeyCode.LeftControl))
MouseScale();
else
MouseRotation();
}
}
void MouseRotation()
{
if (Input.GetMouseButtonDown(0))
{
lastPosition = Input.mousePosition;
return;
}
if (!Input.GetMouseButton(0))
return;
//判断鼠标是否在允许操作的区域内操作
if (rectTransform != null &&
!RectTransformUtility.RectangleContainsScreenPoint(rectTransform, Input.mousePosition, uicamera))
return;
if (rectTransform == null && IsPointerOverUI())
return;
Vector3 mousePosition = Input.mousePosition;
Vector3 offset = mousePosition - lastPosition;
float t = -offset.x;
offset.x = offset.y;
offset.y = t;
if (!rotationX)
offset.x = 0;
if (!rotationY)
offset.y = 0;
target.Rotate(offset * rotationSpeed, Space.World);
lastPosition = mousePosition;
}
void MouseScale()
{
if (!allowScale)
return;
if (Input.GetMouseButtonDown(0))
{
lastPosition = Input.mousePosition;
return;
}
if (!Input.GetMouseButton(0))
return;
//判断鼠标是否在允许操作的区域内操作
if (rectTransform != null &&
!RectTransformUtility.RectangleContainsScreenPoint(rectTransform, Input.mousePosition, uicamera))
return;
if (rectTransform == null && IsPointerOverUI())
return;
float dir = Input.mousePosition.x - lastPosition.x;
float lastDistance = Vector2.Distance(Input.mousePosition, lastPosition) * dir;
float scale = Mathf.Clamp(target.localScale.x + lastDistance * mouseScaleSpeed, minScale, maxScale);
target.localScale = new Vector3(scale, scale, scale);
lastPosition = Input.mousePosition;
}
void TouchRotation()
{
//判断手指是否在允许操作的区域内操作
if (rectTransform != null &&
!RectTransformUtility.RectangleContainsScreenPoint(rectTransform, Input.touches[0].position, uicamera))
return;
if (rectTransform == null && IsPointerOverUI())
return;
Vector3 firstTouch = Input.touches[0].position;
if (Input.touches[0].phase == TouchPhase.Began)
lastPosition = firstTouch;
Vector3 offset = firstTouch - lastPosition;
float t = -offset.x;
offset.x = offset.y;
offset.y = t;
if (!rotationX)
offset.x = 0;
if (!rotationY)
offset.y = 0;
target.Rotate(offset * rotationSpeed, Space.World);
lastPosition = firstTouch;
}
void TouchScale()
{
if (!allowScale)
return;
//判断手指是否在允许操作的区域内操作
if (rectTransform != null &&
!RectTransformUtility.RectangleContainsScreenPoint(rectTransform, Input.touches[0].position, uicamera) &&
!RectTransformUtility.RectangleContainsScreenPoint(rectTransform, Input.touches[1].position, uicamera))
return;
if (rectTransform == null && IsPointerOverUI())
return;
Vector3 firstTouch = Input.touches[0].position;
Vector3 secondTouch = Input.touches[1].position;
float twoTouchDistance = Vector2.Distance(firstTouch, secondTouch);
if (Input.touches[1].phase == TouchPhase.Began)
lastDistance = twoTouchDistance;
else if (Input.touches[1].phase == TouchPhase.Ended)
//双指变单指的情况,不会触发touches[0]的Began阶段
lastPosition = Input.touches[0].position;
else if (Input.touches[0].phase == TouchPhase.Ended)
//双指变单指的情况,不会触发touches[1]的Began阶段
lastPosition = Input.touches[1].position;
float scale = Mathf.Clamp(target.localScale.x + (twoTouchDistance - lastDistance) * touchScaleSpeed, minScale, maxScale);
target.localScale = new Vector3(scale, scale, scale);
lastDistance = twoTouchDistance;
}
public void SetTarget(Transform target)
{
this.target = target;
}
// 判断点击事件是否发生在UI上
public static bool IsPointerOverUI()
{
bool over = false;
if (Input.GetMouseButtonDown(0) || Input.GetMouseButton(0) || Input.touchCount > 0)
{
#if UNITY_EDITOR || UNITY_STANDALONE_WIN
if (EventSystem.current.IsPointerOverGameObject())
#elif UNITY_IPHONE || UNITY_ANDROID
if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
#else
if (EventSystem.current.IsPointerOverGameObject())
#endif
over = true;
else
over = false;
}
return over;
}
}