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接收端接受过于冗余不利于扩展

相关推荐
恋猫de小郭15 分钟前
Kotlin 2.5 的 Companion 改造,对 KMP 的重要升级
android·前端·flutter
淡海水1 小时前
03-02-架构篇-Boehm GC架构解析
unity·架构·c#·gc·boehm
Kapaseker1 小时前
写了这么久 Kotlin,你真的理解 in、out 和 * 吗?
android·kotlin
上海锝秉工控1 小时前
相机激光传感器 三维测量更精准
数码相机
小七在进步2 小时前
C++内存管理:new/delete vs malloc/free深度解析
android·java·c++
FLJwu2 小时前
硬件器件选型实战电源篇 03:TVS 管选型踩坑复盘|盲目选大电压,静电打坏运动相机主控,客户批量退货
经验分享·数码相机·音视频·相机·运动相机
数字融合14 小时前
透明化视频孪生虚实映射一体化融合技术
人工智能·python·数码相机
geovindu15 小时前
sql:Search-Optimized SQL Queries using mysql 9.0
android·数据库·sql·mysql·数据库开发·数据库架构
知之则吱吱17 小时前
Android 开发者验证机制迎来新变化:核心要求、实施时间与开发者应对指南
android·google
墨天梦18 小时前
D09_Retrofit接口与数据转换
android·kotlin·retrofit