Unity3D屏幕自适应

  • Unity3D的四种坐标系

  1. World Space(世界坐标):我们在场景中添加物体(如:Cube),他们都是以世界坐标显示在场景中的。transform.position可以获得该位置坐标。
  2. Screen Space(屏幕坐标):以像素来定义的,以屏幕的左下角为(0,0)点右上角为(Screen.widthScreen.heightZ的位置是以相机的世界单位来衡量的。注:鼠标位置坐标属于屏幕坐标,Input.mousePosition可以获得该位置坐标,手指触摸屏幕也为屏幕坐标,Input.GetTouch(0).position可以获得单个手指触摸屏幕坐标。Screen.width = Camera.pixelWidth ,Screen.height = Camera.pixelHeigth
  3. ViewPort Space(视口坐标):视口坐标是标准的和相对于相机的。相机的左下角为(0,0)点,右上角为(1,1)点Z的位置是以相机的世界单位来衡量的。
  4. GUI界面的坐标系:这个坐标系与屏幕坐标系相似,不同的是该坐标系以屏幕的左上角为(0,0)点右下角为(Screen.widthScreen.height

注意:实际屏幕坐标也是三维的,后面三种坐标的Z轴都是相对与摄像机的距离

  • 四种坐标系的转换

  1. 世界坐标→屏幕坐标camera.WorldToScreenPoint(transform.position);这样可以将世界坐标转换为屏幕坐标。其中camera为场景中的camera对象。
  2. 屏幕坐标→视口坐标camera.ScreenToViewportPoint(Input.GetTouch(0).position);这样可以将屏幕坐标转换为视口坐标。其中camera为场景中的camera对象。
  3. 视口坐标→屏幕坐标camera.ViewportToScreenPoint();
  4. 视口坐标→世界坐标camera.ViewportToWorldPoint()
  • 【坐标系中的变换】
  1. 平移,旋转,缩放。
  2. 旋转和缩放发生在局部坐标系上,以局部坐标原点为中心点,两者还满足交换率。
  3. 平移发生在父坐标系上。

所以实现时,会先算好旋转缩放,再算平移。Unity的转动顺序是YXZ,中间的轴是X。因为围绕Y轴的水平摇摆最常见,围绕X轴的垂直俯仰次常用,而围绕Z轴的歪脑袋最少用。

  • 【Canvas 设置】

  • Canvas.RenderMode:ScreenSpace - Overlay

Canvas作为2D图像,永远处于屏幕的最前方,即使没有相机也能够看到内容。如果画布发生大小改变,也能够自动改变尺寸来匹配屏幕。

  1. 当ScreenOverlay的情况,因为根本没有经过投影空间,而是直接在屏幕空间绘制,因为在屏幕空间的坐标直接绘制像素,所以Canvas的RectTransform的width*scaleX必须等于屏幕的宽、RectTransform的height*scaleY必须等于屏幕的高。
  2. Overlay情况下,Scene View世界空间的、Canvas屏幕空间的,两者处于不同空间,它们的大小比较也就没有可比性了,Unity这里的Editor实现是,屏幕空间1像素等于世界空间1米地把Canvas在SceneView显示出来

Canvas的核心功能是,自动根据屏幕设备的分辨率、当前的scaleXY,算出正确的width和height,确保和屏幕匹配。

Canvas.RectTransform.scaleXYZ = Canvas.scaleFactor

scaleFactor = Mathf.Min(screenSize.x / m_ReferenceResolution.x, screenSize.y / m_ReferenceResolution.y);
scaleFactor尽可能小,结果是尽量把UI在设备屏幕给放大
1024/1280=0.8 < 720/768 所以缩放是0.8,然后将设备分辨率根据除0.8来得到适合的1280*960大小。

 设备分辨率1024*768时,基准分辩率是1280*720,unity会根据1024和768来进行缩放Canvas的width、height、scale,根据宽固定,缩放高度,即把1280缩小到1024是0.8倍,然后根据720/0.8得到960,大小缩放Scale是0.8,自动调整大小为1280*960。

  • Canvas.RenderMode:ScreenSpace - Camera

可以指定摄像机,和Screen Space-Overlay类似,但是有物体比Canvas更加接近摄像机时会显示在前面,反之则会被Canvas遮挡。

  1. 由于使用了Camera,所以此时的Canvas和Scene View里的任意GameObject一样,都是处于世界空间了。
  2. 所以对于ScreenSpace - Camera的Canvas来说,关键是如何把处于世界空间中的Canvas能够占满投影空间的投影平面。
  3. 所以在Camera模式下,相当要把世界坐标的Canvas转化为屏幕坐标,要根据2D相机和Canvas的plane distance,Size
  4. Canvas.RectTransform.scaleXYZ = Canvas.scaleFactor * scaleFactorCamera
  5. 正交(Orthographic)Camera 2D模式下,Size的定义为视体的投影平面高的1/2。 比如Camera的Size是3.6,即投影平面高为500

 设备分辨率1024*768时,因为世界空间转化到屏幕空间,所以Plane Distance相当于移动z轴相反的500,到原点。

size = 3.6米=360像素,所以相机的高度=2*size = 720像素,根据基准分辩率宽就是1280。所以基准分辩率是1280*720,

  • Canvas.height==Screen.height = 768
  • Canvas.height * scaleFactor * scaleFactorCamera = Camera.size * 2
  • 768 * scaleFactor * scaleFactorCamera = 3.6 * 2
  • 所以scaleFactorCamera = Camera.size * 2 / Canvas.height / scaleFactor = Camera.size * 2 / Screen.height / scaleFactor
  • Canvas.RenderMode:World Space:可以指定摄像机,把Canvas视为一个3D物体来处理,可以设置位置和大小。

  • 【Screen Match Mode—Expand】

当屏幕分辨率大于参考分辨率时,选择变化较小的一个方向(横向还是纵向),作为放大Canvas Scale的标准,另一方向上的变化则是在整体缩放以后再进行补偿性的变化。此举旨在减少扩大分辨率时由于非等比扩大而对UI整体布局造成影响。适合制作较小标准尺寸,扩充到较大屏幕。

  • 【锚点】

  

AnchorsMin:锚框左下角的点

AnchorsMax:锚框右上角的点

当AnchorsMin和AnchorsMax不在同一水平线或垂直线上的时候,就形成了锚框;

当AnchorsMin和AnchorsMax两个点重合的时候,就形成了一种特殊情况:锚点

注册点(Pivot):注册点就是自身的中心点,也是个归一化的点

当使用的是锚点的时候,使用的是绝对位置,被子物体定上锚点的父物体的大小改变、移动都不会改变子物体锁定的锚点到子物体注册点(Pivot)之间的距离。

当使用的是锚框的时候,使用的是相对位置(相对父物体的位置),被子物体定上锚框的父物体的移动不会改变子物体锁定的锚框的AnchorsMin到子物体左下角点之间的距离以及锚框的AnchorsMax到子物体右上角点之间的距离。
  •  总结:

Render Mode 选择为Camera

UI Scale Mode选择screen Size

Match Mode选择Expand

UI内的子物体通过设置锚点固定在UI的位置,可以把父物体设置成跟设备分辨率大小一样,然后把子物体根据锚点来设置相对位置。

原文地址:https://www.cnblogs.com/wwhhgg/p/12712448.html