功能
单指滑屏控制相机移动
双指滑屏控制相机视野缩放
原理
借助Input.GetTouch,在正确的时机发出6个事件:
- 单指按下、滑动、抬起
- 双指按下、滑动、抬起
单指滑动控制相机移动
在 单指按下 时:记录当前位置,进入 控制移动状态。
在 单指移动 时:若此时处于 控制移动状态,将当前位置与前一位置做差获得向量,让相机基于该向量进行移动。
在 单指抬起、双指按下滑动抬起时:退出 控制移动状态。
双指滑动控制相机移动
在 双指按下 时:记录当前两指位置的距离,作为本次的标准距离。
在 双指移动 时:将当前两指位置的距离与标准距离做差,算得应缩放的值。
代码
TouchSys.cs
在合适的时机发出各事件。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TouchSys : MonoBehaviour
{
public event Action<Vector2> SingleTouchBeginEvent;
public event Action<Vector2> SingleTouchMoveEvent;
public event Action<Vector2> SingleTouchEndEvent;
public event Action<Vector2,Vector2> DoubleTouchBeginEvent;
public event Action<Vector2,Vector2> DoubleTouchMoveEvent;
public event Action<Vector2,Vector2> DoubleTouchEndEvent;
private void Start()
{
Init();
}
private void Update()
{
MyUpdate();
}
private void OnDestroy()
{
MyDestroy();
}
private void Init()
{
}
private void MyUpdate()
{
if (Input.touchCount == 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
SingleTouchBeginEvent?.Invoke(Input.GetTouch(0).position);
}
else if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
SingleTouchMoveEvent?.Invoke(Input.GetTouch(0).position);
}
else if (Input.GetTouch(0).phase == TouchPhase.Ended)
{
SingleTouchEndEvent?.Invoke(Input.GetTouch(0).position);
}
}
else if (Input.touchCount == 2)
{
Vector2 pos0 = Input.GetTouch(0).position;
Vector2 pos1 = Input.GetTouch(1).position;
if (Input.GetTouch(1).phase == TouchPhase.Began)
{
DoubleTouchBeginEvent?.Invoke(pos0,pos1);
}
else if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
DoubleTouchMoveEvent?.Invoke(pos0,pos1);
}
else if (Input.GetTouch(0).phase == TouchPhase.Ended || Input.GetTouch(1).phase == TouchPhase.Ended)
{
DoubleTouchEndEvent?.Invoke(pos0,pos1);
}
}
}
private void MyDestroy()
{
}
}
MoveCamCtrOnMobile.cs
在合适的时机控制相机移动。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveCamCtrOnMobile : MonoBehaviour
{
private TouchSys _touchSys;
private CamCtrSys _camCtrSys;
[SerializeField]
private float _moveSpeedFactor = 1;
private Vector2 _lastPos;
private Vector2 _curPos;
private bool _isInMoveCtrState;
private bool IsInMoveCtrState{get{return _isInMoveCtrState;}}
private void Start()
{
Init();
}
private void Update()
{
MyUpdate();
}
private void OnDestroy()
{
MyDestroy();
}
private void Init()
{
ExitMoveCtrState();
_camCtrSys = FindObjectOfType<CamCtrSys>();
_touchSys = FindObjectOfType<TouchSys>();
_touchSys.SingleTouchBeginEvent += OnSingleTouchBegin;
_touchSys.SingleTouchMoveEvent += OnSingleTouchMove;
_touchSys.SingleTouchEndEvent += OnSingleTouchEnd;
_touchSys.DoubleTouchBeginEvent += OnDoubleTouchBegin;
_touchSys.DoubleTouchMoveEvent += OnDoubleTouchMove;
_touchSys.DoubleTouchEndEvent += OnDoubleTouchEnd;
}
private void MyUpdate()
{
}
private void MyDestroy()
{
_touchSys.SingleTouchBeginEvent -= OnSingleTouchBegin;
_touchSys.SingleTouchMoveEvent -= OnSingleTouchMove;
_touchSys.SingleTouchEndEvent -= OnSingleTouchEnd;
_touchSys.DoubleTouchBeginEvent -= OnDoubleTouchBegin;
_touchSys.DoubleTouchMoveEvent -= OnDoubleTouchMove;
_touchSys.DoubleTouchEndEvent -= OnDoubleTouchEnd;
_touchSys = null;
_camCtrSys = null;
}
private void OnSingleTouchBegin(Vector2 pos)
{
_lastPos = pos;
EnterMoveCtrState();
}
private void OnSingleTouchMove(Vector2 pos)
{
if (IsInMoveCtrState)
{
_curPos = pos;
_camCtrSys.Move((_curPos - _lastPos)*_moveSpeedFactor * _camCtrSys.CameraZoomSize);
_lastPos = _curPos;
}
}
private void OnSingleTouchEnd(Vector2 pos)
{
ExitMoveCtrState();
}
private void OnDoubleTouchBegin(Vector2 pos0, Vector2 pos1)
{
ExitMoveCtrState();
}
private void OnDoubleTouchMove(Vector2 pos0, Vector2 pos1)
{
ExitMoveCtrState();
}
private void OnDoubleTouchEnd(Vector2 pos0, Vector2 pos1)
{
ExitMoveCtrState();
}
private void EnterMoveCtrState()
{
_isInMoveCtrState = true;
}
private void ExitMoveCtrState()
{
_isInMoveCtrState = false;
}
}
ZoomCamCtrOnMobile.cs
在合适的时机调整相机视野大小。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ZoomCamCtrOnMobile : MonoBehaviour
{
private TouchSys _touchSys;
private CamCtrSys _camCtrSys;
[SerializeField]
private float _zoomSpeedFactor = 1;
private float _curStandardLength;
private void Start()
{
Init();
}
private void Update()
{
MyUpdate();
}
private void OnDestroy()
{
MyDestroy();
}
private void Init()
{
_camCtrSys = FindObjectOfType<CamCtrSys>();
_touchSys = FindObjectOfType<TouchSys>();
_touchSys.DoubleTouchBeginEvent += OnDoubleTouchBegin;
_touchSys.DoubleTouchMoveEvent += OnDoubleTouchMove;
}
private void MyUpdate()
{
}
private void MyDestroy()
{
_touchSys.DoubleTouchBeginEvent -= OnDoubleTouchBegin;
_touchSys.DoubleTouchMoveEvent -= OnDoubleTouchMove;
_touchSys = null;
_camCtrSys = null;
}
private void OnDoubleTouchBegin(Vector2 pos0, Vector2 pos1)
{
_curStandardLength = Vector2.Distance(pos0, pos1);
}
private void OnDoubleTouchMove(Vector2 pos0, Vector2 pos1)
{
float curLength = Vector2.Distance(pos0, pos1);
float curOffset = curLength - _curStandardLength;
_camCtrSys.ZoomByOffset(curOffset * _zoomSpeedFactor);
}
}
CamCtrSys.cs
相机参数(位置、视野大小)控制。
using System.Transactions;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamCtrSys : MonoBehaviour
{
[SerializeField]
private Transform _camTrans;
[SerializeField]
private Camera _cam;
[SerializeField]
private Vector2 _zoomRange;
private MapGenerator _mapGenerator;
public float CameraZoomSize
{
get{return _cam.orthographicSize;}
}
private void Start()
{
Init();
}
private void Update()
{
MyUpdate();
}
private void OnDestroy()
{
MyDestroy();
}
private void Init()
{
_mapGenerator = FindObjectOfType<MapGenerator>();
_mapGenerator.GenerateMapEvent += OnGenerateMap;
}
private void MyUpdate()
{
}
private void MyDestroy()
{
_mapGenerator.GenerateMapEvent-= OnGenerateMap;
_mapGenerator = null;
}
public void SetPos(Vector2 pos)
{
_camTrans.position = new Vector3(pos.x, _camTrans.position.y, pos.y);
}
public void Move(Vector2 offset)
{
var lastPos = new Vector2(_camTrans.position.x, _camTrans.position.z);
var newPos = lastPos + offset;
SetPos(newPos);
}
private void OnGenerateMap(Vector2Int size, Vector2 centerPos)
{
SetPos(centerPos);
}
// v表示比例:0~1
public void ZoomByRatio(float v)
{
_cam.orthographicSize = _zoomRange.x+(_zoomRange.y-_zoomRange.x)*Mathf.Clamp01(v);
}
public void ZoomByOffset(float offset)
{
_cam.orthographicSize = Mathf.Clamp(_cam.orthographicSize + offset, _zoomRange.x, _zoomRange.y);
}
}
网友评论