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之间的相对距离保持不变。具体代码如下:
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); } }
实现的效果如下图:
demo工程在此下载:mouselookdemowithunity3d
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。