服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - Unity3D使用鼠标旋转缩放平移视角

Unity3D使用鼠标旋转缩放平移视角

2022-07-29 10:21肚皮朝上的刺猬 C#

这篇文章主要为大家详细介绍了Unity3D使用鼠标旋转缩放平移视角,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

Unity使用鼠标旋转缩放平移视角,供大家参考,具体内容如下

用代码在Game界面完美实现Scene界面的操作方法。

使用方法:把脚本挂在相机上,把跟踪的target拖到脚本上。

视角跟踪的是一个空物体,当然如果你是做RPG游戏需要跟踪某一角色的视角,那就不需要中键平移功能,把空物体换成角色就行。

代码主要是分三部分功能进行实现。

1.右键拖动控制视角的旋转;
2.滚轮旋转控制视角的缩放;
3.中键拖动控制视角的平移。

右键拖动控制旋转主要是用GetAxis获得鼠标在x方向与y方向平移的距离,相机的旋转是通过旋转相机本体坐标系的x轴与y轴实现的,重要的是在旋转相机的同时,要控制相机和target物体的相对距离,即同时控制相机绕target物体的旋转。这个网上多数实现都相同,不赘述

中键滚轮控制视角的缩放,定义Distance变量控制相机与target的距离(相机z轴方向的距离),用GetAxis获得滚轮旋转的程度,控制Distance的变动。这里和网上已有的方法也没什么区别。

中键拖动控制视角的平移,之前在网上查找相关的实现,结果实际效果都比较差,所以自己实现了一下。视角的平移是通过获取中键在屏幕坐标系下的平移的方向向量,然后转换为世界坐标系下的target坐标的平移,然后调整相机的位置进行相应的平移以保证旋转和缩放不受影响。

屏幕坐标系的平移转换到世界坐标系下的平移,本质上就是世界坐标系下沿着相机的本体坐标系的x与y轴进行相应的平移。所以只需要求出屏幕坐标系x与y方向的平移,分别乘以相机x与y轴的方向向量,然后与target原来的坐标相加,就可以获得target平移后的位置,再将相机的位置平移过去即实现了视角的平移,这种平移保证了相机平面和target之间的相对距离保持不变。具体代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class MouseLookTest : MonoBehaviour {
 
 //相机跟随的目标物体,一般是一个空物体
 public Transform target;
 private int MouseWheelSensitivity = 1; //滚轮灵敏度设置
 private int MouseZoomMin = 1; //相机距离最小值
 private int MouseZoomMax = 20; //相机距离最大值
 
 private float moveSpeed = 10; //相机跟随速度(中键平移时),采用平滑模式时起作用,越大则运动越平滑
 
 private float xSpeed = 250.0f; //旋转视角时相机x轴转速
 private float ySpeed = 120.0f; //旋转视角时相机y轴转速
 
 private int yMinLimit = -360;
 private int yMaxLimit = 360;
 
 private float x = 0.0f; //存储相机的euler角
 private float y = 0.0f; //存储相机的euler角
 
 private float Distance = 5; //相机和target之间的距离,因为相机的Z轴总是指向target,也就是相机z轴方向上的距离
 private Vector3 targetOnScreenPosition; //目标的屏幕坐标,第三个值为z轴距离
 private Quaternion storeRotation; //存储相机的姿态四元数
 private Vector3 CameraTargetPosition; //target的位置
 private Vector3 initPosition; //平移时用于存储平移的起点位置
 private Vector3 cameraX; //相机的x轴方向向量
 private Vector3 cameraY; //相机的y轴方向向量
 private Vector3 cameraZ; //相机的z轴方向向量
 
 private Vector3 initScreenPos; //中键刚按下时鼠标的屏幕坐标(第三个值其实没什么用)
 private Vector3 curScreenPos; //当前鼠标的屏幕坐标(第三个值其实没什么用)
 void Start () {
 //这里就是设置一下初始的相机视角以及一些其他变量,这里的x和y。。。是和下面getAxis的mouse x与mouse y对应
 var angles = transform.eulerAngles;
 x = angles.y;
 y = angles.x;
 CameraTargetPosition = target.position;
 storeRotation = Quaternion.Euler (y + 60, x, 0);
 transform.rotation = storeRotation; //设置相机姿态
 Vector3 position = storeRotation * new Vector3 (0.0F, 0.0F, -Distance) + CameraTargetPosition; //四元数表示一个旋转,四元数乘以向量相当于把向量旋转对应角度,然后加上目标物体的位置就是相机位置了
 transform.position = storeRotation * new Vector3 (0, 0, -Distance) + CameraTargetPosition; //设置相机位置
 
 // Debug.Log("Camera x: "+transform.right);
 // Debug.Log("Camera y: "+transform.up);
 // Debug.Log("Camera z: "+transform.forward);
 
 // //-------------TEST-----------------
 // testScreenToWorldPoint();
 
 }
 
 void Update () {
 //鼠标右键旋转功能
 if (Input.GetMouseButton (1)) {
 x += Input.GetAxis ("Mouse X") * xSpeed * 0.02f;
 y -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
 
 y = ClampAngle (y, yMinLimit, yMaxLimit);
 
 storeRotation = Quaternion.Euler (y + 60, x, 0);
 var position = storeRotation * new Vector3 (0.0f, 0.0f, -Distance) + CameraTargetPosition;
 
 transform.rotation = storeRotation;
 transform.position = position;
 } else if (Input.GetAxis ("Mouse ScrollWheel") != 0) //鼠标滚轮缩放功能
 {
 if (Distance >= MouseZoomMin && Distance <= MouseZoomMax) {
 Distance -= Input.GetAxis ("Mouse ScrollWheel") * MouseWheelSensitivity;
 }
 if (Distance < MouseZoomMin) {
 Distance = MouseZoomMin;
 }
 if (Distance > MouseZoomMax) {
 Distance = MouseZoomMax;
 }
 var rotation = transform.rotation;
 
 transform.position = storeRotation * new Vector3 (0.0F, 0.0F, -Distance) + CameraTargetPosition;
 }
 
 //鼠标中键平移
 if (Input.GetMouseButtonDown (2)) {
 cameraX = transform.right;
 cameraY = transform.up;
 cameraZ = transform.forward;
 
 initScreenPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
 Debug.Log ("downOnce");
 
 //targetOnScreenPosition.z为目标物体到相机xmidbuttonDownPositiony平面的法线距离
 targetOnScreenPosition = Camera.main.WorldToScreenPoint (CameraTargetPosition);
 initPosition = CameraTargetPosition;
 }
 
 if (Input.GetMouseButton (2)) {
 curScreenPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
 //0.01这个系数是控制平移的速度,要根据相机和目标物体的distance来灵活选择
 target.position = initPosition - 0.01f * ((curScreenPos.x - initScreenPos.x) * cameraX + (curScreenPos.y - initScreenPos.y) * cameraY);
 
 //重新计算位置
 Vector3 mPosition = storeRotation * new Vector3 (0.0F, 0.0F, -Distance) + target.position;
 transform.position = mPosition;
 
 // //用这个会让相机的平移变得更平滑,但是可能在你buttonup时未使相机移动到应到的位置,导致再进行旋转与缩放操作时出现短暂抖动
 //transform.position=Vector3.Lerp(transform.position,mPosition,Time.deltaTime*moveSpeed);
 
 }
 if (Input.GetMouseButtonUp (2)) {
 Debug.Log ("upOnce");
 //平移结束把cameraTargetPosition的位置更新一下,不然会影响缩放与旋转功能
 CameraTargetPosition = target.position;
 }
 
 }
 
 //将angle限制在min~max之间
 static float ClampAngle (float angle, float min, float max) {
 if (angle < -360)
 angle += 360;
 if (angle > 360)
 angle -= 360;
 return Mathf.Clamp (angle, min, max);
 }
 
 void testScreenToWorldPoint () {
 //第三个坐标指的是在相机z轴指向方向上的距离
 Vector3 screenPoint = Camera.main.WorldToScreenPoint (CameraTargetPosition);
 Debug.Log ("ScreenPoint: " + screenPoint);
 
 // var worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(1,1,10));
 // Debug.Log("worldPosition: "+worldPosition);
 }
}

