参考于:https://blog.csdn.net/cactus12138/article/details/78269700
根据原博主进行了少量修改,在2D游戏中摄像机的投影为正交,缩放时改变的是剪裁大小,而3D游戏采用的是透视方式,缩放改变的是摄像机在自己Y轴方向上的位移。
1. 2D游戏操控方式
public class GestureController : MonoBehaviour
{
//摄像机当前缩放
public float distance = 4f;
//缩放系数
public float scaleFactor = 0.1f;
//最大最小缩放范围
public float maxDistance = 6f;
public float minDistance = 2f;
//记录上一次手机触摸位置判断用户是在左放大还是缩小手势
private Vector2 oldPosition1;
private Vector2 oldPosition2;
private Vector2 lastSingleTouchPosition;
//位移后摄像机的位置
private Vector3 m_CameraOffset;
//主摄像机
private Camera m_Camera;
//鼠标和手指操作切换
public bool useMouse = false;
//摄像机缩放为中间值时摄像机可以活动的范围
public float xMin = 7f;
public float xMax = 14f;
public float yMin = 4f;
public float yMax = 11f;
//这个变量用来记录单指双指的变换
private bool m_IsSingleFinger;
//初始化游戏信息设置
public void Start()
{
if (Application.platform == RuntimePlatform.Android)
{
useMouse = false;
}
m_Camera = Camera.main;
m_CameraOffset = m_Camera.transform.position;
}
public void Update()
{
//判断触摸数量为单点触摸
if (Input.touchCount == 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Began || !m_IsSingleFinger)
{
//在开始触摸或者从两字手指放开回来的时候记录一下触摸的位置
lastSingleTouchPosition = Input.GetTouch(0).position;
}
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
MoveCamera(Input.GetTouch(0).position);
}
m_IsSingleFinger = true;
}
else if (Input.touchCount > 1)
{
//当从单指触摸进入多指触摸的时候,记录一下触摸的位置
//保证计算缩放都是从两指手指触碰开始的
if (m_IsSingleFinger)
{
oldPosition1 = Input.GetTouch(0).position;
oldPosition2 = Input.GetTouch(1).position;
}
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
ScaleCamera();
}
m_IsSingleFinger = false;
}
//用鼠标的
if (useMouse)
{
distance -= Input.GetAxis("Mouse ScrollWheel");
distance = Mathf.Clamp(distance, minDistance, maxDistance);
if (Input.GetMouseButtonDown(0))
{
lastSingleTouchPosition = Input.mousePosition;
Debug.Log("GetMouseButtonDown:" + lastSingleTouchPosition);
}
if (Input.GetMouseButton(0))
{
MoveCamera(Input.mousePosition);
}
}
LateUpdate();
}
///
/// 触摸缩放摄像头
///
private void ScaleCamera()
{
//计算出当前两点触摸点的位置
var tempPosition1 = Input.GetTouch(0).position;
var tempPosition2 = Input.GetTouch(1).position;
float currentTouchDistance = Vector3.Distance(tempPosition1, tempPosition2);
float lastTouchDistance = Vector3.Distance(oldPosition1, oldPosition2);
//计算上次和这次双指触摸之间的距离差距
//然后去更改摄像机的距离
distance -= (currentTouchDistance - lastTouchDistance) * scaleFactor * Time.deltaTime;
//把距离限制住在min和max之间
distance = Mathf.Clamp(distance, minDistance, maxDistance);
//重新位移摄像机位置防止超出边界
MoveCamera(lastSingleTouchPosition);
//备份上一次触摸点的位置,用于对比
oldPosition1 = tempPosition1;
oldPosition2 = tempPosition2;
}
//Update方法一旦调用结束以后进入这里算出重置摄像机的位置
private void LateUpdate()
{
m_Camera.transform.position = m_CameraOffset;
m_Camera.orthographicSize = distance;
}
//移动摄像机
private void MoveCamera(Vector3 scenePos)
{
Vector3 lastTouchPostion = m_Camera.ScreenToWorldPoint(new Vector3(lastSingleTouchPosition.x, lastSingleTouchPosition.y, -1));
Vector3 currentTouchPosition = m_Camera.ScreenToWorldPoint(new Vector3(scenePos.x, scenePos.y, -1));
Vector3 v = currentTouchPosition - lastTouchPostion;
m_CameraOffset -= v;
//这两个值为基于摄像机缩放最大值和最小值增长的幅度,自行调整找感觉
float ratioY = distance - Mathf.Lerp(minDistance, maxDistance, 0.5f);
float ratioX = (distance - Mathf.Lerp(minDistance, maxDistance, 0.5f)) * 1.75f;
//把摄像机的位置控制在范围内
m_CameraOffset = new Vector3(Mathf.Clamp(m_CameraOffset.x, xMin + ratioX, xMax - ratioX), Mathf.Clamp(m_CameraOffset.y, yMin + ratioY, yMax - ratioY), m_CameraOffset.z);
lastSingleTouchPosition = scenePos;
}
}
2. 3D游戏操控方式
public class GestureController : MonoBehaviour
{
//摄像机当前缩放
public float distance = 4f;
//缩放系数
public float scaleFactor = 0.1f;
//最大最小缩放范围
public float maxDistance = 6f;
public float minDistance = 2f;
//记录上一次手机触摸位置判断用户是在左放大还是缩小手势
private Vector2 oldPosition1;
private Vector2 oldPosition2;
private Vector2 lastSingleTouchPosition;
//位移后摄像机的位置
private Vector3 m_CameraOffset;
//主摄像机
private Camera m_Camera;
//鼠标和手指操作切换
public bool useMouse = true;
//摄像机缩放为中间值时摄像机可以活动的范围
public float xMin = 3.5f;
public float xMax = 17.5f;
public float zMin = 0;
public float zMax = 11.75f;
//这个变量用来记录单指双指的变换
private bool m_IsSingleFinger;
//初始化游戏信息设置
public void Start()
{
if (Application.platform == RuntimePlatform.Android)
{
useMouse = false;
}
m_Camera = Camera.main;
m_CameraOffset = m_Camera.transform.position;
}
public void Update()
{
//判断触摸数量为单点触摸
if (Input.touchCount == 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Began || !m_IsSingleFinger)
{
//在开始触摸或者从两字手指放开回来的时候记录一下触摸的位置
lastSingleTouchPosition = Input.GetTouch(0).position;
}
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
MoveCamera(Input.GetTouch(0).position);
}
m_IsSingleFinger = true;
}
else if (Input.touchCount > 1)
{
//当从单指触摸进入多指触摸的时候,记录一下触摸的位置
//保证计算缩放都是从两指手指触碰开始的
if (m_IsSingleFinger)
{
oldPosition1 = Input.GetTouch(0).position;
oldPosition2 = Input.GetTouch(1).position;
}
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
ScaleCamera();
}
m_IsSingleFinger = false;
}
//用鼠标的
if (useMouse)
{
distance -= Input.GetAxis("Mouse ScrollWheel");
distance = Mathf.Clamp(distance, minDistance, maxDistance);
if (Input.GetMouseButtonDown(0))
{
lastSingleTouchPosition = Input.mousePosition;
//Debug.Log("GetMouseButtonDown:" + lastSingleTouchPosition);
}
if (Input.GetMouseButton(0))
{
MoveCamera(Input.mousePosition);
}
}
LateUpdate();
}
///
/// 触摸缩放摄像头
///
private void ScaleCamera()
{
//计算出当前两点触摸点的位置
var tempPosition1 = Input.GetTouch(0).position;
var tempPosition2 = Input.GetTouch(1).position;
float currentTouchDistance = Vector3.Distance(tempPosition1, tempPosition2);
float lastTouchDistance = Vector3.Distance(oldPosition1, oldPosition2);
//计算上次和这次双指触摸之间的距离差距
//然后去更改摄像机的距离
distance -= (currentTouchDistance - lastTouchDistance) * scaleFactor * Time.deltaTime;
//把距离限制住在min和max之间
distance = Mathf.Clamp(distance, minDistance, maxDistance);
//重新位移摄像机位置防止超出边界
// MoveCamera(lastSingleTouchPosition);
//备份上一次触摸点的位置,用于对比
oldPosition1 = tempPosition1;
oldPosition2 = tempPosition2;
MoveCamera(lastSingleTouchPosition);
}
//Update方法一旦调用结束以后进入这里算出重置摄像机的位置
private void LateUpdate()
{
var position = m_CameraOffset + m_Camera.transform.forward * -distance;
m_Camera.transform.position = position;
}
//移动摄像机
private void MoveCamera(Vector3 scenePos)
{
Vector3 lastTouchPostion = m_Camera.ScreenToWorldPoint(new Vector3(lastSingleTouchPosition.x, lastSingleTouchPosition.y, -1));
Vector3 currentTouchPosition = m_Camera.ScreenToWorldPoint(new Vector3(scenePos.x, scenePos.y, -1));
Vector3 v = currentTouchPosition - lastTouchPostion;
m_CameraOffset += new Vector3(v.x, 0, v.z) * m_Camera.transform.position.y;
//这两个值为基于摄像机缩放最大值和最小值增长的幅度,自行调整找感觉
float ratioX = distance - Mathf.Lerp(minDistance, maxDistance, 0.5f);
float ratioZ = distance - Mathf.Lerp(minDistance, maxDistance, 0.5f) * 1.5f;
//把摄像机的位置控制在范围内
m_CameraOffset = new Vector3(Mathf.Clamp(m_CameraOffset.x, xMin + ratioX, xMax - ratioX), 0, Mathf.Clamp(m_CameraOffset.z, zMin, zMax - ratioZ));
lastSingleTouchPosition = scenePos;
}
}