虚拟遥杆实现

xiaoxiao2021-02-27  170

        记录:

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

Using standard .NET  delegate-based events. Each gesture recognizer exposes a  .NET event that you can subscribe to from code. 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

        

转载请注明原文地址: https://www.6miu.com/read-15209.html

最新回复(0)