【问题标题】:Unity 5 Multi touch Swipe eventsUnity 5 多点触控滑动事件
【发布时间】:2016-06-04 17:32:40
【问题描述】:

我正在使用统一的默认跨平台操纵杆控件的稍微修改版本,它在统一 5.3 中可用,我正在尝试创建一个事件触发器,当我在操纵杆上滑动时会触发它(初始点击必须启动离开操纵杆)

public class Joystick : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
    public enum AxisOption
    {
        // Options for which axes to use
        Both, // Use both
        OnlyHorizontal, // Only horizontal
        OnlyVertical // Only vertical
    }

    public int MovementRange = 100;
    public AxisOption axesToUse = AxisOption.Both; // The options for the axes that the still will use
    public string horizontalAxisName = "Horizontal"; // The name given to the horizontal axis for the cross platform input
    public string verticalAxisName = "Vertical"; // The name given to the vertical axis for the cross platform input

    Vector3 m_StartPos;
    bool m_UseX; // Toggle for using the x axis
    bool m_UseY; // Toggle for using the Y axis
    CrossPlatformInputManager.VirtualAxis m_HorizontalVirtualAxis; // Reference to the joystick in the cross platform input
    CrossPlatformInputManager.VirtualAxis m_VerticalVirtualAxis; // Reference to the joystick in the cross platform input

    void OnEnable()
    {
        CreateVirtualAxes();
    }

    void Start()
    {
        m_StartPos = transform.position;
    }

    void UpdateVirtualAxes(Vector3 value)
    {
        var delta = m_StartPos - value;
        delta.y = -delta.y;
        delta /= MovementRange;
        if (m_UseX)
        {
            m_HorizontalVirtualAxis.Update(-delta.x);
        }

        if (m_UseY)
        {
            m_VerticalVirtualAxis.Update(delta.y);
        }
    }

    void CreateVirtualAxes()
    {
        // set axes to use
        m_UseX = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyHorizontal);
        m_UseY = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyVertical);

        // create new axes based on axes to use
        if (m_UseX)
        {
            m_HorizontalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(horizontalAxisName);
            CrossPlatformInputManager.RegisterVirtualAxis(m_HorizontalVirtualAxis);
        }
        if (m_UseY)
        {
            m_VerticalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(verticalAxisName);
            CrossPlatformInputManager.RegisterVirtualAxis(m_VerticalVirtualAxis);
        }
    }

    public void OnDrag(PointerEventData data)
    {
        Vector3 newPos = Vector3.zero;

        if (m_UseX)
        {
            int delta = (int)(data.position.x - m_StartPos.x);
            newPos.x = delta;
        }

        if (m_UseY)
        {
            int delta = (int)(data.position.y - m_StartPos.y);
            newPos.y = delta;
        }

        var newPosition = new Vector3(newPos.x, newPos.y, newPos.z);

        transform.position = Vector3.ClampMagnitude(newPosition, MovementRange) + m_StartPos;

        UpdateVirtualAxes(transform.position);
    }

    public void OnPointerUp(PointerEventData data)
    {
        transform.position = m_StartPos;
        UpdateVirtualAxes(m_StartPos);
    }

    public void OnPointerDown(PointerEventData data) { }
}

我已经知道如何创建检测滑动方向的逻辑,我们将方法存根定义为这样,

 public SwipeDirectionEnum GetSwipeDirection(Vector3 startPosition, Vector3 endingPosition);

我遇到的唯一问题是如何在控件外部建立点击,通过与操纵杆控件相交或部分相交来滑动末端?

