最近在弄AI,调试程序的时候总是要调整摄像机的视角。灰常不爽然后自己写了个脚本。比较习惯Scene窗口下的摄像机操作所以就仿造了一个一样的操作脚本。

首相我们要知道Scene下的摄像机的操作方式

1.WASD分别控制前后左右的位移,注意:位移是已当前视角为基准的。

2.QE分别控制上下,注意:这个是针对世界坐标的。

3.鼠标右键控制自由视角旋转。(难点)

对于第一条来说,主要的问题就是现在玩家朝向问题。我怎么知道我面向哪里。

  1. Vector3 Face = transform.rotation * Vector3.forward;
  2. Face = Face.normalized;

这段代码就是玩家的朝向,把目前玩家的旋转角度乘上向量的前方,就是玩家的面朝方向,因为我们就要方向,所以单位向量化了。

下面就是关于第一条的控制方式。

  1. Vector3 Face = transform.rotation * Vector3.forward;
  2. Face = Face.normalized;
  3.  
  4. Vector3 Left = transform.rotation * Vector3.left;
  5. Left = Left.normalized;
  6.  
  7. Vector3 Right = transform.rotation * Vector3.right;
  8. Right = Right.normalized;
  9.  
  10. if (Input.GetKey("w"))
  11. {
  12. transform.position += Face * Speed * Time.deltaTime;
  13. }
  14.  
  15. if (Input.GetKey("a"))
  16. {
  17. transform.position += Left * Speed * Time.deltaTime;
  18. }
  19.  
  20. if (Input.GetKey("d"))
  21. {
  22. transform.position += Right * Speed * Time.deltaTime;
  23. }
  24.  
  25. if (Input.GetKey("s"))
  26. {
  27. transform.position -= Face * Speed * Time.deltaTime;
  28. }

第二条就不用多说了吧。上代码

  1. if (Input.GetKey("q"))
  2. {
  3. transform.position -= Vector3.up * Speed * Time.deltaTime;
  4. }
  5.  
  6. if (Input.GetKey("e"))
  7. {
  8. transform.position += Vector3.up * Speed * Time.deltaTime;
  9. }

最难的第三条。心思了半天有两种解决方法,但都有缺陷

1)统一转换成Vector来计算

2)统一转换成Quaternion来计算

优缺点:

1)旋转时有卡顿不流畅,但是到位快

2)旋转时比第一种流畅一些也有些许卡顿,但到位不快甚至不到位。

对于这两种方式,主要的思路都是取鼠标滑动的单位向量然后乘以速度。

这两种都设计到一个比较坑爹的问题。

鼠标向上下滑动时:

针对鼠标来说是y轴加减

针对rotation来说是x轴减加

同理鼠标左右滑动时:

针对鼠标来说是x轴减加

针对rotation来说是y轴减加

所以这段代码就很重要

  1. //_Rot是物体当前rotation值,MovePos是修改的值,最后得旋转后的值
  2. _Rot.x -= MovePos.y * ; //*2是可以调节的速度,越大越快
  3. _Rot.y += MovePos.x * ;
  4. _Rot.z += MovePos.z *

然后对于第一种方式全部变为Vector处理我们就会用到Transform.eulerAngles;

代码为

  1. Vector3 Save = Input.mousePosition;
  2. Vector3 MovePos = Save - MouseDownPos;
  3. MovePos = MovePos.normalized;
  4. Vector3 _Rot = transform.rotation.eulerAngles;
  5. _Rot.x -= MovePos.y * ;
  6. _Rot.y += MovePos.x * ;
  7. _Rot.z += MovePos.z * ;
  8. transform.eulerAngles = _Rot;
  9. Debug.Log(MovePos);
  10. MouseDownPos = Save;

对于第二种方式全部变为Quaternion处理我们用Quaternion.Slerp

代码为

  1. Vector3 Save = Input.mousePosition;
  2. Vector3 MovePos = Save - MouseDownPos;
  3. MovePos = MovePos.normalized;
  4. Vector3 _Rot = transform.rotation.eulerAngles;
  5. _Rot.x -= MovePos.y * ;
  6. _Rot.y += MovePos.x * ;
  7. _Rot.z += MovePos.z * ;
  8. Quaternion MoveRot = Quaternion.Euler(_Rot);
  9. transform.rotation = Quaternion.Slerp(transform.rotation, MoveRot, Time.deltaTime * );
  10. MouseDownPos = Save;

