IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity小实用八-使用input system进行单指/双指的手势操作 -> 正文阅读

[游戏开发]Unity小实用八-使用input system进行单指/双指的手势操作

1、在package manager中先安装Input system 包。

2、安装完成之后,创建input action。创建单手指操作,创建一个获取单手指位置的action,一个获取单手指交互的action。

3、创建双手指的操作,创建一个获取第一个手指位置的action,一个获取第二个手指位置的action,一个获取第二个手指交互的action。

4、创建InputManager.cs脚本,用来管理所有的操作信息。

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;

[DefaultExecutionOrder(-1)]
public class InputManager : MonoBehaviourSingleton<InputManager>
{
    public Action<Vector2, Vector2> pinchStarted;
    public Action<Vector2, Vector2> pinchChanged;
    public Action<Vector2, Vector2> pinchEnd;

    public Action<Vector2, float> swipeStarted;
    public Action<Vector2, float> swipeChanged;
    public Action<Vector2, float> swipeEnd;

    private InputControls _inputControl;
    private Coroutine _swipeCoroutine;
    private Coroutine _pinchCoroutine;

    private void Awake()
    {
        _inputControl = new InputControls();
    }

    private void OnEnable()
    {
        _inputControl.Enable();
    }

    private void OnDisable()
    {
        _inputControl.Disable();
    }

    // Start is called before the first frame update
    void Start()
    {
        _inputControl.Touch.SecondaryTouchContact.started += _ => PinchStart();
        _inputControl.Touch.SecondaryTouchContact.canceled += _ => PinchEnd();

        _inputControl.Touch.PrimaryContact.started += SwipeStart;
        _inputControl.Touch.PrimaryContact.canceled += SwipeEnd;
    }

    private void SwipeStart(InputAction.CallbackContext ctx)
    {
        swipeStarted?.Invoke(_inputControl.Touch.PrimaryPosition.ReadValue<Vector2>(), (float)ctx.startTime);
        _swipeCoroutine = StartCoroutine(SwipeDetection(ctx));
    }

    private void SwipeEnd(InputAction.CallbackContext ctx)
    {
        swipeEnd?.Invoke(_inputControl.Touch.PrimaryPosition.ReadValue<Vector2>(), (float)ctx.time);
        StopCoroutine(_swipeCoroutine);
    }

    IEnumerator SwipeDetection(InputAction.CallbackContext ctx)
    {
        while (true)
        {
            if (Input.touchCount > 1)
            {
                break;
            }

            swipeChanged?.Invoke(_inputControl.Touch.PrimaryPosition.ReadValue<Vector2>(), (float)ctx.time);

            yield return null;
        }
    }

    private void PinchStart()
    {
        pinchStarted?.Invoke(_inputControl.Touch.PrimaryFingerPosition.ReadValue<Vector2>(), _inputControl.Touch.SecondaryFingerPosition.ReadValue<Vector2>());
        _pinchCoroutine = StartCoroutine(PinchDetection());
    }

    private void PinchEnd()
    {
        pinchEnd?.Invoke(_inputControl.Touch.PrimaryFingerPosition.ReadValue<Vector2>(), _inputControl.Touch.SecondaryFingerPosition.ReadValue<Vector2>());
        StopCoroutine(_pinchCoroutine);
    }

    IEnumerator PinchDetection()
    {
        while (true)
        {
            if(Input.touchCount == 2)
            {
                pinchChanged?.Invoke(_inputControl.Touch.PrimaryFingerPosition.ReadValue<Vector2>(), _inputControl.Touch.SecondaryFingerPosition.ReadValue<Vector2>());
            }

            yield return null;
        }
    }
}