【问题讨论】:

    标签: c# mobile unity3d multi-touch


    【解决方案1】:

    我编写了一个脚本来执行此操作,以防将来有人希望这样做。你需要修改 TouchPad.cs 这将使用一个帧缓存来找到几帧之间的中间方向,这样它就可以适当地支持多点触控。

    将此添加到 TouchPad.Cs

      bool isTouchPadCoordinatorInitialized = false;
        TouchPadEventCoordinator touchPadCoordinator;
    
        public void InitializeTouchPadCoordinator(string horizontalAxis, string verticalAxis, Action swipeUp = null, Action swipeRight = null,
            Action swipeDown = null, Action swipeLeft = null, Action swipeMultiUp = null, 
            Action swipeMultiRight = null, Action swipeMultiDown = null, Action swipeMultiLeft = null)
        {
            touchPadCoordinator = new TouchPadEventCoordinator(horizontalAxis, verticalAxisName, swipeUp, swipeRight, 
                                                                swipeDown, swipeLeft, swipeMultiUp, swipeMultiRight, 
                                                                swipeMultiDown, swipeLeft);
            isTouchPadCoordinatorInitialized = true;
        }
    

    修改on指针向上清除缓存:

        public void OnPointerUp(PointerEventData data)
        {
            m_Dragging = false;
            m_Id = -1;
            UpdateVirtualAxes(Vector3.zero);
    
            if(isTouchPadCoordinatorInitialized)
            {
                touchPadCoordinator.ClearDirectionCache();
            }
    
        }
    

    修改更新以这样开始:

        void Update()
        {
            if (!m_Dragging)
            {
                return;
            }
    
            if(isTouchPadCoordinatorInitialized)
            {
                touchPadCoordinator.UpdateSwipe();
            }
       // The rest of the update function goes here
    

    TouchPadCoordinator 文件如下所示:

    using UnityEngine;
    using System.Collections;
    using UnityStandardAssets.CrossPlatformInput;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace UnityStandardAssets.CrossPlatformInput
    {
        public class TouchPadEventCoordinator : MonoBehaviour
        {
    
            public int maxFrameCache = 7;
    
            string _horizontalAxisName;
            string _verticalAxisName;
    
            List<SwipeDirection> _directionCache = new List<SwipeDirection>();
            Dictionary<SwipeDirection, Action> _directionEventMap = new Dictionary<SwipeDirection, Action>();
    
            public Action SwipeUp { get; set; }
            public Action SwipeRight { get; set; }
            public Action SwipeDown { get; set; }
            public Action SwipeLeft { get; set; }
            public Action SwipeMultiUp { get; set; }
            public Action SwipeMultiRight { get; set; }
            public Action SwipeMultiDown { get; set; }
            public Action SwipeMultiLeft { get; set; }
    
            public TouchPadEventCoordinator(string horizontalAxisName, string verticalAxisName, Action swipeUp = null, Action swipeRight = null,
                Action swipeDown = null, Action swipeLeft = null, Action swipeMultiUp = null,
                Action swipeMultiRight = null, Action swipeMultiDown = null, Action swipeMultiLeft = null)
            {
                _horizontalAxisName = horizontalAxisName;
                _verticalAxisName = verticalAxisName;
    
                SwipeUp = swipeUp;
                SwipeDown = swipeDown;
                SwipeLeft = swipeLeft;
                SwipeRight = swipeRight;
                SwipeMultiUp = swipeMultiUp;
                SwipeMultiDown = swipeMultiDown;
                SwipeMultiLeft = swipeMultiLeft;
                SwipeMultiRight = swipeMultiRight;
    
                _directionEventMap.Add(SwipeDirection.Up, SwipeUp);
                _directionEventMap.Add(SwipeDirection.Down, SwipeDown);
                _directionEventMap.Add(SwipeDirection.Left, SwipeLeft);
                _directionEventMap.Add(SwipeDirection.Right, SwipeRight);
                _directionEventMap.Add(SwipeDirection.MultiUp, SwipeMultiUp);
                _directionEventMap.Add(SwipeDirection.MultiDown, SwipeMultiDown);
                _directionEventMap.Add(SwipeDirection.MultiLeft, SwipeMultiLeft);
                _directionEventMap.Add(SwipeDirection.MultiRight, SwipeMultiRight);
            }
    
            public void ProcessSwipeEvent(SwipeDirection swipeDirection)
            {
                if (false == Enum.IsDefined(typeof(SwipeDirection), swipeDirection))
                {
                    throw new Exception("Event Not defined");
                }
    
                _directionCache.Add(swipeDirection);
    
                if (_directionCache.Count == maxFrameCache)
                {
                    var averageSwipeDirection = GetAverageSwipeDirection();
                    Action swipeEvent = _directionEventMap[averageSwipeDirection];
    
                    if (null != swipeEvent)
                    {
                        swipeEvent();
                    }
    
                    ClearDirectionCache();
                }
    
            }
    
            public SwipeDirection GetAverageSwipeDirection()
            {
                return _directionCache.GroupBy(x => x)
                         .Select(directionGroup => new
                         {
                             directionGroup.Key,
                             Count = directionGroup.Count()
                         }).OrderByDescending(x => x.Count)
                         .FirstOrDefault().Key;
            }
    
            public void ClearDirectionCache()
            {
                _directionCache.Clear();
            }
    
            public enum SwipeDirection
            {
                Up,
                Right,
                Down,
                Left,
                MultiUp,
                MultiRight,
                MultiDown,
                MultiLeft,
            }
    
            public void UpdateSwipe()
            {
                var horizontal = CrossPlatformInputManager.GetAxis(_horizontalAxisName);
                var vertical = CrossPlatformInputManager.GetAxis(_verticalAxisName);
    
                //No Touch Occured
                if (vertical == 0 && horizontal == 0)
                {
                    return;
                }
    
                if (Input.touchCount > 1)
                {
    
                }
    
                //If they swipe at exactly a 45 register as horizontal so atleast we registered a hit
                if (Mathf.Abs(horizontal) >= Mathf.Abs(vertical))
                {
                    HandleHorizontalMovement(horizontal);
                }
                else
                {
                    HandleVerticalMovement(vertical);
                }
            }
    
            protected void HandleVerticalMovement(float vertical)
            {
                if (vertical > 0)
                {
                    ProcessSwipeEvent(SwipeDirection.Up);
                }
                else
                {
                    ProcessSwipeEvent(SwipeDirection.Down);
                }
            }
    
            protected void HandleHorizontalMovement(float horizontal)
            {
                if (horizontal > 0)
                {
                    ProcessSwipeEvent(SwipeDirection.Right);
                }
                else
                {
                    ProcessSwipeEvent(SwipeDirection.Left);
                }
            }
    
            protected void HandleDepthMovement(float horizontal, float vertical)
            {
                //establish the most prodiment direction
                if (Mathf.Abs(horizontal) >= Mathf.Abs(vertical))
                {
                    if (horizontal > 0)
                    {
                        ProcessSwipeEvent(SwipeDirection.MultiRight);
                    }
                    else if (horizontal < 0)
                    {
                        ProcessSwipeEvent(SwipeDirection.MultiLeft);
                    }
                }
                else
                {
                    if (vertical > 0)
                    {
                        ProcessSwipeEvent(SwipeDirection.MultiUp);
                    }
                    else if (vertical < 0)
                    {
                        ProcessSwipeEvent(SwipeDirection.MultiDown);
                    }
                }
            }
        }
    }
    

    使用它看起来像这样:

        var touchPad = transform.parent.Find(TOUCH_PAD_PATH);
        _touchPad = touchPad.GetComponent<TouchPad>();
    
        _touchPad.InitializeTouchPadCoordinator(GameHelper.InputAxisName.TouchHorizontal.ToString(), GameHelper.InputAxisName.TouchHorizontal.ToString(),
                                                 SwipeUpEvent, SwipeRightEvent, SwipeDownEvent, SwipeLeftEvent);
    

    请注意,SwipeEvent 是在调用该滑动时将执行的操作。

    请注意,由于我尚未移植到移动设备,因此尚未对多次滑动事件进行测试,因此使用风险自负。我会在我在移动设备上测试我的游戏后更新此内容

    【讨论】:

      猜你喜欢
      • 2011-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多