Unity Window触摸屏电脑和移动端Input触控,控制相机旋转缩放

2023-11-01

Unity Window触摸屏电脑和移动端Input触控,控制相机旋转缩放

  • 原理就是获取手指滑动的偏移量,来计算
  • 代码帖出来
using UnityEngine;
using System;
using System.Collections;

public class CameraController : MonoBehaviour
{
    /// <summary>
    /// 是否能旋转X轴
    /// </summary>
    public bool canRotation_X = true;
    /// <summary>
    /// 是否能旋转Y轴
    /// </summary>
    public bool canRotation_Y = true;
    /// <summary>
    /// 是否能缩放
    /// </summary>
    public bool canScale = true;

    #region 属性
    /// <summary>
    /// 相机看向的目标
    /// </summary>
    public Transform target;

    /// <summary>
    /// 鼠标按钮,指针和滚轮的设置
    /// </summary>
    public MouseSettings mouseSettings = new MouseSettings(0, 10, 10);

    /// <summary>
    /// 角度范围限制
    /// </summary>
    public Range angleRange = new Range(-90, 90);

    /// <summary>
    /// 距离极限范围
    /// </summary>
    public Range distanceRange = new Range(0, 10);

    /// <summary>
    /// 平面上的矩形区域
    /// </summary>
    public PlaneArea PlaneArea = new PlaneArea();

    /// <summary>
    /// 摄像机对准目标
    /// </summary>
    public AlignTarget AlignTarget = new AlignTarget();

    /// <summary>
    /// 阻尼器可移动和旋转的范围.
    /// </summary>
    [Range(0, 10)]
    public float damper = 5;

    /// <summary>
    /// 相机当前的角度.
    /// </summary>
    public Vector2 CurrentAngles { protected set; get; }

    /// <summary>
    /// 相机到目标的当前距离.
    /// </summary>
    public float CurrentDistance { protected set; get; }

    /// <summary>
    /// 相机目标角度.
    /// </summary>
    protected Vector2 targetAngles;

    /// <summary>
    /// 相机到目标的距离
    /// </summary>
    protected float targetDistance;
    #endregion

    #region Protected Method
    protected virtual void Start()
    {
        CurrentAngles = targetAngles = transform.eulerAngles;
        CurrentDistance = targetDistance = Vector3.Distance(transform.position, target.position);
    }

    protected virtual void LateUpdate()
    {
#if UNITY_EDITOR
                AroundByMouseInput();
#elif UNITY_STANDALONE_WIN
                AroundByMobileInput();
#elif UNITY_ANDROID || UNITY_IPHONE
                AroundByMobileInput();
#endif
    }

    //记录上一次手机触摸位置判断用户是在左放大还是缩小手势  
    private Vector2 oldPosition1;
    private Vector2 oldPosition2;

    //是否单指操作
    private bool m_IsSingleFinger;

