Unity RPG手游中控制角色相机的移动跟随(三)

实现:通过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获取几种屏幕点击事件,再手动添加事件,当点击屏幕的时候触发,再在角色控制脚本中进行监听,监听到事件触发,就调用相机中的旋转视角的方法。

你可能感兴趣的:(Unity)