限制UI只能在屏幕内移动(放大或缩小屏幕同样适用)

新建一个工程 ,创建Canvas  Render mode 选择 Screen Space-Camera

创建一个为相机扩展的脚本,主要用于获取到相机的边界(左上,左下,右上,右下。4个点)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public static class CameraExtension {

public static Vector3[] GetCameraFovPositionByDistance(this Camera cam, float distance)
{
Vector3[] corners = new Vector3[4];

float halfFOV = (cam.fieldOfView * 0.5f) * Mathf.Deg2Rad;
float aspect = cam.aspect;

float height = distance * Mathf.Tan(halfFOV);
float width = height * aspect;

Transform tx = cam.transform;

// 左上角
corners[0] = tx.position - (tx.right * width);
corners[0] += tx.up * height;
corners[0] += tx.forward * distance;

// 右上角
corners[1] = tx.position + (tx.right * width);
corners[1] += tx.up * height;
corners[1] += tx.forward * distance;

// 左下角
corners[2] = tx.position - (tx.right * width);
corners[2] -= tx.up * height;
corners[2] += tx.forward * distance;

// 右下角
corners[3] = tx.position + (tx.right * width);
corners[3] -= tx.up * height;
corners[3] += tx.forward * distance;

return corners;
}
}

实现双指滑动放大 

using UnityEngine;

public class CameraController : MonoBehaviour {
private Camera camera;
public Camera Camera
{
get
{
if (camera == null)
camera = GameObject.FindGameObjectWithTag("UICamera").GetComponent<Camera>();
return camera;
}
}
private float ZoomSpeed = 500;
private float zoomSpeed
{
get
{
return ZoomSpeed;
}
set
{
ZoomSpeed = value;
}
}
private float max =- 150;
private float Max
{
get
{
return max;
}
}

private float min =- 600;
private float Min
{
get
{
return min;
}
}
private Vector2 lastTouchPos1 = Vector2.zero;
private Vector2 lastTouchPos2 = Vector2.zero;

void Update()
{


#if UNITY_IOS || UNITY_ANDROID||UNITY_EDITOR
if (Input.touchCount > 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
Vector2 v1 = Input.GetTouch(0).position;
Vector2 v2 = Input.GetTouch(1).position;

float distance = GetDistance(v1, v2);
Vector3 forward =Camera.transform.forward*distance*Time.deltaTime*0.05f;

if ((Camera.transform.localPosition + forward).z <= Max &&
(Camera.transform.localPosition + forward).z >= Min)
{
Camera.transform.localPosition += forward;
NotificationCentre.GetInstance().SendMessage(MessageConst.MESSAGE_SETBORDER);
}

lastTouchPos1 = Input.GetTouch(0).position;
lastTouchPos2 = Input.GetTouch(1).position;
}
else
{
lastTouchPos1 = Vector2.zero;
lastTouchPos2 = Vector2.zero;
}
}
}
#endif
private float GetDistance(Vector2 pos1, Vector2 pos2)
{
if (lastTouchPos1 == Vector2.zero && lastTouchPos2 == Vector2.zero)
{
return 0.0f;
}

return (pos2 - pos1).sqrMagnitude - (lastTouchPos2 - lastTouchPos1).sqrMagnitude;
}
}

得到UI的边界,在Canva下创建一个空物体border 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GetBorder : MonoBehaviour
{
public Camera UiCamera;
public static float borderX;
public static float borderY;
// Use this for initialization
void Awake()
{

//当屏幕进行放大或缩小后,UI的边界变化,注册了消息 如果发生变化 对border进行改变   

//NotificationCentre 事件中心是我自己写的 不在本篇中,可以看另一篇 http://www.cnblogs.com/FingerCaster/p/7591305.html

//可以使用事件直接注册的方式实现

NotificationCentre.GetInstance().RegisterMessage(MessageConst.MESSAGE_SETBORDER,SetBorderFunc);
}

void Start ()
{
SetBorderFunc(null);
}

public void SetBorderFunc(params object[] obj)
{
Vector3[] corners =
UiCamera.GetCameraFovPositionByDistance(Vector3.Distance(Vector3.zero, UiCamera.transform.localPosition));
corners[0].z = 0;
GetComponent<RectTransform>().localPosition = corners[0];
borderX = Mathf.Abs(GetComponent<RectTransform>().localPosition.x) ;
borderY = Mathf.Abs(GetComponent<RectTransform>().localPosition.y) ;
}
}

最后实现UI的移动 

public class MoveUI{

//界面移动的向量
private Vector3 vec3;
private Vector3 pos;
public bool PanelIsCanMove = false;
protected bool isCanMove = false;

public void Update()
{

#if UNITY_IOS || UNITY_ANDROID || UNITY_EDITOR
if (Input.touchCount == 1)
{
isCanMove = true;
}
else
{
isCanMove = false;
}
if (isCanMove)
{
if (Input.GetMouseButtonDown(0))
{
vec3 = Input.mousePosition;
pos = GetComponent<RectTransform>().localPosition;
}
if (Input.GetMouseButton(0))
{
Vector3 off = Input.mousePosition - vec3;
bool isUp = off.y > 0;
bool isRight = off.x > 0;
vec3 = Input.mousePosition;
pos = pos + off;
float borderX = Mathf.Abs(GetBorder.borderX - GetComponent<RectTransform>().sizeDelta.x / 2);
Vector3 localVector3 = GetComponent<RectTransform>().localPosition;
float borderY = GetComponent<RectTransform>().sizeDelta.y / 2 - GetBorder.borderY;
if (borderY <= 0)
{
borderY = GetComponent<RectTransform>().sizeDelta.y / 2;
}

if (pos.x > borderX)
{
if (isRight)
{
pos.x = localVector3.x;
}
}
if (pos.x < -borderX)
{
if (!isRight)
{
pos.x = localVector3.x;
}
}
if (pos.y > borderY)
{
if (isUp)
{
pos.y = localVector3.y;
}

}
if (pos.y < -borderY)
{
if (!isUp)
{
pos.y = localVector3.y;
}
}
GetComponent<RectTransform>().localPosition = pos;
}
}
#endif
}
}

}

原文地址:https://www.cnblogs.com/FingerCaster/p/7591298.html