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 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity3d C# 实现纯鼠标平滑控制场景摄像头(相机)实现自由旋转、移动和围绕节点移动旋转等功能(含源码工程) -> 正文阅读

[游戏开发]Unity3d C# 实现纯鼠标平滑控制场景摄像头(相机)实现自由旋转、移动和围绕节点移动旋转等功能(含源码工程)

前言

在很多情况下我们都会用到如题的功能,在一般情况下我们可以漫游场景,自由的在场景中移动旋转等,而特殊情况下我们会进行围绕某一物体查看的操作。之前的实现一般都是按需求来实现,现在做了一些整理和优化,并将实现方法和过程分享出来。

效果

漫游效果

前进后退效果:
在这里插入图片描述

上下左右移动:
在这里插入图片描述

旋转效果:
在这里插入图片描述

围绕节点效果

围绕Cube前后移动:
在这里插入图片描述

围绕Cube旋转:
在这里插入图片描述

围绕胶囊前后移动:
在这里插入图片描述

围绕胶囊旋转:

在这里插入图片描述

实现过程

交互效果的触发就是鼠标的事件,这里我们用了右键、中键和滚轮等。主要函数如下:

Input.GetMouseButton(1);//右键
Input.GetMouseButton(2); //中键
Input.GetAxis("Mouse ScrollWheel");//滚轮

根据如上的事件进行摄像头参数的修改即可实现控制的功能,但是如果要实现平滑的效果,就需要进行插值,让它有个平滑的过渡。

功能范围

首先对旋转和移动等功能块设定开关,方便在某些情况下需要不可移动和旋转时,可以设置开关实现,
对移动位置范围进行限制,防止自由移动时跑出场景;对旋转范围进行限制,上下范围限制住不至于出现多次翻转等情况;锁定查看节点时,限制查看距离等,防止穿模查看模型;其它参数可限制,如移动速度、旋转速度,和插值系数等。
右键控制旋转,中键上下左右移动,滚轮进行前后移动。

搭建场景

在这里插入图片描述

如上图,进行几个简单模型搭建,方便查看效果控制效果。

编码实现

变量设置

//是否可控制属性,用于脚本移动摄像头时,不受鼠标控制
    public bool IsUseCtrl
    { 
        set
        {
            if (value)
                ResetCtrl();
            isUseCtrl = value;
        }
        get
        {
            return isUseCtrl;
        }
    }
    bool isUseCtrl = true;
    [Header("是否限制移动范围")]
    public bool IsLimitPos = true;
    [Header("是否可移动")]
    public bool IsMove = true;
    [Header("是否可旋转")]
    public bool IsRot = true;
    [Header("镜头位置范围限制")]
    public float PosMinX = -2;
    public float PosMaxX = 2, PosMinY = 1, PosMaxY = 6, PosMinZ = -2, PosMaxZ = 2;

    [Header("镜头前后移动速度")]
    public float HBMoveSpeed = 20;

    [Header("镜头左右移动速度")]
    public float LRMoveSpeed = 1f;

    [Header("镜头上下旋转限制")]
    public float RotMinX = -45.0f;
    public float RotMaxX = 45.0f;

    [Header("镜头旋转速度")]
    public float XRotSpeed = 2f;
    public float YRotSpeed = 2f;

    [Header("围绕的对象")]
    public Transform LookAtTran = null;
    [Header("距离配置")]
    public float LookMinDis = 2;
    public float LookMaxDis = 20;

自由漫游

在无观察节点时,自动在自由漫游状态下。

滚轮控制前进后退:

if (IsMove && Input.GetAxis("Mouse ScrollWheel") != 0)
    tdirz += Input.GetAxis("Mouse ScrollWheel") * HBMoveSpeed;
dirz = Mathf.SmoothDamp(dirz, tdirz, ref zVel, 0.5f);

采集滚轮消息后,先对目标值进行更新,然后进行插值。

中键平移操作:

  if (IsMove && Input.GetMouseButton(2))
  {
       tdirx += Input.GetAxis("Mouse X") * -LRMoveSpeed;
       tdiry += Input.GetAxis("Mouse Y") * -LRMoveSpeed;
}
  dirx = Mathf.SmoothDamp(dirx, tdirx, ref xVel, 0.3f);
  diry = Mathf.SmoothDamp(diry, tdiry, ref yVel, 0.3f);

右键旋转操作:


 if (IsRot && Input.GetMouseButton(1))
{
      troty += Input.GetAxis("Mouse X") * XRotSpeed;
      trotx -= Input.GetAxis("Mouse Y") * YRotSpeed;
      trotx = CutAngle(trotx, RotMinX, RotMaxX);
  }
rotx = Mathf.SmoothDampAngle(rotx, trotx, ref RxVel, 0.3f);
roty = Mathf.SmoothDampAngle(roty, troty, ref RyVel, 0.3f);

最后进行位置和旋转的更新:

 Quaternion rotation = Quaternion.Euler(rotx, roty, 0);
 Vector3 tpos = transform.position + rotation * new Vector3(tdirx - dirx, tdiry - diry, tdirz - dirz);
 if (IsLimitPos)
 {
    if (CheckPos(tpos))
         transform.position = tpos;
    else{
                    dirx = tdirx;
                    diry = tdiry;
                    dirz = tdirz;
     }
  }
   else
     transform.position = tpos;
 transform.rotation = rotation;

观察节点

这部分和自由漫游基本类似,不过少了上下左右移动,而且位置的计算是根据观察节点来进行计算的。

   //滚轮控制前进后退
   if (IsMove && Input.GetAxis("Mouse ScrollWheel") != 0)
   {
       tdis -= Input.GetAxis("Mouse ScrollWheel") * HBMoveSpeed;
       tdis = Mathf.Clamp(tdis, LookMinDis, LookMaxDis);
   }
   dis = Mathf.SmoothDamp(dis, tdis, ref zVel, 0.5f);


   if (IsRot && Input.GetMouseButton(1)) //鼠标右键
   {
      troty += Input.GetAxis("Mouse X") * XRotSpeed;
      trotx -= Input.GetAxis("Mouse Y") * YRotSpeed;
      trotx = CutAngle(trotx, RotMinX, RotMaxX);
   }
    rotx = Mathf.SmoothDampAngle(rotx, trotx, ref RxVel, 0.3f);
   roty = Mathf.SmoothDampAngle(roty, troty, ref RyVel, 0.3f);
   Quaternion rotation = Quaternion.Euler(rotx, roty, 0);
   Vector3 position = rotation * new Vector3(0.0f, 0.0f, -dis) + LookAtTran.position;
   transform.rotation = rotation;
   transform.position = position;

功能使用

配置位置范围:

在这里插入图片描述

开关配置:
在这里插入图片描述

观察的节点配置:

在这里插入图片描述

按上图,将观察的节点拖入或者设置即可。

其它:
在这里插入图片描述

项目工程

https://download.csdn.net/download/qq_33789001/25952768
如果无效,说明审核未通过。

瑕疵

在旋转快结束时,程序会出现一个掉帧的情况:
在这里插入图片描述

如上图,在旋转快结束时有个明显的掉帧,目前没找到问题,如果有知道的可以麻烦=指点一下

  游戏开发 最新文章
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-09-30 12:15:25  更:2021-09-30 12:15:33 
 
开发: 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年11日历 -2024/11/28 3:26:38-

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