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

相关推荐
萧雾宇1 小时前
Android Compose打造仿现实逼真的烟花特效
android·flutter·kotlin
翻滚丷大头鱼1 小时前
android 性能优化—ANR
android·性能优化
翻滚丷大头鱼1 小时前
android 性能优化—内存泄漏,内存溢出OOM
android·性能优化
拜无忧2 小时前
【教程】flutter常用知识点总结-针对小白
android·flutter·android studio
地狱为王3 小时前
在Unity中实现DTLN-AEC处理音频文件的功能
unity·aec·降噪
拜无忧3 小时前
【教程】Flutter 高性能项目架构创建指南:从入门到高性能架构
android·flutter·android studio
用户2018792831673 小时前
故事:公司的 "私人储物柜" 系统(ThreadLocalMap)
android·java
CYRUS_STUDIO3 小时前
如何防止 so 文件被轻松逆向?精准控制符号导出 + JNI 动态注册
android·c++·安全
yinmaisoft3 小时前
当低代码遇上AI,有趣,实在有趣
android·人工智能·低代码·开发工具·rxjava
如此风景4 小时前
Compose Modifier 修饰符介绍
android