下面的类主要作用是根据不同的值来改变摄像头的位置,从而达到不同的视角满足各种不同的需求,基本原理:角度的4元数乘以一个位移向量,得到一个旋转过后的最终向量,然后把最终向量赋值给摄像头,就得到摄像头的位置。还是看DEMO吧。
可以按下鼠标右键来操作angleX、angleY 的值,达到操作摄像头围绕着正方形X轴旋转,Y轴旋转。
根据绕x、y、z轴的旋转得到摄像头的旋转。
根据向量的x、y、z的值来确定上下左右坐标。
还有旋转速度 以及鼠标滚轮缩放的速度设置。
自己操作一下DEMO,再看看代码,什么都明白了。其实核心的东西就是 UpdateCarema 这个方法。
This movie requires Flash Player 9
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 137 138 139 140 |
using UnityEngine; using System.Collections; //如果要贴代码自己建立项目,请先创建一个CUBE, //并且将CUBE放大3倍(当然可以根据你的喜好自己调节大小。我DEMO的大小是3倍), //然后将代码挂到摄像机上就可以运行了。切记要挂到摄像机上。 public class CameraControl : MonoBehaviour { // 观测对象 private GameObject target; //距离 public float distanceX = 0f; public float distanceY = 0f; public float distanceZ = -5f; public float maxDistance = -50f; public float minDistance = -5f; //角度 public float angleX = 30f; public float angleY = 0f; public float angleZ = 0f; public float anglespeed = 5f; public float scrollSpeed = 250f; void Start() { target = GameObject.Find("Cube"); } void Update() { Mouse(); UpdateCarema(); } void OnGUI() { string text; float y = 0; float dis = 20; GUI.Label(new Rect(0, 0, 90, 30), "distanceX : "); distanceX = GUI.HorizontalSlider(new Rect(90, 0, 100, 10), distanceX, -30.0F, 30.0F); text = GUI.TextField(new Rect(190, 0, 50, 20), distanceX.ToString(), 6); distanceX = float.Parse(text == "" ? "0" : text); y += dis; GUI.Label(new Rect(0, y, 90, 30), "distanceY : "); distanceY = GUI.HorizontalSlider(new Rect(90, y, 100, 10), distanceY, -30.0F, 30.0F); text = GUI.TextField(new Rect(190, y, 50, 20), distanceY.ToString(), 6); distanceY = float.Parse(text == "" ? "0" : text); y += dis; GUI.Label(new Rect(0, y, 90, 30), "distanceZ : "); distanceZ = GUI.HorizontalSlider(new Rect(90, y, 100, 10), distanceZ, maxDistance, minDistance); text = GUI.TextField(new Rect(190, y, 50, 20), distanceZ.ToString(), 6); distanceZ = float.Parse(text == "" ? "0" : text); y += dis; GUI.Label(new Rect(0, y, 90, 30), "maxDistance : "); maxDistance = GUI.HorizontalSlider(new Rect(90, y, 100, 10), maxDistance, -100, 100.0F); text = GUI.TextField(new Rect(190, y, 50, 20), maxDistance.ToString(), 6); maxDistance = float.Parse(text == "" ? "0" : text); y += dis; GUI.Label(new Rect(0, y, 90, 30), "minDistance : "); minDistance = GUI.HorizontalSlider(new Rect(90, y, 100, 10), minDistance, -100, 100.0F); text = GUI.TextField(new Rect(190, y, 50, 20), minDistance.ToString(), 6); minDistance = float.Parse(text == "" ? "0" : text); y += dis; GUI.Label(new Rect(0, y, 90, 30), "angleX : "); angleX = GUI.HorizontalSlider(new Rect(90, y, 100, 10), angleX, -360.0F, 360.0F); text = GUI.TextField(new Rect(190, y, 50, 20), angleX.ToString(), 6); angleX = float.Parse(text == "" ? "0" : text); y += dis; GUI.Label(new Rect(0, y, 90, 30), "angleY : "); angleY = GUI.HorizontalSlider(new Rect(90, y, 100, 10), angleY, -360.0F, 360.0F); text = GUI.TextField(new Rect(190, y, 50, 20), angleY.ToString(), 6); angleY = float.Parse(text == "" ? "0" : text); y += dis; GUI.Label(new Rect(0, y, 90, 30), "angleZ : "); angleZ = GUI.HorizontalSlider(new Rect(90, y, 100, 10), angleZ, -360.0F, 360.0F); text = GUI.TextField(new Rect(190, y, 50, 20), angleZ.ToString(), 6); angleZ = float.Parse(text == "" ? "0" : text); y += dis; GUI.Label(new Rect(0, y, 90, 30), "speed : "); anglespeed = GUI.HorizontalSlider(new Rect(90, y, 100, 10), anglespeed, 100.0F, 0.0F); text = GUI.TextField(new Rect(190, y, 50, 20), anglespeed.ToString(), 6); anglespeed = float.Parse(text == "" ? "0" : text); y += dis; GUI.Label(new Rect(0, y, 90, 30), "scrollSpeed : "); scrollSpeed = GUI.HorizontalSlider(new Rect(90, y, 100, 10), scrollSpeed, 500.0F, 0.0F); text = GUI.TextField(new Rect(190, y, 50, 20), scrollSpeed.ToString(), 6); scrollSpeed = float.Parse(text == "" ? "0" : text); } private void Mouse() { if (Input.GetMouseButton(1)) { angleY += Input.GetAxis("Mouse X") * anglespeed; angleX -= Input.GetAxis("Mouse Y") * anglespeed; } if (Input.GetAxis("Mouse ScrollWheel") != 0) { //根据鼠标滚轮都值计算出这一帧应该移动都距离。 distanceZ += Mathf.Lerp(0, Input.GetAxis("Mouse ScrollWheel") * scrollSpeed, Time.deltaTime); //判断是否超过最大范围 distanceZ = Mathf.Clamp(distanceZ, maxDistance, minDistance); } } private void UpdateCarema() { //通过围绕x、y、z轴都角度创建一个四元数 Quaternion rotation = Quaternion.Euler(angleX, angleY, angleZ); //创建一个位移向量。 Vector3 Pos = new Vector3(distanceX, distanceY, distanceZ); //将上面都向量选择对应四元数所表示都角度。 Vector3 move = rotation * Pos; //从目标点进行move向量的移动。得到一个新都位置。 Vector3 pos = move + target.transform.position; //赋值给摄像机新的位置 transform.position = pos; //赋值给摄像机新都旋转 transform.rotation = rotation; } } |
目前对向量、点、角度的一些概念在Unity中的使用还是不熟悉。Unity还在入门阶段。