频道栏目
首页 > 资讯 > 其他 > 正文

虚拟遥杆实现

17-08-07        来源:[db:作者]  
收藏   我要投稿

记录:

最近接触到了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 .NETdelegate-based events. Each gesture recognizer exposes a.NET eventthat you can subscribe to from code.
  2. Using Unity'sSendMessage() 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=====");
          }
      
      }
相关TAG标签
上一篇:浅谈SSH+ajax分页效果
下一篇:jquery选择器全解
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站