虚拟遥杆实现


        记录:

     最近接触到了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

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值