实现的效果如下图:

Unity3D使用鼠标旋转缩放平移视角

demo工程在此下载:MouseLookDemoWithUnity3D

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/a380331382/article/details/84069582

延伸 · 阅读

精彩推荐
  • C#C#中explicit与implicit的深入理解

    C#中explicit与implicit的深入理解

    这篇文章主要给大家介绍了关于C#中explicit与implicit的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要...

    依乐祝11762022-07-22
  • C#在C#项目中如何使用NHibernate详解

    在C#项目中如何使用NHibernate详解

    NHibernate的设计思想和Hibernate的设计思想基本相同,都是为了避免频繁的编写sql脚本,使用面向对象的方式使用hql语句进行查询。下面这篇文章主要给大家介...

    灵动生活12002022-02-22
  • C#C# WinForm实现窗体上控件自由拖动功能示例

    C# WinForm实现窗体上控件自由拖动功能示例

    这篇文章主要介绍了C# WinForm实现窗体上控件自由拖动功能,涉及WinForm控件属性及事件响应相关操作技巧,需要的朋友可以参考下...

    a7719485244822022-01-12
  • C#C# Distinct和重写IEqualityComparer时要知道的二三事

    C# Distinct和重写IEqualityComparer时要知道的二三事

    这篇文章主要给大家介绍了关于C# Distinct和重写IEqualityComparer时要知道的二三事,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考...

    新田三十三11102022-07-27
  • C#详解C#设置Excel数据自适应行高、列宽的2种情况

    详解C#设置Excel数据自适应行高、列宽的2种情况

    这篇文章主要介绍了C#设置Excel数据自适应行高、列宽的2种情况,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需...

    E-iceblue7012022-07-20
  • C#C# 字符串按 ASCII码 排序的方法

    C# 字符串按 ASCII码 排序的方法

    这篇文章主要介绍了C# 字符串按 ASCII码 排序的方法,需要的朋友可以参考下...

    C#教程网5262021-12-31
  • C#C#微信开发之接收 / 返回文本消息

    C#微信开发之接收 / 返回文本消息

    本文主要介绍了C#微信开发之接收 / 返回文本消息原理与实现方法,具有一定的参考价值,下面跟着小编一起来看下吧...

    likar11182021-12-22
  • C#C#在PDF中绘制不同风格类型的文本方法实例

    C#在PDF中绘制不同风格类型的文本方法实例

    这篇文章主要给大家介绍了关于C#在PDF中绘制不同风格类型的文本的相关资料,文中通过图文以及示例代码介绍的非常详细,对大家的学习或者工作具有一...

    E-iceblue8032022-02-25