像素:图像的最小单位,图像就是由像素点构成的。
图像分辨率:像素/英寸。
屏幕分辨率:屏幕每行像素点数*每列像素点数。
Pixels Per Unit = 100(默认),表示:Sprite100个像素转换成unity的中的一个单位(unit),比如100x100的图片,在不放大的原始大小情况下,就是1个单位高。
unity中,最终游戏窗口的渲染显示范围取决于摄像机的属性,在camera的Orthographic模式下,通过调节size来调整结果。
Camera.orthographicsSize属性,调整的是摄像机的渲染高度,其值表示的是屏幕高度*0.5。
例子如下,这个sprite是100x100,因为camera相当于是只看到屏幕高度的一半,所以1个单位的sprite就是在中间,如果把size = 0.5,sprite的高度就会填满游戏界面了:
那么给unity单位又该怎么理解,一般情况下,unity创建一个3d cube正好就占据了1个unity单位,如下:
所以Camera.orthographicsSize =1,可以理解为,它可以看到2个unit。size=0.5表示它可以看到1个unit。
注意:游戏窗口的3:2,1:1永远表示的是逻辑上的宽高比,和unit及像素无关。
所以在开发游戏的时候,比如说pc,可以先判断笔记本的屏幕分辨率,假设笔记本的屏幕分辨率高度是640px,那么换算成unity单位就是6.4个unit,所以camra的size应该是3.2,正好使摄像机的大小和屏幕大小相等。这样在开发中,game视图下看到的界面,就是launch以后的界面效果,不会放大也不会缩小。
下面给出个例子:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//[ExecuteInEditMode]
public class Ground : MonoBehaviour
{
#region propertity
public float Camera_size = 1f; //相机的size
public float Screen_height = 768; //标准屏幕的高度
private float Gl_to_pixel_ration; //屏幕unit和屏幕像素的比值
public Material spriteMaterial;
private int _vertice_count = 4;
#endregion
void Start()
{
//屏幕unit和屏幕像素的比值
Gl_to_pixel_ration = Camera_size * 2.0f / Screen_height;
InitSprite();
//transform.Rotate(90, 0, 0, Space.Self);
}
void Update()
{
}
public void InitSprite()
{
//获取图片的像素比宽高
int pixel_height = spriteMaterial.mainTexture.height;
int pixel_width = spriteMaterial.mainTexture.width;
Debug.Log(pixel_width + " " + pixel_height);
//得到MeshFilter对象
MeshFilter meshFilter = gameObject.GetComponent<MeshFilter>();
if(!meshFilter)
{
meshFilter = gameObject.AddComponent<MeshFilter>();
MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>();
meshRenderer.sharedMaterial = spriteMaterial;
//meshRenderer.material = spriteMaterial;
meshRenderer.sharedMaterial.color = Color.white;
//meshRenderer.sharedMaterials[0] = spriteMaterial;
}
//得到对应的网格对象
//Mesh mesh = meshFilter.sharedMesh;
Mesh mesh = meshFilter.mesh;
//网格的顶点做标数组
Vector3[] vertices = new Vector3[_vertice_count];
//得到三角形的数量
int _triangle_count = _vertice_count - 2;
//三角形顶点数组
int[] triangles = new int[_vertice_count * 3];
//如果用自带的Sprite插件,一个pixels per unit参数就搞定了
float glHeight = pixel_height * Gl_to_pixel_ration; //得到的是图片高度占据的unit大小
float glWidth = pixel_width * Gl_to_pixel_ration; //得到的是图片宽度占据的unit的大小
Debug.Log(glWidth + " " + glHeight);
vertices[0] = new Vector3(0,0,0);
vertices[1] = new Vector3(glWidth,0, 0);
vertices[2] = new Vector3(0,glHeight,0);
vertices[3] = new Vector3(glWidth,glHeight,0);
mesh.vertices = vertices;
//绑定顶点顺序--顺时针
triangles[0] = 0;
triangles[1] = 3;
triangles[2] = 1;
triangles[3] = 3;
triangles[4] = 0;
triangles[5] = 2;
mesh.triangles = triangles;
//for(int i=0;i<meshFilter.mesh.normals.Length;i++)
//{
// Debug.Log(meshFilter.mesh.normals[i]);
//}
//mesh.uv = new Vector2[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 0), new Vector2(1, 1) };
//meshFilter.mesh = mesh;
mesh.RecalculateNormals();
for (int i = 0; i < meshFilter.mesh.normals.Length; i++)
{
Debug.Log(meshFilter.mesh.normals[i]);
}
}
}
这段代码的意思就是实现Sprite物体的功能(其实直接用Unity 自带的Sprite插件还是很快很便捷的)。
为什么Game视图下只能看到左下角,因为Camera在(0,0-10)的位置,对于这个自定义Sprite而言,它的位置(0,0)是从左下角开始的。这在代码里有体现:
vertices[0] = new Vector3(0,0,0);
vertices[1] = new Vector3(glWidth,0, 0);
vertices[2] = new Vector3(0,glHeight,0);
vertices[3] = new Vector3(glWidth,glHeight,0);
另外关于这段代码有一个地方需要说一下,那就是
Mesh mesh = meshFilter.mesh;
看起来,meshFilter.mesh应该是一个引用,所以在最后需要通过mesh重新计算法向量,这样光照才能正确。
mesh.RecalculateNormals();