unity使用input system实现相机屏幕手势丝滑拖拽

input action设置

操作对象设置

camera

具体操作类

PlayerInputView类

csharp 复制代码
using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;
using TouchPhase = UnityEngine.InputSystem.TouchPhase;

public class FingerScale : MonoBehaviour
{
    private Vector3 _offset;
    [SerializeField] private Camera mainCamera;
    private Vector2 _firstTouchPosition;
    private Vector2 _firstTouchStartPosition;
    private Vector3 _firstTouchStartPositionToWorld;
    private Vector2 _secondTouchPosition;
    private Vector2 _secondTouchStartPosition;

    public void OnFirstTouch(InputAction.CallbackContext context)
    {
        Debug.Log("OnFirstTouch"+context.phase);
        _firstTouchStartPosition = context.ReadValue<Vector2>();
        _firstTouchStartPositionToWorld = mainCamera.ScreenToWorldPoint(_firstTouchStartPosition);
       
    }

    public void OnTap(InputAction.CallbackContext context)
    {
        if (context.performed)
        {
            Vector3 worldPosition = new Vector3(_firstTouchStartPositionToWorld.x, 
                _firstTouchStartPositionToWorld.y, -20f);
            StartCoroutine(MoveSmooth(worldPosition));
        }
    }

    public void OnFirstPosition(InputAction.CallbackContext context)
    {
        _firstTouchPosition = context.ReadValue<Vector2>();
        Debug.Log("onFirstPosition"+context.phase);
    }

    public void OnFirstMove(InputAction.CallbackContext context)
    {
        if (context.performed)
        {
           _offset = mainCamera.ScreenToWorldPoint(_firstTouchPosition)-_firstTouchStartPositionToWorld;
           Debug.Log("_offset"+_offset);
            mainCamera.transform.position -= _offset;
        }
    }

    
    IEnumerator MoveSmooth(Vector3 targetPosition)
    {
        Vector3 start = mainCamera.transform.position;
        Vector3 speed = Vector3.zero;
        while (Vector3.Distance(start, targetPosition) > 0.001f)
        {
            mainCamera.transform.position = Vector3.SmoothDamp(start, targetPosition, ref speed, 0.3f);
            start = mainCamera.transform.position;
            yield return new WaitForEndOfFrame();
        }
        mainCamera.transform.position = targetPosition;
    }
    
}

出现的问题相机位置变化后通过screenToWorldPoint获取的位置和上一帧的位置,坐标系完全不一样

如何解决:改变相机位置后再通过screentoworldpoint 修改上一帧的位置,实现丝滑拖拽

新解决:根本不需要更新lastframpos ,只需每次触发更新当前位置就可以了。因为改变相机位置后再通过screentoworldpoint 修改上一帧的位置,这一计算的结果在每一帧都一样,都是初始点击的位置。想想也确实如此。因为实现丝滑的拖拽就是要让屏幕触摸的位置相对与地图来说完全不变。在第一次接触时获取这个lastframepos的值就可以了。

ps;使用了近10多个小时才解决,不过收获颇丰。不过在input action中仍存在优化空间一个是状态机优化,一个是input action接收端接受过于冗余不利于扩展

相关推荐
Kapaseker1 小时前
Compose 进阶—巧用 GraphicsLayer
android·kotlin
黄林晴2 小时前
Android17 为什么重写 MessageQueue
android
阿巴斯甜1 天前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker1 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95271 天前
Andorid Google 登录接入文档
android
黄林晴1 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab2 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android