5、在InputManger中,所有的手指触发操作都会有回调,创建单手指滑动的操作,让相机沿着正方体进行旋转。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SwipeDetection : MonoBehaviour
{
    [SerializeField]
    private Camera mainCamera;
    [SerializeField]
    private float minDistance = 4f;
    [SerializeField]
    float sensitivity = 20f;
    [SerializeField]
    private GameObject targetAnchor;

    private InputManager _inputManager;
    private float _startTime;
    private float _endTime;
    private Vector2 _startPosition;
    private Vector2 _endPosition;
    private Vector2 _previousPosition;

    private void Awake()
    {
        _inputManager = InputManager.Instance;
    }

    private void OnEnable()
    {
        _inputManager.swipeStarted += OnSwipeStarted;
        _inputManager.swipeEnd += OnSwipeEnd;
        _inputManager.swipeChanged += OnSwipeChanged;
    }

    private void OnDisable()
    {
        _inputManager.swipeStarted -= OnSwipeStarted;
        _inputManager.swipeEnd -= OnSwipeEnd;
        _inputManager.swipeChanged -= OnSwipeChanged;
    }

    private void OnSwipeStarted(Vector2 position, float time)
    {
        _startPosition = position;
        _previousPosition = position;
        _startTime = time;
    }

    private void OnSwipeEnd(Vector2 position, float time)
    {
        _endPosition = position;
        _endTime = time;

        Debug.DrawLine(_startPosition, _endPosition, Color.red, 5f);
    }

    private void OnSwipeChanged(Vector2 position, float time)
    {
        Vector2 curPosition = position;

        if(Vector2.Distance(curPosition, _previousPosition) < minDistance)
        {
            return;
        }

        float angle = Vector2.Angle(curPosition - _startPosition, Vector2.up);

        if(angle > 45.0 && angle < 135.0)
        {
            float x = (curPosition.x - _previousPosition.x) / Screen.width * sensitivity;
            mainCamera.transform.RotateAround(targetAnchor.transform.position, Vector3.up, x);
        } else
        {
            float y = (curPosition.y - _previousPosition.y) / Screen.height * sensitivity;
            mainCamera.transform.RotateAround(targetAnchor.transform.position, transform.right, -y);
        }

        _previousPosition = curPosition;
    }
}

6、Unity提供了RotateAround(targetAnchor.transform.position, Vector3.up, x);函数可以沿着某个物体旋转。我们也可以自己实现这个函数。

void MyRotateAround(Vector3 center, Vector3 axis, float angle)
 {
        Vector3 pos = transform.position;
        Quaternion rot = Quaternion.AngleAxis(angle, axis);
        Vector3 dir = pos - center; //计算从圆心指向摄像头的朝向向量
        dir = rot * dir;            //旋转此向量
        transform.position = center + dir;//移动摄像机位置
        var myrot = transform.rotation;
        //transform.rotation *= Quaternion.Inverse(myrot) * rot *myrot;//设置角度另一种方法
        transform.rotation = rot * myrot; //设置角度
 }

7、双手指操作,相机沿着正方体的方向进行拉近拉远的操作。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PinchDetection : MonoBehaviour
{
    [SerializeField]
    private Camera mainCamera;
    [SerializeField]
    private float cameraSpeed = 4f;
    [SerializeField]
    private GameObject targetAnchor;

    private InputManager _inputManager;
    private float _previousDistance;

    private void Awake()
    {
        _inputManager = InputManager.Instance;
    }

    private void OnEnable()
    {
        _inputManager.pinchStarted += OnPinchStarted;
        _inputManager.pinchChanged += OnPinchChanged;
    }

    private void OnDisable()
    {
        _inputManager.pinchStarted -= OnPinchStarted;
        _inputManager.pinchChanged -= OnPinchChanged;
    }

    public void OnPinchStarted(Vector2 position1, Vector2 position2)
    {
        _previousDistance = Vector2.Distance(position1, position2);
    }

    public void OnPinchChanged(Vector2 position1, Vector2 position2)
    {
        float distance = Vector2.Distance(position1, position2);
        if (distance > _previousDistance)
        {
            Vector3 forward = targetAnchor.transform.position - mainCamera.transform.position;

            mainCamera.transform.Translate(forward.normalized * Time.deltaTime * cameraSpeed, Space.World);
        }
        else
        {
            Vector3 forward = mainCamera.transform.position - targetAnchor.transform.position;

            mainCamera.transform.Translate(forward.normalized * Time.deltaTime * cameraSpeed, Space.World);
        }

        _previousDistance = distance;
    }
}

8、脚本都已经就位,我们就在Unity操作界面上进行绑定。

9、在PC端我们先调试一下单手指的操作。

10、最后在手机上展示一下我们的成功。

案例下载地址:

https://download.csdn.net/download/grace_yi/20559035?spm=1001.2014.3001.5501

参考文献:

https://www.cnblogs.com/tangzhenqiang/p/8966882.html

https://www.cnblogs.com/lichuangblog/p/7967307.html

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 08:09:12  更:2021-07-28 08:09:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/30 20:57:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码