最后给完整的Update代码

  1. private float Speed = ;
  2. private Vector3 MouseDownPos;
  3.  
  4. void Update ()
  5. {
  6. Vector3 Face = transform.rotation * Vector3.forward;
  7. Face = Face.normalized;
  8.  
  9. Vector3 Left = transform.rotation * Vector3.left;
  10. Left = Left.normalized;
  11.  
  12. Vector3 Right = transform.rotation * Vector3.right;
  13. Right = Right.normalized;
  14.  
  15. //Debug.Log(transform.rotation * Vector3.forward + "," + transform.rotation * Vector3.left + "," + transform.rotation * Vector3.right);
  16.  
  17. if (Input.GetMouseButtonDown())
  18. {
  19. MouseDownPos = Input.mousePosition;
  20. }
  21.  
  22. if (Input.GetMouseButton())
  23. {
  24. //Vector处理
  25. Vector3 Save = Input.mousePosition;
  26. Vector3 MovePos = Save - MouseDownPos;
  27. MovePos = MovePos.normalized;
  28. Vector3 _Rot = transform.rotation.eulerAngles;
  29. _Rot.x -= MovePos.y * ;
  30. _Rot.y += MovePos.x * ;
  31. _Rot.z += MovePos.z * ;
  32. transform.eulerAngles = _Rot;
  33. Debug.Log(MovePos);
  34. MouseDownPos = Save;
  35.  
  36. //Quaternion处理
  37. //Vector3 Save = Input.mousePosition;
  38. //Vector3 MovePos = Save - MouseDownPos;
  39. //MovePos = MovePos.normalized;
  40. //Vector3 _Rot = transform.rotation.eulerAngles;
  41. //_Rot.x -= MovePos.y * 2;
  42. //_Rot.y += MovePos.x * 2;
  43. //_Rot.z += MovePos.z * 2;
  44. //Quaternion MoveRot = Quaternion.Euler(_Rot);
  45. //transform.rotation = Quaternion.Slerp(transform.rotation, MoveRot, Time.deltaTime * 30);
  46. //MouseDownPos = Save;
  47. }
  48.  
  49. if (Input.GetKey("w"))
  50. {
  51. transform.position += Face * Speed * Time.deltaTime;
  52. }
  53.  
  54. if (Input.GetKey("a"))
  55. {
  56. transform.position += Left * Speed * Time.deltaTime;
  57. }
  58.  
  59. if (Input.GetKey("d"))
  60. {
  61. transform.position += Right * Speed * Time.deltaTime;
  62. }
  63.  
  64. if (Input.GetKey("s"))
  65. {
  66. transform.position -= Face * Speed * Time.deltaTime;
  67. }
  68.  
  69. if (Input.GetKey("q"))
  70. {
  71. transform.position -= Vector3.up * Speed * Time.deltaTime;
  72. }
  73.  
  74. if (Input.GetKey("e"))
  75. {
  76. transform.position += Vector3.up * Speed * Time.deltaTime;
  77. }
  78.  
  79. }