    /// <summary>
    /// 移动端(Win平板)
    /// </summary>
    protected void AroundByMobileInput()
    {
        if (Input.touchCount == 1)
        {
            if (Input.touches[0].phase == TouchPhase.Moved)
            {
                //手机端可调用此代码(window电脑只能获取鼠标不能获取触摸板)
                targetAngles.y += Input.GetAxis("Mouse X") * mouseSettings.pointerSensitivity;
                targetAngles.x -= Input.GetAxis("Mouse Y") * mouseSettings.pointerSensitivity;

                //window电脑可获取(移动端也可以使用)
                targetAngles.y += Input.touches[0].deltaPosition.x * Time.deltaTime * 5;
                targetAngles.x -= Input.touches[0].deltaPosition.y * Time.deltaTime * 5;

                //范围
                targetAngles.x = Mathf.Clamp(targetAngles.x, angleRange.min, angleRange.max);
            }
            //鼠标指针
            m_IsSingleFinger = true;
        }

        //鼠标滚轮
        if (canScale)
        {
            if (Input.touchCount > 1)
            {

                //计算出当前两点触摸点的位置  
                if (m_IsSingleFinger)
                {
                    oldPosition1 = Input.GetTouch(0).position;
                    oldPosition2 = Input.GetTouch(1).position;
                }
                if (Input.touches[0].phase == TouchPhase.Moved && Input.touches[1].phase == TouchPhase.Moved)
                {
                    var tempPosition1 = Input.GetTouch(0).position;
                    var tempPosition2 = Input.GetTouch(1).position;

                    float currentTouchDistance = Vector3.Distance(tempPosition1, tempPosition2);
                    float lastTouchDistance = Vector3.Distance(oldPosition1, oldPosition2);

                    //计算上次和这次双指触摸之间的距离差距  
                    //然后去更改摄像机的距离  
                    targetDistance -= (currentTouchDistance - lastTouchDistance) * Time.deltaTime * mouseSettings.wheelSensitivity;
                   
                    //备份上一次触摸点的位置,用于对比  
                    oldPosition1 = tempPosition1;
                    oldPosition2 = tempPosition2;
                    m_IsSingleFinger = false;
                }
            }

        }

        targetDistance = Mathf.Clamp(targetDistance, distanceRange.min, distanceRange.max);

        //缓动
        CurrentAngles = Vector2.Lerp(CurrentAngles, targetAngles, damper * Time.deltaTime);
        CurrentDistance = Mathf.Lerp(CurrentDistance, targetDistance, damper * Time.deltaTime);


        if (!canRotation_X) targetAngles.y = 0;
        if (!canRotation_Y) targetAngles.x = 0;

        //实时位置旋转
        transform.rotation = Quaternion.Euler(CurrentAngles);
        //实时位置移动
        transform.position = target.position - transform.forward * CurrentDistance;

    }

    /// <summary>
    /// 相机通过鼠标输入围绕目标
    /// </summary>
    protected void AroundByMouseInput()
    {
        if (Input.GetMouseButton(mouseSettings.mouseButtonID))
        {
            //鼠标指针
            targetAngles.y += Input.GetAxis("Mouse X") * mouseSettings.pointerSensitivity;
            targetAngles.x -= Input.GetAxis("Mouse Y") * mouseSettings.pointerSensitivity;

            //范围
            targetAngles.x = Mathf.Clamp(targetAngles.x, angleRange.min, angleRange.max);
        }

        //鼠标滚轮
        if (canScale)
        {
            targetDistance -= Input.GetAxis("Mouse ScrollWheel") * mouseSettings.wheelSensitivity;

        }
        targetDistance = Mathf.Clamp(targetDistance, distanceRange.min, distanceRange.max);

        //缓动
        CurrentAngles = Vector2.Lerp(CurrentAngles, targetAngles, damper * Time.deltaTime);
        CurrentDistance = Mathf.Lerp(CurrentDistance, targetDistance, damper * Time.deltaTime);


        if (!canRotation_X) targetAngles.y = 0;
        if (!canRotation_Y) targetAngles.x = 0;


        //实时位置旋转
        transform.rotation = Quaternion.Euler(CurrentAngles);
        //实时位置移动
        transform.position = target.position - transform.forward * CurrentDistance;
    }
    #endregion
}

[Serializable]
public struct MouseSettings
{
    /// <summary>
    /// 鼠标按键的ID
    /// </summary>
    public int mouseButtonID;

    /// <summary>
    /// 鼠标指针的灵敏度.
    /// </summary>
    public float pointerSensitivity;

    /// <summary>
    /// 鼠标滚轮的灵敏度
    /// </summary>
    public float wheelSensitivity;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="mouseButtonID">鼠标按钮的ID</param>
    /// <param name="pointerSensitivity">鼠标指针的灵敏度</param>
    /// <param name="wheelSensitivity">鼠标滚轮的灵敏度</param>
    public MouseSettings(int mouseButtonID, float pointerSensitivity, float wheelSensitivity)
    {
        this.mouseButtonID = mouseButtonID;
        this.pointerSensitivity = pointerSensitivity;
        this.wheelSensitivity = wheelSensitivity;
    }
}

