实现:通过EasyTouch插件中点击屏幕的几种事件,来实现点击屏幕,角色发动移动,以及滑动屏幕实现视角转变和两指操作实现缩放。
本人测试过:EasyTouch4或者5版本都可以使用。
1.导入EasyTouch插件,在Hierarchy窗口中点击右键创建EasyTouch->EasyTouch(有可能没有出现这个选项,需要加载一会就出来了)
2.创建该物体之后,再创建脚本FingerEvent.cs,因为插件之间低耦合性,所以该脚本只需要获取EasyTouch几种点击屏幕的点击事件就好了,其他插件也会有类似的方法。
3.编辑FingerEvent脚本,获取几种事件。
void OnEnable()
{
//启动时调用,这里开始注册手势操作的事件。
//按下事件: OnFingerhDown就是按下事件监听的方法,这个名子可以由你来自定义。方法只能在本类中监听。下面所有的事件都一样!!!
EasyTouch.On_TouchDown += OnFingerDown;
//抬起事件
EasyTouch.On_TouchUp += OnFingerUp;
//手指在屏幕中拖动事件
EasyTouch.On_Swipe+= OnFingerDragMove;
//开始拖动事件
EasyTouch.On_SwipeStart += OnFingerDragBegin;
//拖动结束事件
EasyTouch.On_SwipeEnd += OnFingerDragEnd;
EasyTouch.On_EasyTouchIsReady += OnFingerStationaryBegin;
}
void OnDisable()
{
EasyTouch.On_TouchDown -= OnFingerDown;
EasyTouch.On_TouchUp -= OnFingerUp;
EasyTouch.On_Drag -= OnFingerDragMove;
EasyTouch.On_DragStart -= OnFingerDragBegin;
EasyTouch.On_DragEnd -= OnFingerDragEnd;
EasyTouch.On_EasyTouchIsReady -= OnFingerStationaryBegin;
}
void OnFingerDown(Gesture gesture)
{
Debug.Log("On_TouchDown");
}
void OnFingerUp(Gesture gesture)
{
Debug.Log("On_TouchUp");
}
void OnFingerDragMove(Gesture gesture)
{
Debug.Log("OnFingerDragMove");
}
void OnFingerDragBegin(Gesture gesture)
{
Debug.Log("OnFingerDragBegin");
}
void OnFingerDragEnd(Gesture gesture)
{
Debug.Log("On_DragEnd");
}
void OnFingerStationaryBegin()
{
}
这样就可以在测试运行后通过鼠标左键,移动是否会调用这些事件。
测试成功后就可以在触发这些事件之后,调用相应的相机方法。
4.先定义FingerEvent单例,一个枚举FingerDir,枚举类型的滑动委托OnFingerDrag,记录手指上一次位置的变量m_OldFingerPos,手指滑动方向变量m_Dir。
public class FingerEvent : MonoBehaviour {
public static FingerEvent Instance;
///
/// 滑动的四个方向
///
public enum FingerDir
{
Left,
Right,
Up,
Down
}
///
/// 滑动委托
///
public Action OnFingerDrag;
///
/// 手指上一次的位置
///
private Vector2 m_OldFingerPos;
///
/// 手指滑动方向
///
private Vector2 m_Dir;
void Awake()
{
Instance = this;
}
///
/// 记录开始滑动时候,手指点击的位置
///
///
void OnFingerDragBegin(Gesture gesture)
{
m_OldFingerPos = gesture.position;
}
void OnFingerDragMove(Gesture gesture)
{
m_PrevFinger = 3;
m_Dir = gesture.position - m_OldFingerPos;
//通过向量的数值,判断滑动的方向
if(m_Dir.y-m_Dir.x)
{
//向右
if(OnFingerDrag!=null)
{
OnFingerDrag(FingerDir.Right);
}
}else if(m_Dir.y>m_Dir.x&&m_Dir.y<-m_Dir.x)
{
//向左
if (OnFingerDrag != null)
{
OnFingerDrag(FingerDir.Left);
}
}
else if(m_Dir.y>m_Dir.x&&m_Dir.y>-m_Dir.x)
{
//向上
if (OnFingerDrag != null)
{
OnFingerDrag(FingerDir.Up);
}
}
else
{
//向下
if (OnFingerDrag != null)
{
OnFingerDrag(FingerDir.Down);
}
}
4.在角色控制脚本监听事件
void Start ()
{
FingerEvent.Instance.OnFingerDrag += OnFingerDrag;
}
//在被摧毁时,取消监听事件
void OnDestroy()
{
FingerEvent.Instance.OnFingerDrag -= OnFingerDrag;
}
private void OnFingerDrag(FingerEvent.FingerDir obj)
{
switch(obj)
{
case FingerEvent.FingerDir.Left:
CameraCtrl.Instance.SetCameraRotate(0);
break;
case FingerEvent.FingerDir.Right:
CameraCtrl.Instance.SetCameraRotate(1);
break;
case FingerEvent.FingerDir.Up:
CameraCtrl.Instance.SetCameraUpAndDown(0);
break;
case FingerEvent.FingerDir.Down:
CameraCtrl.Instance.SetCameraUpAndDown(1);
break;
}
}
到这里就已经实现了,滑动屏幕调整相机角度,但是又一个问题,就是我**滑动结束,松开鼠标或者屏幕的时候,角色自己走到松开点击的位置。**所以需要再改动一下。
5.再添加角色点击地面的事件,以及记录上一个操作的int型变量m_PrevFinger(这里也可以设置成一个枚举方便代码阅读)
///
/// 玩家点击地面
///
public System.Action OnPlayerClickGround;
///
/// 上一个操作
///
private int m_PrevFinger = -1;
void OnFingerDown(Gesture gesture)
{
//Debug.Log("On_TouchDown");
m_PrevFinger = 1;
}
void OnFingerUp(Gesture gesture)
{
//Debug.Log("On_TouchUp");
//只有当上一个操作时点击屏幕时,才会触发OnPlayerClickGround事件
if(m_PrevFinger==1)
{
m_PrevFinger = -1;
if(OnPlayerClickGround!=null)
{
OnPlayerClickGround();
}
}
}
void OnFingerDragMove(Gesture gesture)
{
m_PrevFinger = 3;
m_Dir = gesture.position - m_OldFingerPos;
if(m_Dir.y-m_Dir.x)
{
//向右
if(OnFingerDrag!=null)
{
OnFingerDrag(FingerDir.Right);
}
}else if(m_Dir.y>m_Dir.x&&m_Dir.y<-m_Dir.x)
{
//向左
if (OnFingerDrag != null)
{
OnFingerDrag(FingerDir.Left);
}
}
else if(m_Dir.y>m_Dir.x&&m_Dir.y>-m_Dir.x)
{
//向上
if (OnFingerDrag != null)
{
OnFingerDrag(FingerDir.Up);
}
}
else
{
//向下
if (OnFingerDrag != null)
{
OnFingerDrag(FingerDir.Down);
}
}
}
///
/// 记录开始滑动时候,手指点击的位置
///
///
void OnFingerDragBegin(Gesture gesture)
{
m_PrevFinger = 2;
m_OldFingerPos = gesture.position;
}
void OnFingerDragEnd(Gesture gesture)
{
m_PrevFinger = 4;
//Debug.Log("On_DragEnd");
}
然后在角色控制代码监听这个事件。
void Start ()
{
FingerEvent.Instance.OnFingerDrag += OnFingerDrag;
FingerEvent.Instance.OnPlayerClickGround += OnPlayerClickGround;
}
void OnDestroy()
{
FingerEvent.Instance.OnFingerDrag -= OnFingerDrag;
FingerEvent.Instance.OnPlayerClickGround -= OnPlayerClickGround;
}
//将点击鼠标左键使确定移动的目标的代码,复制到这下面。
//因为点击屏幕不能一直触发,所以移动部分的代码,还得放在Update里
private void OnPlayerClickGround()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
if (hitInfo.collider.gameObject.name.Equals("Ground"))
{
m_TargetPos = hitInfo.point;
Debug.DrawLine(Camera.main.transform.position, m_TargetPos);
}
}
m_RotationSpeed = 0f;
}
到这里,也就实现了点击屏幕角色移动到目标点,并且解决了移动和转视角同时发生的情况。下一步实现视角缩放
6. 实现移动平台下的视角缩放。
添加枚举ZoomType,ZoomType类型的事件OnZoom(事件前面一般都要加个On,习惯),四个二维坐标记录现在手指在屏幕中的两个位置m_TempFinger1Pos,m_TempFinger2Pos,以及以前的两个手指在屏幕中的位置m_OldFinger1Pos,m_OldFinger2Pos。
public enum ZoomType
{
In,
Out
}
public System.Action OnZoom;
private Vector2 m_TempFinger1Pos;
private Vector2 m_TempFinger2Pos;
private Vector2 m_OldFinger1Pos;
private Vector2 m_OldFinger2Pos;
//在update里写各平台的预编译操作
void Update()
{
//在编辑器下和windows平台下
#if UNITY_EDITOR || UNITY_STANDALONE_WIN
if(Input.GetAxis("Mouse ScrollWheel")<0)
{
//触发事件
if(OnZoom!=null)
{
OnZoom(ZoomType.In);
}
}
else if(Input.GetAxis("Mouse ScrollWheel") > 0)
{
if (OnZoom != null)
{
OnZoom(ZoomType.Out);
}
}
//在Android和iphone平台下
#elif UNITY_ANDROID || UNITY_IPHONE
//判断是否为两个手指进行操作
if(Input.touchCount>1)
{
//最少一个手指在移动
if(Input.GetTouch(0).phase==TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
//得到当前两个手指的位置
m_TempFinger1Pos = Input.GetTouch(0).position;
m_TempFinger2Pos = Input.GetTouch(1).position;
//现在两个手指的位置距离与以前手指位置的距离做对比
if(Vector2.Distance(m_TempFinger1Pos,m_TempFinger2Pos)>Vector2.Distance(m_OldFinger1Pos,m_OldFinger2Pos))
{
//放大
OnZoom(ZoomType.In);
}
else
{
//缩小
OnZoom(ZoomType.Out);
}
m_OldFinger1Pos = m_TempFinger1Pos;
m_OldFinger2Pos = m_TempFinger2Pos;
}
}
#endif
}
再在角色控制代码中监听这个事件
void Start ()
{
FingerEvent.Instance.OnZoom += OnZoom;
}
void OnDestroy()
{
FingerEvent.Instance.OnZoom -= OnZoom;
}
private void OnZoom(FingerEvent.ZoomType obj)
{
switch(obj)
{
case FingerEvent.ZoomType.In:
CameraCtrl.Instance.SetCameraZoom(0);
break;
case FingerEvent.ZoomType.Out:
CameraCtrl.Instance.SetCameraZoom(1);
break;
}
}
再将以前写的通过键盘按键控制角色旋转或者缩放按键均注释掉,就实现了所有的功能。
总结:1.利用射线,得到目标位置点,控制角色移动到目标点
2.通过相机5层结构,简化实现相机围绕目标点旋转的算法。并封装成几种方法,通过角色控制脚本用键盘点击调用这几种方法
3.利用EasyTouch获取几种屏幕点击事件,再手动添加事件,当点击屏幕的时候触发,再在角色控制脚本中进行监听,监听到事件触发,就调用相机中的旋转视角的方法。