Unity Game窗口中还原Scene窗口摄像机操作的更多相关文章

  1. Unity Game窗口中还原Scene窗口摄像机操作 强化版

    之前写的那个版本看来真的是不行啊.最近研究了一下官方第一人称脚本,人家的平滑过渡真的是没得说.借鉴了一下,写出来了一个新的比较完美的控制. 之前我们的操作是通过鼠标输入的开始坐标和转动坐标.其实官方有 ...

  2. C#在父窗口中调用子窗口的过程(无法访问已释放的对象)异常,不存在从对象类型System.Windows.Forms.DateTimePicker到已知的托管提供程序本机类型的映射。

    一:C#在父窗口中调用子窗口的过程(无法访问已释放的对象)异常 其实,这个问题与C#的垃圾回收有关.垃圾回收器管 理所有的托管对象,所有需要托管数据的.NET语言(包括 C#)都受运行库的 垃圾回收器 ...

  3. (转)C#在父窗口中调用子窗口的过程(无法访问已释放的对象)

    C#在父窗口中调用子窗口的过程: 1. 创建子窗口对象 2. 显示子窗口对象   笔者的程序中,主窗体MainFrm通过菜单调用子窗口ChildFrm.在窗体中定义了子窗口对象,然后在菜单项点击事件中 ...

  4. Wpf窗口中打开WinForm窗口

    获取wpf窗口对应的句柄窗口 using System; using System.Windows; using System.Windows.Interop; using IWin32Window ...

  5. C# A窗口内容显示在B窗口中的方法

    HeScripts script = new HeScripts(); //A窗口中实例化B窗口 string okscripts = "test"; //设置字段内容 scrip ...

  6. C#中关闭子窗口而不释放子窗口对象的方法

    1 在主窗口中实例化子窗口 在主窗口中实例化子窗口,而不是在按钮中实例化子窗口对象. Form2 f2 = new Form2(); 2 通过按钮来显示主窗口 在按钮中需要实现的是窗口的显示 priv ...

  7. 在SOUI中非半透明窗口如何实现圆角窗口?

    如果SOUI的宿主窗口没有包含子窗口,直接使用窗口的半透明属性:translucent=1就可以解决了,整个窗口形状完全由背景图决定,可以实现完美的圆角. 然后窗口半透明时,窗口中的子窗口(非SWin ...

  8. jQuery 获取父窗口的元素 父窗口 子窗口(iframe)

    $("#父窗口元素ID",window.parent.document); 对应javascript版本为window.parent.document.getElementById ...

  9. C#关闭子窗口而不释放子窗口对象的问题解决

    在网上找来一些方式,感觉还都不错,下面给出方式: 在线扫描相机的调试过程中,需要开辟调试界面来进行位置的配置.调试结束后,一种常用的方式是将调试参数保存并在下次启动时加载.另一种简单方式是直接使用该参 ...

随机推荐

  1. Android 热修复技术(1)---原理

    热修复技术分为几部分: 原理介绍 Android HotFix源码分析 自定义框架 1.Android分包MultiDex原理 首先Dex是什么东西? Dex就是Window里面的exe文件 也就是可 ...

  2. 拯救你的文档 – 【DevOps敏捷开发动手实验】开源文档发布

    今天上海的天气真是不错,风和日丽.再次来到微软上海紫竹研发中心,心情很是愉快,喜欢这里的大草坪,喜欢这里的工程气氛,更喜欢今天来陪我的小伙伴们. 这次动手实验培训与以往最大的不同就是采用了开源文档的方 ...

  3. vmstat命令

    vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存.进程.CPU活动进行监控.他是对系统的整体情况进行统计,不足之处是无法对某个进程进行深 ...

  4. FusionCharts参数说明 (中文)

    FushionCharts是把抽象数据图示化的套件,使用方便,配置简单.其相关参数中文说明如下. FusionCharts Free中文开发指南第二版.pdf 功能特性 animation       ...

  5. echo命令详解

    echo: echo [-neE] [arg ...] echo会将输入的字符串送往标准输出.输出的字符串间以空白字符隔开, 并在最后加上换行号. Options: -n 不在最后自动换行 -e 使用 ...

  6. maven核心,pom.xml详解(转)

    什么是pom?    pom作为项目对象模型.通过xml表示maven项目,使用pom.xml来实现.主要描述了项目:包括配置文件:开发者需要遵循的规则,缺陷管理系统,组织和licenses,项目的u ...

  7. makefile 学习笔记

    1/ 编写简单makefile test_out: test.o g++ test.o -o test_out test.o: test.cpp test.h g++ -c test.cpp test ...

  8. 你不知道的Javascript(上卷)读书笔记之二 ---- 词法作用域

    在前一篇文章中,我们把作用域定义为"管理.维护变量的一套规则",接下来是时候来深入讨论一下Js的作用域问题了,首先我们要知道作用域一般有两种主要的工作类型,一种是词法作用域,一种是 ...

  9. ThreadLocal

    package cn.happy.util; import org.hibernate.Session;import org.hibernate.SessionFactory;import org.h ...

  10. HTML 学习笔记 JavaScript (String)

    String对象用于存储字符串的数据.这里我们做了JavaScript的String字符串对象常用操作总结. 创建String对象的方式 声明:String 对象的方法也可以在所有基本字符串值中访问到 ...