/// <summary>
/// 范围从最小到最大
/// </summary>
[Serializable]
public struct Range
{
    /// <summary>
    /// 范围的最小值
    /// </summary>
    public float min;

    /// <summary>
    /// 范围的最大值
    /// </summary>
    public float max;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="min">范围的最小值</param>
    /// <param name="max">范围的最大值</param>
    public Range(float min, float max)
    {
        this.min = min;
        this.max = max;
    }
}

/// <summary>
/// 平面上的矩形区域
/// </summary>
[Serializable]
public struct PlaneArea
{
    /// <summary>
    /// 区域中心
    /// </summary>
    public Transform center;

    /// <summary>
    /// 区域宽度
    /// </summary>
    public float width;

    /// <summary>
    /// 区域长度
    /// </summary>
    public float length;

    /// <summary>
    /// 平面区域_构造函数
    /// </summary>
    /// <param name="center">区域中心</param>
    /// <param name="width">区域宽度</param>
    /// <param name="length">区域长度</param>
    public PlaneArea(Transform center, float width, float length)
    {
        this.center = center;
        this.width = width;
        this.length = length;
    }
}

/// <summary>
/// 摄像机对准目标
/// </summary>
[Serializable]
public struct AlignTarget
{
    /// <summary>
    /// 对准目标中心
    /// </summary>
    public Transform center;

    /// <summary>
    /// 对齐角度
    /// </summary>
    public Vector2 angles;

    /// <summary>
    /// 相机到目标中心的距离
    /// </summary>
    public float distance;

    /// <summary>
    /// 角度范围限制
    /// </summary>
    public Range angleRange;

    /// <summary>
    /// 距离范围限制
    /// </summary>
    public Range distanceRange;

