这个只是实现了双指缩放,至于单指挪动的,是用unity的SCrollView实现的,只需要单指的时候,打开ScrollView,双指的时候,关闭ScrollView就行,如果不关闭的话,ScrollView的平移会和C#中的逻辑产生冲突。TRACE.TraceLn这个是打印日志的,可以忽略。这个感觉还是可以讨论的,当初在网上搜的时候,也是都没有说的很具体,就只能自己摸索,自己尝试。
namespace rkt.UI
{
public class InputTouchScale : MonoBehaviour
{
public Image mOriginTexture;
public Image mBaseSize;
public ScrollRect m_scrollRect;
public float fRate = 1000f;
private Touch oldTouch1; //上次触摸点1(手指1)
private Touch oldTouch2; //上次触摸点2(手指2)
void Update()
{
//float scaleFactor = 0f;
//#if UNITY_EDITOR || UNITY_STANDALONE_WIN
//scaleFactor = Input.GetAxis("Mouse ScrollWheel");
//if (!m_scrollRect.isActiveAndEnabled)
//{
// m_scrollRect.enabled = true;
//}
//#else
TRACE.TraceLn("双指缩放地图");
//没有触摸
if (Input.touchCount <= 1)
{
if (!m_scrollRect.isActiveAndEnabled)
{
m_scrollRect.enabled = true;
}
TRACE.TraceLn("双指缩放地图,Input.touchCount = " + Input.touchCount);
return;
}
if (Input.touchCount >= 2)
{
if (m_scrollRect.isActiveAndEnabled)
{
m_scrollRect.enabled = false;
}
TRACE.TraceLn("双指缩放地图,Input.touchCount = " + Input.touchCount);
}
else
{
m_scrollRect.enabled = true;
TRACE.TraceLn("双指缩放地图,Input.touchCount = " + Input.touchCount);
}
//多点触摸, 放大缩小
Touch newTouch1 = Input.GetTouch(0);
Touch newTouch2 = Input.GetTouch(1);
//第2点刚开始接触屏幕, 只记录,不做处理
if (newTouch2.phase == TouchPhase.Began)
{
oldTouch2 = newTouch2;
oldTouch1 = newTouch1;
TRACE.TraceLn("双指缩放地图,oldTouch2 = " + oldTouch2 + "oldTouch1 = " + oldTouch1);
return;
}
//计算老的两点距离和新的两点间距离,变大要放大模型,变小要缩放模型
float oldDistance = Vector2.Distance(oldTouch1.position, oldTouch2.position);
float newDistance = Vector2.Distance(newTouch1.position, newTouch2.position);
//两个距离之差,为正表示放大手势, 为负表示缩小手势
float offset = newDistance - oldDistance;
//#endif
//放大因子, 一个像素按 0.01倍来算(1000可调整)
float scaleFactor = offset / fRate;
if (scaleFactor == 0 )
{
m_scrollRect.enabled = true;
}
else
{
m_scrollRect.enabled = false;
}
//获取地图当前的缩放比例
Vector3 localScale = mOriginTexture.rectTransform.localScale;
//获取地图显示区域的左右上下间距
Vector3 localSizeDelta = mBaseSize.rectTransform.sizeDelta;
TRACE.TraceLn("双指缩放地图, 地图显示区域的左右上下间距 localSizeDelta = " + localSizeDelta);
//根据地图显示区域的左右间距,结合分辨率,计算显示区域的实际宽或高
float HWBase;
//获取地图的宽和高
float localMapWidth = mOriginTexture.rectTransform.rect.width;
float localMapHight = mOriginTexture.rectTransform.rect.height;
//计算实际显示区域的宽和高
float localShowAreaWidth = localSizeDelta.x + UIHelper.Instance.contentWidth;
float localShowAreaHight = localSizeDelta.y + UIHelper.Instance.contentHeight;
//显示区域中心点和地图中心点的距离
float RemovHMax = localShowAreaHight - localMapHight * 1.5f;
float RemovWMax = localShowAreaWidth - localMapWidth * 1.5f;
//计算宽和高的最小基准值,从中间取最大的
float BaseOne = localShowAreaWidth / localMapWidth;
float BaseTwo = localShowAreaHight / localMapHight;
//根据实际大小计算缩放的最小比例
float WidthMin = Math.Max(BaseOne, BaseTwo) - localScale.y;
//最大的放大比例
float WidthMan = 1.5f - localScale.x;
//放大:如果大于最大比例,就置为最大比例
// if (offset > 0)
if (scaleFactor >= WidthMan)
{
scaleFactor = WidthMan;
}
//缩小:如果小于最小比例,就置为最小
if (scaleFactor <= WidthMin)
{
scaleFactor = WidthMin;
}
ZoomRemove(localMapWidth, localMapHight, localShowAreaWidth, localShowAreaHight, localScale.x + scaleFactor);
//记住最新的触摸点,下次使用
oldTouch1 = newTouch1;
oldTouch2 = newTouch2;
}
public void ZoomRemove(float localMapWidth, float localMapHight, float localShowAreaWidth, float localShowAreaHight, float scale)
{
float Map_X = mOriginTexture.rectTransform.anchoredPosition.x;
float Map_Y = mOriginTexture.rectTransform.anchoredPosition.y;
bool IsRemove = false;
// 计算当前比例边界的极限值
float Limit_X = (localMapWidth * scale * 0.5f) - localShowAreaWidth * 0.5f;
float Limit_Y = (localMapHight * scale * 0.5f) - localShowAreaHight * 0.5f;
if (Map_X < 0 && Map_Y < 0)
{
Limit_X = Limit_X * -1;
Limit_Y = Limit_Y * -1;
}
else if (Map_X > 0 && Map_Y < 0)
{
Limit_Y = Limit_Y * -1;
}
else if (Map_X < 0 && Map_Y > 0)
{
Limit_X = Limit_X * -1;
}
if (System.Math.Abs(Map_X) > System.Math.Abs(Limit_X))
{
Map_X = Limit_X;
IsRemove = true;
}
if (System.Math.Abs(Map_Y) > System.Math.Abs(Limit_Y))
{
Map_Y = Limit_Y;
IsRemove = true;
}
if (IsRemove)
{
Vector3 PosXY = new Vector3(Map_X, Map_Y, 0);
TRACE.TraceLn("双指缩放地图, scale = " + scale + " PosXY = " + PosXY);
TRACE.TraceLn("双指缩放地图,参数 localMapWidth = " + localMapWidth + "localMapHight = " + localMapHight);
TRACE.TraceLn("双指缩放地图,参数 localShowAreaWidth = " + localShowAreaWidth + "localShowAreaHight = " + localShowAreaHight);
TRACE.TraceLn("双指缩放地图,当前的距离 Map_X = " + Map_X + "Map_Y = " + Map_Y);
TRACE.TraceLn("双指缩放地图,卡边的极限距离 Limit_X = " + Limit_X + "Limit_Y = " + Limit_Y);
TRACE.TraceLn("双指缩放地图,实际的分辨率 UIHelper.Instance.contentWidth = " + UIHelper.Instance.contentWidth + "UIHelper.Instance.contentHeight = " + UIHelper.Instance.contentHeight);
mOriginTexture.rectTransform.anchoredPosition = PosXY;
}
Vector3 Scale = new Vector3(scale, scale, scale);
mOriginTexture.rectTransform.localScale = Scale;
}
}
}