首页 > 代码库 > Unity API 解析(2)—— Camera 类属性

Unity API 解析(2)—— Camera 类属性

aspect属性 —— 摄像机视口比例

public float aspect {get ; set ;}

用于获取或设置camera适口的宽高比例值

aspect 只处理摄像机可以看到的试图的宽高比例,而硬件显示屏的作用只是把摄像机的内容显示出来,当硬件显示屏的宽高比例与aspect的比例值不同时,视图将发生变形

using UnityEngine;using System.Collections;public class Aspect_ts : MonoBehaviour{    void Start()    {        // 默认值就是当前硬件的aspect值        Debug.Log("camera.aspectμ???è??μ£o" + camera.aspect);    }    void OnGUI()    {        if (GUI.Button(new Rect(10.0f, 10.0f, 200.0f, 45.0f), "aspect=1.0f"))        {            camera.ResetAspect();            camera.aspect = 1.0f;        }        if (GUI.Button(new Rect(10.0f, 60.0f, 200.0f, 45.0f), "aspect=2.0f"))        {            camera.ResetAspect();            camera.aspect = 2.0f;        }        if (GUI.Button(new Rect(10.0f, 110.0f, 200.0f, 45.0f), "aspect?1?-??è??μ"))        {            camera.ResetAspect();        }    }}

cameraToWorldMatrix 变换矩阵

public Matrix4x4 cameraToWorldMatrix { get; }

返回从摄像机的局部坐标系到世界坐标系的变换矩阵

注意 —— camera 中的forward 方向为其自身坐标系的-z轴方向,一般其他GameObject对象forward方向为自身坐标系的z轴方向

using UnityEngine;using System.Collections;public class CameraToWorldMatrix_ts : MonoBehaviour{    void Start()    {        Debug.Log("Camera 旋转前位置" + transform.position);        Matrix4x4 m = camera.cameraToWorldMatrix;        //v3 的值为沿着Camera局部坐标系的-z轴方向前移5个单位的位置在世界坐标系中的位置        Vector3 v3 = m.MultiplyPoint(Vector3.forward * 5.0f);		//v4 的值为沿着Camera世界坐标系的-z轴方向前移5个单位的位置在世界坐标系中的位置        Vector3 v4 = m.MultiplyPoint(transform.forward * 5.0f);        //′òó?v3?¢v4        Debug.Log("旋转前,v3" + v3);		Debug.Log("旋转前,v4" + v4);        transform.Rotate(Vector3.up * 90.0f);        Debug.Log("Camera 旋转后" + transform.position);    }}

cullingMask 属性 —— 摄像机按层渲染

有选择地渲染场景中的物体。cullingMusk = -1渲染场景中任何物体,cullingMusk = 0不渲染场景中任何层,若渲染2,3,4层的物体,则可以使用代码 cullingMask = (1<<2)+(1<<3)+(1<<4)

需要现对场景中的物体层次进行设置

using UnityEngine;using System.Collections;public class CullingMask_ts : MonoBehaviour{    void OnGUI()    {        //渲染任何层        if (GUI.Button(new Rect(10.0f, 10.0f, 200.0f, 45.0f), "CullingMask=-1"))        {            camera.cullingMask = -1;        }        //不渲染任何层        if (GUI.Button(new Rect(10.0f, 60.0f, 200.0f, 45.0f), "CullingMask=0"))        {            camera.cullingMask = 0;        }        //0层        if (GUI.Button(new Rect(10.0f, 110.0f, 200.0f, 45.0f), "CullingMask=1<<0"))        {            camera.cullingMask = 1 << 0;        }        //8层        if (GUI.Button(new Rect(10.0f, 160.0f, 200.0f, 45.0f), "CullingMask=1<<8"))        {            camera.cullingMask = 1 << 8;        }        //0层和8层        if (GUI.Button(new Rect(10.0f, 210.0f, 200.0f, 45.0f), "CullingMask=0&&8"))        {            //不可写成camera.cullingMask = 1 << 8+1;或            //camera.cullingMask = 1+1<<8 ;根据优先顺序分别等价于            //camera.cullingMask = 1 << (8+1)oícamera.cullingMask = (1+1)<<8;            camera.cullingMask = (1 << 8) + 1;        }    }}

evenMask 属性:按层响应事件

选择哪个层layer的物体可以响应鼠标事件

物体必须在摄像机的视野范围内

using UnityEngine;using System.Collections;public class EventMask_ts : MonoBehaviour{    bool is_rotate = false;//控制物体旋转    public Camera c;//指向场景中摄像机    //记录摄像机的eventMask值,可以在程序运行时在Inspector面板中修改其值的大小    public int eventMask_now = -1;    //记录当前物体的层    int layer_now;    int tp;//记录2的layer次方的值    int ad;//记录与运算(&)的结果    string str = null;    void Update()    {        //记录当前对象的层,可以在程序运行时在Inspector面板中选择不同的层        layer_now = gameObject.layer;        //求2的layer_now次方的值        tp = (int)Mathf.Pow(2.0f, layer_now);        //与运算(&)        ad = eventMask_now & tp;        c.eventMask = eventMask_now;        //当is_rotate为true时旋转物体        if (is_rotate)        {            transform.Rotate(Vector3.up * 15.0f * Time.deltaTime);        }    }    //当鼠标左键按下时,物体开始旋转    void onm ouseDown()    {        is_rotate = true;    }    //当鼠标左键抬起时,物体结束旋转    void onm ouseUp()    {        is_rotate = false;    }    void OnGUI()    {        GUI.Label(new Rect(10.0f, 10.0f, 300.0f, 45.0f), "当前对象的layer值为:" + layer_now + " , 2的layer次方的值为" + tp);        GUI.Label(new Rect(10.0f, 60.0f, 300.0f, 45.0f), "当前摄像机eventMask的值为:" + eventMask_now);        GUI.Label(new Rect(10.0f, 110.0f, 500.0f, 45.0f), "根据算法,当eventMask的值与" + tp + "进行与运算(&)后, 若结果为" + tp + ",则物体相应OnMousexxx方法,否则不响应!");        if (ad == tp)        {            str = " ,所以物体会相应OnMouseXXX方法!";        }        else        {            str = " ,所以物体不会相应OnMouseXXX方法!";        }        GUI.Label(new Rect(10.0f, 160.0f, 500.0f, 45.0f), "而当前eventMask与" + tp + "进行与运算(&)的结果为" + ad + str);    }}

 

layerCullDistances 属性 :层消隐的距离

设置摄像机基于层的消隐距离 —— 必须小于或等于摄像机的farClipPlane才有效

using UnityEngine;using System.Collections;public class LayerCullDistances_ts : MonoBehaviour{    public Transform cb1;    void Start()    {        // 定义32一维数组,用来存储所有层的剔除距离        float[] distances = new float[32];        //设置第9层的剔除距离        distances[8] = Vector3.Distance(transform.position, cb1.position);        //将数组赋值给摄像机的layerCullDistance        camera.layerCullDistances = distances;    }    void Update()    {        //摄像机远离物体        transform.Translate(transform.right * Time.deltaTime);    }}

layerCullSpherical 属性 —— 基于球面距离剔除

默认值为false —— 不适用球面剔除方式 —— 此时,只要物体表面上有一点没有超出物体所在层的远适口平面,物体就是可见的

当layerCullSpherical 为true时,只要物体的世界坐标点position与摄像机的距离大于所在层的剔除距离,物体就是不可见的

声明3个transform公共变量,用于指向场景中的物体

using UnityEngine;using System.Collections;public class layerCullSpherical_ts : MonoBehaviour{    public Transform cb1, cb2, cb3;    void Start()    {        //定义大小为32的一维数组,用来存储所有层的剔除距离        float[] distances = new float[32];        //设置第9层的剔除距离        distances[8] = Vector3.Distance(transform.position, cb1.position);        //将数组赋给摄像机的layerCullDistances        camera.layerCullDistances = distances;        //打印出三个物体距离摄像机的距离        Debug.Log("Cube1距离摄像机的距离:" + Vector3.Distance(transform.position, cb1.position));        Debug.Log("Cube2距离摄像机的距离:" + Vector3.Distance(transform.position, cb2.position));        Debug.Log("Cube3距离摄像机的距离:" + Vector3.Distance(transform.position, cb3.position));    }    void OnGUI()    {        //使用球形距离剔除        if (GUI.Button(new Rect(10.0f, 10.0f, 180.0f, 45.0f), "use layerCullSpherical"))        {            camera.layerCullSpherical = true;        }        //取消球形距离剔除        if (GUI.Button(new Rect(10.0f, 60.0f, 180.0f, 45.0f), "unuse layerCullSpherical"))        {            camera.layerCullSpherical = false;        }    }}

orthographic 属性 —— 摄像机投影模式

true为正交投影模式(orthographic) 和false为透视投影模式(perspective)

正交投影模式下,物体在视口中的大小只与正交适口的大小有关,于摄像机到物体的距离无关,主要用来呈现2D效果 —— 没有近大远小的效果

pixelRect 属性 —— 摄像机渲染区间

设置camera被渲染到屏幕中的坐标位置

pixelRect与属性rect功能类似,不同的是pixelRect以实际像素大小来设置视口的位置

camera.pixelRect(x,y,w,h) —— x的值为视口右移的像素大小,y的值为视口上移的像素大小,w的值为camera.pixelWidth ,h的值为 camera.pixelHeight

using UnityEngine;using System.Collections;public class PixelRect_ts : MonoBehaviour{    int which_change = -1;    float temp_x = 0.0f, temp_y = 0.0f;    void Update()    {        //Screen.widthoíScreen.height?a?£?aó2?t?á??μ??í???μ,        //??·μ???μ2???camera.pixelWidthoícamera.pixelHeightμ???±?????±?        Debug.Log("Screen.width:" + Screen.width);        Debug.Log("Screen.height:" + Screen.height);        Debug.Log("pixelWidth:" + camera.pixelWidth);        Debug.Log("pixelHeight:" + camera.pixelHeight);        // 通过改变camera的坐标位置而改变视口的区间        if (which_change == 0)        {            if (camera.pixelWidth > 1.0f)            {                temp_x += Time.deltaTime * 20.0f;            }            camera.pixelRect = new Rect(temp_x, temp_y, camera.pixelWidth, camera.pixelHeight);        }        //通过改变camera的视口宽度和高度来改变视口的区间        else if (which_change == 1)        {            if (camera.pixelWidth > 1.0f)            {                temp_x = camera.pixelWidth - Time.deltaTime * 20.0f;            }            camera.pixelRect = new Rect(0, 0, temp_x, temp_y);        }    }    void OnGUI()    {        if (GUI.Button(new Rect(10.0f, 10.0f, 200.0f, 45.0f), "视口改变方式一"))        {            camera.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f);            which_change = 0;            temp_x = 0.0f;            temp_y = 0.0f;        }        if (GUI.Button(new Rect(10.0f, 60.0f, 200.0f, 45.0f), "视口改变方式二"))        {            camera.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f);            which_change = 1;            temp_x = 0.0f;            temp_y = camera.pixelHeight;        }        if (GUI.Button(new Rect(10.0f, 110.0f, 200.0f, 45.0f), "视口还原"))        {            camera.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f);            which_change = -1;        }    }}

projectionMatrix 属性 —— 自定义投影矩阵

用于实现一些特效场景,在切换变换矩阵时通常需要先用camera.ResetProjectionMatrix()重置camera的变换矩阵

using UnityEngine;using System.Collections;public class ProjectionMatrix_ts : MonoBehaviour{    public Transform sp, cb;    public Matrix4x4 originalProjection;    float q=0.1f;// 晃动振幅    float p=1.5f;// 晃动频率    int which_change = -1;    void Start()    {        //记录原始投影矩阵        originalProjection = camera.projectionMatrix;    }    void Update()    {        sp.RotateAround(cb.position, cb.up, 45.0f * Time.deltaTime);        Matrix4x4 pr = originalProjection;        switch (which_change)        {            case -1:                break;            case 0:                //绕摄像机x轴晃动                pr.m11 += Mathf.Sin(Time.time * p) * q;                break;            case 1:                // 绕摄像机y轴晃动                pr.m01 += Mathf.Sin(Time.time * p) * q;                break;            case 2:                // 绕摄像机z轴晃动                pr.m10 += Mathf.Sin(Time.time * p) * q;                break;            case 3:                // 绕摄像机左右移动                pr.m02 += Mathf.Sin(Time.time * p) * q;                break;            case 4:                //摄像机视口缩放运动                pr.m00 += Mathf.Sin(Time.time * p) * q;                break;        }        //设置Camera的变换矩阵        camera.projectionMatrix = pr;    }    void OnGUI()    {		if (GUI.Button(new Rect(10.0f, 10.0f, 200.0f, 45.0f), "绕摄像机x轴晃动"))        {            camera.ResetProjectionMatrix();            which_change = 0;        }		if (GUI.Button(new Rect(10.0f, 60.0f, 200.0f, 45.0f), "绕摄像机y轴晃动"))        {            camera.ResetProjectionMatrix();            which_change = 1;        }		if (GUI.Button(new Rect(10.0f, 110.0f, 200.0f, 45.0f), "绕摄像机z轴晃动"))        {            camera.ResetProjectionMatrix();            which_change = 2;        }		if (GUI.Button(new Rect(10.0f, 160.0f, 200.0f, 45.0f), "绕摄像机左右移动"))        {            camera.ResetProjectionMatrix();            which_change = 3;        }		if (GUI.Button(new Rect(10.0f, 210.0f, 200.0f, 45.0f), "摄像机视口缩放运动"))        {            camera.ResetProjectionMatrix();            which_change = 4;        }    }}

rect 属性 —— 摄像机视图的位置和大小

使用单位化坐标系的方式来设置当前摄像机的视图位置和大小,缩放比例

renderingPath

获取或设置摄像机的渲染路径

渲染路径的设置有四种方式 :

UsePlayerSettings —— 使用工程中的设置

VertexLit —— 使用顶点光照,最低消耗的渲染路径,不支持实时阴影,适用于移动及老实设备

Forward —— 使用正向光照,基于着色器的渲染路径

DeferredLighting —— 使用延迟光照,支持实时阴影,计算消耗大

using UnityEngine;using System.Collections;public class renderingPath_ts : MonoBehaviour{    void OnGUI()    {        if (GUI.Button(new Rect(10.0f, 10.0f, 120.0f, 45.0f), "UsePlayerSettings"))        {            camera.renderingPath = RenderingPath.UsePlayerSettings;        }        if (GUI.Button(new Rect(10.0f, 60.0f, 120.0f, 45.0f), "VertexLit"))        {			// 无凹凸纹理,无投影            camera.renderingPath = RenderingPath.VertexLit;        }        if (GUI.Button(new Rect(10.0f, 110.0f, 120.0f, 45.0f), "Forward"))        {			// 有凹凸纹理,只能显示一个投影            camera.renderingPath = RenderingPath.Forward;        }        if (GUI.Button(new Rect(10.0f, 160.0f, 120.0f, 45.0f), "DeferredLighting"))        {			// 有凹凸纹理,可以显示多个投影            camera.renderingPath = RenderingPath.DeferredLighting;        }    }}

targetTexture  属性 —— 目标渲染纹理

调用此属性可生成目标渲染纹理,仅专业版可用

此属性的作用是可以把某个摄像机A的视图作为Renderer Texture,然后添加到一个Material对象形成一个新的material,再把这个material赋给一个GameObject对象的Renderer组件

worldToCameraMatrix 属性 —— 变换矩阵

返回或设置从世界坐标系到当前Camera自身坐标系的变换矩阵

当用camera.worldToCameraMatrix重置摄像机的转换矩阵时,摄像机对应的Transform组件数据不会同步更新,若想回到Transform的可控状态,需要调用ResetWoldToCameraMatrix方法重置摄像机的转换矩阵

Unity API 解析(2)—— Camera 类属性