    /// <summary>
    /// 对准目标_构造函数
    /// </summary>
    /// <param name="center">对准目标中心</param>
    /// <param name="angles">对齐角度</param>
    /// <param name="distance">相机到目标中心的距离</param>
    /// <param name="angleRange">角度范围限制</param>
    /// <param name="distanceRange">距离范围限制</param>
    public AlignTarget(Transform center, Vector2 angles, float distance, Range angleRange, Range distanceRange)
    {
        this.center = center;
        this.angles = angles;
        this.distance = distance;
        this.angleRange = angleRange;
        this.distanceRange = distanceRange;
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity Window触摸屏电脑和移动端Input触控,控制相机旋转缩放 的相关文章

随机推荐

  • 打包3阶段-使用Enigma Virtual Box打包为独立exe程序

    一 首先了解一下Enigma Virtual Box 百科 Enigma Virtual Box是软件虚拟化工具 它可以将多个文件封装到应用程序主文件 从而制作成为单执行文件的绿色软件 它支持所有类型的文件格式 虚拟化后的软件不释放任何临时
  • C语言程序设计超详细复习总结

    C语言 注意 要了解c语言的函数库 会使用里面的函数 如math h stdlib h库 rand 函数等 计算机元素 1 机器语言 机器指令的集合 机器指令 计算机能够识别的二进制代码 2 符号语言 汇编语言 一些英文字母和数字表示一个指
  • 制作双击可以直接运行的jar包

    原文地址 http www cnblogs com ylawrence3 archive 2009 11 08 1350645 html 1 JAR 文件包 JAR 文件就是 Java Archive File 顾名思意 它的应用是与 Ja
  • Android中启动一个服务,Android服务的两种启动方式

    前言 Service是Android的四大组件之一 也是可执行的程序 服务是Android中实现程序后台运行的解决方案 非常适合去执行那些不需要和用户交互而且还要求长期运行的任务 Service的启动方式有两种 总结一下两种方式的区别 一
  • Leetcode 14 string::find / substr

    思想 利用C string find 函数的特性 暴力匹配 重要特性 substr start length 如果 length 为 0 或负数 将返回一个空字符串 string find str 匹配返回首下标 不匹配返回string n
  • Idea Sonar使用说明

    1 Sonarlint安装 1 1 Idea在线安装 1 打开idea file 文件 setting 设置 1 插件搜索sonarlint进行安装 1 2 Idea离线安装 若idea 无法下载安装该插件 在idea https plug
  • opencv(十三)--边缘检测和梯度

    目标 图像梯度 图像边界等 使用到的函数有 cv2 Sobel cv2 Schar cv2 Laplacian 等 原理 梯度简单来说就是求导 OpenCV 提供了三种不同的梯度滤波器 或者说高通滤波器 Sobel Scharr 和Lapl
  • Qt 之 QVideoFrame转换为QImage

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 方法一 最简单 方法二 依赖opencv 方法三 qt5 15版本 前言 在qt框架下 实现相机预览的几种方式在qt相机预览已经描述过了 在该文章的几种方式中
  • 二叉搜索树(数组实现)

    内容 建立二叉搜索树 bool buildtree int k tree k value a index int cur 0 if index a size return true while 1 if a index lt tree cu
  • 正整数序列的数

    正整数序列的数 正整数序列的数量 问题描述 小明想知道 满足以下条件的正整数序列的数量 1 第一项为 n 2 第二项不超过 n 3 从第三项开始 每一项小于前两项的差的绝对值 请计算 对于给定的 n 有多少种满足条件的序列 输入格式 输入一
  • Qt使用gSoap实现webservice服务端和客户端

    文章目录 gSoap工具介绍 1 下载 2 Hello world 开始使用SOAP api 2 1 新建文件夹 2 2 新建服务接口头文件 hello h 2 3 使用 soapcpp2 exe 2 4 拷贝源代码库文件 2 5 Qt 服
  • 第二次作业:微信案例分析

    2 1 介绍产品相关信息 你选择的产品是 微信 为什么选择该产品作为分析 微信是一款全方位的手机通讯应用 帮助我们轻松连接全球好友 微信可以通过SMS MMS网络发送短信 进行视频聊天 与好友一起玩游戏 以及分享自己的生活到朋友圈 让我们感
  • Stable Diffusion 个人推荐的各种模型及设置参数、扩展应用等合集(不断更新中)

    本文主要是把平时使用的模型及其参数进行推荐和整理 相关 安装及其问题解决参考 Windows安装Stable Diffusion WebUI及问题解决记录 运行使用时问题 Windows使用Stable Diffusion时遇到的各种问题整
  • Stack,ArrayDeque,LinkedList的区别

    这段时间把疯狂JAVA再看了一遍 发现Stack ArrayDeque LinkedList都可以作为栈使用 所以就稍微从性能以及实现的细节对比这三者的区别 类继承树 由继承树看出 三者都是Collection的间接实现类 ArrayDeq
  • js中数组删除对象的几种方式总结

    1 关键字删除 2 splice删除 3 特殊位置删除 一 关键字删除 关键字删除是通过js提供的关键字 delete手动删除数组的某一项 使用delete删除掉数组中的元素后 会把该下标出的值置为undefined 数组的长度不会变 ar
  • 一个案例说明高层属性形式化验证

    1 验证软件功能介绍 Beosin VaaS的业务逻辑验证软件 是一款用来检测智能合约上层业务逻辑漏洞的软件 基于合约的白皮书 软件利用形式化方法 首先对单个函数进行属性的描述 在对单个函数进行属性的验证并通过后 基于这些已验证属性 抽取出
  • 号传到服务器为空,URL 传+号到后台变空格问题解决方案

    今天在调试客户端向服务器传递参数时 参数中的 全部变成了空格 原因是URL中默认的将 号转义了 解决方法如下 方法一 修改客户端 将客户端带 的参数中的 全部替换为 2B 这样参数传到服务器端时就能得到 了 方法二 修改服务器端 将空格替换
  • 第六天作业

    include
  • VC++操作SQLserver动态库【含源码】,及动态库使用教程。

    VC 操作SQLserver动态库 含源码 动态库使用Demo程序演示 include
  • Unity Window触摸屏电脑和移动端Input触控,控制相机旋转缩放

    Unity Window触摸屏电脑和移动端Input触控 控制相机旋转缩放 原理就是获取手指滑动的偏移量 来计算 代码帖出来 using UnityEngine using System using System Collections p