虚拟遥杆实现

发表于2017-12-04
评论0 903浏览

       最近接触到了FingerGesture插件,了解其大致使用方法之后,便想用它做个简单的例子尝试一下,于是便选择了虚拟遥杆,下面就来看看虚拟遥杆的实现方式。


       该demo实现的大致功能如下:1.虚拟遥杆操作界面 2.根据操作移动场景中的物体。大致效果如下,AV画质:

      

       具体实现:首先,遥杆操作界面的实现,其思想是用两张图片,一张做背景,一张做移动杆。这样只需捕获到手指的触屏操作,动态改变移动杆的位置便可模拟出虚拟遥杆。而捕获触摸操作既可以通过unity自带的事件系统,也可以借助一些插件,这里则是使用了FingerGesture插件,用到了其中的FingerDown Detector,FingerUpDetector,FingerMotionDetector。

       FingerGesture能够识别的手势有taps, swipes, drags and pinches 等;使用时,首先要在场景中中添加FingerGestures.prefab,它是管理各种手势触屏操作的中心。其次根据需要添加相应的模块,比如识别长按,则可添加脚本Long-Press Recognizer.cs 。监听一些手指操作,则可添加FingerDown Detector,FingerUpDetector等。对于各种触摸操作事件的传递,有以下两种:(使用的Finger Gesture版本是3.1,Unity5.3.6p8)

       A gesture recognizer has several ways of firing its events:

  1. Using standard .NET delegate-based events. Each gesture recognizer exposes a .NET event that you can subscribe to from code.
  2. Using Unity's SendMessage() method
    • The gesture event is broadcast to all the other components on the same GameObject
    • The gesture event can also be forwarded to the scene object currently being interacted with (selection). This however requires the GestureRecognizer to be equipped with a Raycaster component in order to detect scene objects.

       大意为:手势操作的监听既可通过委托注册相应事件,也可利用Unity广播传递。使用广播机制时,要注意:在没有设置Message Tagert时,消息会默认发送给挂在了该手势事件脚本的游戏体,若指定了,则只发送给指定的对象。使用委托进行事件的注册时,使用的是统一的事件接口,对于手势识别为: FingerGestures.OnGestureEvent;对于手指事件则为  FingerGestures.OnFingerEvent。在触发了事件后,在对应的处理函数中再利用GetType()判断具体的事件类型。

具体使用细节可查看官网文档:http://fingergestures.fatalfrog.com/docs/start。


       其次,则是将遥杆的操作作用到场景中的具体对象。物体移动最主要的也就是两个方面:1.移动的方向,2.移动的速度。本例对运动方向的确定由下图可直观的看出,对于速度的控制则采取的是手动设定、匀速的方式;当然也可以根据遥杆距中心点的距离不同设置不同的移动速度。



主要逻辑代码:

using UnityEngine;  
using System.Collections;  
using UnityEngine.EventSystems;  
public class CircleMove : MonoBehaviour{  
    public Transform circle;  
    public Transform player;  
    private Vector3 origin;  
    public float rotate_speed=1.0f;  
    public float move_speed=1.0f;  
    //摇杆移动半径  
    public float move_area = 100.0f;  
    public GameObject container;  
    private bool stop=true ;  
    public Vector2 default_pos = new Vector2(300,300);  
    private Vector3 last_position;  
    private Vector3 move_dir;  
    private int first_finger_index=-1;  
    // Use this for initialization  
    void Start () {  
        container.transform.position = default_pos;  
        origin = circle.position;        
    }  
    // Update is called once per frame  
    void Update () {  
        //EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId);//对于EventSystem.current.IsPointerOverGameObject这个函数,  
        //因为EventSystem是UI的事件系统,所以IsPointerOverGameObject中的GameObject是针对UI的,而不是普遍意义上的GameObject  
        if(!stop)  
            MoveGameObj(circle.position);     
    }  
    void OnFingerMove(FingerMotionEvent e)  
    {  
        if(first_finger_index!=e.Finger.Index)  
            return ;  
        if (e.Position.x > Screen.width / 2 || e.Position.y > Screen.height / 2)  
            return;  
        float elapsed = e.ElapsedTime;  
        if (e.Phase == FingerMotionPhase.Started)  
            Debug.Log(e.Finger + " started moving at " + e.Position);  
        else if (e.Phase == FingerMotionPhase.Updated)  
        {  
            if (Vector2.Distance(origin, Input.mousePosition) <= move_area)  
                circle.position = e.Position;  
            else {   
                Vector2 dir=e.Position- new Vector2(origin.x, origin.y);  
                circle.position =new Vector2(origin.x, origin.y)+ dir.normalized * move_area;  
            }  
        }  
        else if (e.Phase == FingerMotionPhase.Ended)  
        {  
            Debug.Log(e.Finger + " stopped moving at " + e.Position);  
            last_position = circle.position;  
        }  
    }  
    void OnFingerStationary(FingerMotionEvent e)  
    {  
        //float elapsed = e.ElapsedTime;  
        //if (e.Phase == FingerMotionPhase.Started)  
        //    Debug.Log(e.Finger + " started stationary state at " + e.Position);  
        //else if (e.Phase == FingerMotionPhase.Updated)  
        //    Debug.Log(e.Finger + " is still stationary at " + e.Position);  
        //else if (e.Phase == FingerMotionPhase.Ended)  
        //{  
        //    Debug.Log(e.Finger + " stopped being stationary at " + e.Position);  
        //    circle.position = origin;  
        //}  
    }  
    void OnFingerDown(FingerDownEvent e)  
    {  
        if(first_finger_index!=-1)  
            return ;  
        first_finger_index = e.Finger.Index;  
        Debug.Log(" first_finger_index >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + first_finger_index);  
        if (e.Position.x < Screen.width / 2 && e.Position.y < Screen.height / 2)//判断出触摸处是否可显示虚拟遥杆,可则显示,不可则退出  
        {  
            container.transform.position = e.Position;  
            origin = circle.position;  
            stop = false;  
        }  
        else {  
            return;  
        }  
        Debug.Log(e.Finger + " Down at " + e.Position + " on object:" + e.Selection.name);  
    }  
    void OnFingerUp(FingerUpEvent e)  
    {  
        Debug.LogError("tappppppp2555552=====111111111");  
        if (first_finger_index != e.Finger.Index)  
            return;  
        container.transform.position = default_pos;  
        circle.localPosition=Vector2.zero;  
        origin = circle.position;  
        stop = true;  
        first_finger_index=-1;  
    }  
    void MoveGameObj(Vector2 target) {  
        if (Vector2.Distance(target, last_position) > 0.5) {                 
            Vector2 dir = target - new Vector2(origin.x, origin.y);        
            move_dir = new Vector3(dir.x, 0, dir.y);  
        }             
        player.position += move_dir.normalized * move_speed * Time.deltaTime;  
        player.rotation = Quaternion.Lerp(player.rotation, Quaternion.LookRotation(move_dir), rotate_speed * Time.deltaTime);  
    }  
    void OnTap(TapGesture gesture)  
    {  
        // Number of taps performed  
        Debug.LogError("tappppppp=====");  
    }  
}  


工程很乱,没有整理,DEMO下载:http://download.csdn.net/detail/u012221316/9921999
来自:http://blog.csdn.net/u012221316/article/details/76697168

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论