通過代碼創造圖形
//創建頂點,創建序列,創建網格,然后把網格賦給網格序列器 //draw a triangle void Start () { Vector3[] vs = new Vector3[3]; vs[0] = new Vector3(0,0,0); vs[1] = new Vector3(1,0,0); vs[2] = new Vector3(0,1,0); int[ts] = new int[3]; ts[0] = 0; ts[1] = 1; ts[2] = 2; //要注意順序,要用左手系,法線向外,拇指向外 Mesh mesh = new Mesh(); GetComponet<MeshFilter>().mesh = mesh; mesh.vertices = vs; // vertices至高點 mesh.triangles = ts; }

///* *///
//draw a triangle程序封裝代碼 public GameObject Create Triangle() { GameObject obj = new GameObject(“Triangle”); MeshFilter mf = obj.AddComponet<MeshFilter>(); obj.AddComponent<MeshRender>(); Mesh mesh = new Mesh(); mesh.vertices = nes[] { new Vector3(0,0,0); new Vector3(3,0,0); new Vector3(0,3,0); }; mesh.triangles = new[] { 0,2,1 //不用分號,初始化系,直接把初始值放進去 }; mf.mesh = mesh; return obj; }
Camera 的性質與使用
//Camera的實例性質
public CameraClearFlags clearFlags; //clearFlags是相機清除表識
public ColorbackgroundColor; //給定他的顏色,背景色,只有單色才起作用
public int cullingMask; //提出掩碼
public class chapter6 : MonoBehaviour { public GameObject cube; void Start(){ cube.laber = 9; //把cube設置在第9層 Camera cam = this.GetComponet<Camera>()’ cam.clearFlags = CameraClearFlags.SolidColor; cam.backgroundColor = new Vector3(1,0,0,0); //表示設置顏色 cam.cullingMask = 9; //表示第9層的都不會被渲染出來,也就是說cube不會顯示出來 } }
//CameraClearFlags是一個枚舉類型,有以下四個成員:
solidColor 表示用backgroundColor所制定的填充背景
skybox 表示天空盒,模擬天空效果填充
Depth 只是清除深度緩存,保留上一幀所使用的顏色
Nothing 不進行背景清除,這種情況在游戲和模擬應用中比較少用
public bool orthographic;//用於讀取和設定相機的投影方式,如果為true則表示是正交投影,否則為透視投影;正交投影可用於UI和2D開發
public float orthographicSize; //用以指定正交投影的視景體的垂直方向尺寸的一半
public Rect rect; //相機對應的視角口的位置和大小,rect以單位化形式制定相機視口在屏幕中的位置和大小,位置大小取值范圍為0~1,滿屏為1
Camera main = this.gameObject.GetComponet<Camera>(); this.gameObject.SetActive(false); Camera cam0 = camGO0.AddComponet<Camera>(); cam0.orthographic = true; cam0.transform.position = main.transform.position; cam0.transform.rotation = main.transform. rotation; cam0.orthographicSize = 2.0f; //指物體渲染后顯示的大小遠近,數值越大,相機視口越靠近該物體,從而該物體顯示出來的更加大 cam0.rect = new Rect(0f,0f, 0.5f, 0.5f); //前兩個參數是camera的位置,后面兩個參數設置相機大小(0.5f,0.5f)表示占x軸的二分之一,y軸的二分之一,所以總共占渲染窗口的四分之一 Camera cam1 = camGO1.AddComponet<Camera>(); cam1.orthographic = true; cam1.transform.position = main.transform.position; cam1.transform.rotation = main.transform. rotation; cam1.orthographicSize = 7.0f; cam1.rect = new Rect(0.5f, 0.5f, 0.5f, 0.5f); }
Material,Shader,Texture(材質,着色器,紋理)
光照、紋理等讓物體更加的真實。
材質在幾何物質的基礎下增加額外的東西,讓物體顯得更加真實。
着色器:核心最后的渲染過程。特殊的一串代碼,用特殊語言所寫,實現一定的算法。計算每個像素點的顏色。根據定點信息,光照,材質,計算頂點顏色,最后顯示出來。Unity提供多種着色器提供選擇。有專門一本書提供着色器的介紹。主流工具語言是Cg(C語言+graph)
紋理:圖片,增加在物體表面,復制在材質上,材質再復制給物體。美工的過程。
程序開發人員主要處理的是材質。
Rendering Mode,渲染模式,進一步確定着色器類型,在Standard系列下,有四種類型:Opaque(不透明), Cutout(表示在透明和不透明區域之間具有尖銳邊沿,沒有不透明效果,比如說一些鏤空邊緣或者一些草的材質), Fade(漸變,用以表示材質的透明度逐漸改變), Transparent(處理透明的,比如說玻璃材質)
Albedo,反照率,表示一種材質對白光的反射能力,是材質的散射、反射、折射和半透明成分的總和,相關參數控制物體表面的基色,純黑色「RGB=(0,0,0),Albedo=0」;白色「RGB=(1,1,1), Albedo=1」。alpha通道控制材質透明度,alpha值越小,Albedo的實現效果越微弱(因為alpha越透明度越高,當透明度極高的時候甚至不可以看到表面效果,所以有材質沒材質,有調Albedo和沒調也一樣)。
Metallic,表示材質處於金屬模擬工作流metalness workflow下。金屬模擬工作流與鏡面反射工作流specular workflow是兩種處理光反射的不同模式。
光照於CG中十分重要。PBR(physical base render)基於物理渲染,可以模擬光線於現實的情況,實現光線追蹤。
Smoothness,光滑度,最光滑相當於鏡面反射。
MeshFilter&MeshRender
網格渲染器
Cast shadows,一個開關,該網格物體是否產生陰影
Receive Shadows,一個開關,是否接受其他物體投射到其上面
Motion Vectors, 運動適量,用於追蹤一個物體從一幀到下一幀的空間位置,並可用於后期處理效果,比如說運動模糊處理和時域抗鋸齒效果。
Coding for materials
Shader shader; Texture texture; Color color; void Start(){ Renderer rend = GetComponet<Renderer>(); rend.material = new Material(shader); //把着色器、材質、顏色復制給該物體 rend.material.mainTexture = texture; rend.material .color = color; }
Using colors
public class Example: MonoBehaviour{ Color colorStart = Color.red; Color colorEnd= Color.green; //顏色差值算法 float duration = 1.0f; Renderer rend; void Start(){ rend = GetComponent<Renderer>() } void Update(){ float lerp = Mathf.PingPong(Time.time, duration)/duration); //如果大於該值則截斷,返回上一個值, 然后開始往回縮小值,類似打乒乓球一樣 //該參數為,從0到1,在從1到0,如果是0則為純粹的紅色,如果為1則為純粹的綠色,動態的改變,包括顏色、位置 rend.material.color = Color.Lerp(colorStart, coloredEnd, lerp); //lerp只能是在0~1之間,所以上面一定要除以duration } }
紋理大小要滿足2的n次方(2、4、8、… 、1024、2048)等, Unity允許倒入的最大紋理為8k
Operating textures with codes
public class ExampleClass:MonoBehaviour{ public Texture[]texture; public float changeInteval = 0.33F; public Renderer rend; void Start( rend = GetComponet<Renderer>;) void Update(){ if (textures.Length == 0)return; int index = Methf.FloorTolnt(Time.time/changelntervla); index = index % textures.Length; rend.material.mainTexture = textures[index]; } }
物理組件(剛體組建)
Rigidbody:
Is Kinematic,勾選上物體運動將不會受物理引擎沒有關系,只純粹受transform影響,但是會受其他影響;雖然缸體自身不受力和碰撞的影響,但會通過力的碰撞傳導給別的物體;
Interpolate,差值;
Collosion Detection, 用於檢測與其他剛體的碰撞,其主要目的之一是防止物體之間的穿越 [默認為Discrete,表示每一幀做一次檢查,缺點是快速移動游戲對象會有穿透現象];
Constraints,剛體約束,可以凍結游戲對象在某個方向限制的移動和旋轉。eg.,如果選擇了Freeze Position中的X,表示凍結游戲對象在X軸上的運動;如果選擇Free Rotation下的X,表示凍結游戲對象在X軸上的旋轉。[ 使用價值,比如說掛鈎有時候只會在一個方向上亂動,所以凍結其他方向的數值,從而不讓該物體受到力的影響后在其他方向上亂晃 ];
通過控制面板,Rigibody類的使用方法:
public class fvc_rigibody_falling: MonoBehaviour{ private Rigibody rg; //通過代碼實現自由落體 void Start(){ rb = this. gameObject.AddComponent<Rigibody>(); rb.isKinematic = false; //受物理引擎影響,isKinematic不開啟 rb.detectCollisions = ture; rb.useGravity = true; rb.mass = 0.1f; } void Update(){ rb.drag = Mathf.Repeat(Time.time*15f, 8.0f); } }
//模擬一個球平拋運動 public class fvc_rigibody_falling: MonoBehaviour{ private Rigibody rg; //通過代碼實現自由落體 ///* [Range(0,20)] public int speed = 5; public GameObject humanbeing; */// privare Vector3 old_pos; void Start(){ rb = this. gameObject.AddComponent<Rigibody>(); rb.isKinematic = false; //受物理引擎影響,isKinematic不開啟 rb.detectCollisions = ture; rb.useGravity = true; rb.mass = 0.1f; rb.velocity = 5.0f* Vector3.right; //給物體增加一個速度 old_pos = transform.position; //humanbeing.transform.Translate(0,0,speed*Time.deltaTime,Space.World); } void FixedUpdate(){ //把拋物線畫出來 Debug.DrawLine(old_pos, transform.position, Color.red, 60,false); //把拋物線畫出來 old_pos = transform.position; } void Update(){ rb.drag = Mathf.Repeat(Time.time*15f, 8.0f); } }
angularVelocity表示角速度
centerOfMass表示剛體質心
//讓剛體旋轉 public class fvc_rigibody_falling: MonoBehaviour{ private Rigibody rg; //通過代碼實現自由落體 void Start(){ rb = this. gameObject.AddComponent<Rigibody>(); rb.angularVelcity = new Vector3(0,2.4f,0); //通過物理引擎來模擬旋轉效果,底層驅動是物理引擎 rb.detectCollisions = false; re.angularDrag = 0.01f; } void Update(){ if(Input. GetKeyDown(KeyCode.Space)){ rb.freezeRotation = true; } if(Input. GetKeyDown(KeyCode.Z)){ rb.centerOfMass = new Vector3(-0.5f,0,0); } if(Input. GetKeyDown(KeyCode.X)){ rb.centerOfMass = new Vector3(0,0,0); } } }
force表示力的矢量,該矢量長度表示力的大小,參數mode表示模式
public void AddForce(Vector3 force, ForceMode mode = ForceMode.Force); //給物體加力效果,第一個force表示給剛體的加速度,該力是在世界坐標下,eg,.橙色坐標
public void AddForceAtPosition(Vector3 force, Vector3 position, ForceMode mode = FforceMode.Force);//圍着質心的軸旋轉,和上面的一樣,不過多了個position參數
public void AddRelativeForce(Vector 3 force, ForceMode.mode = ForceMode.Force );//加相對力,相對於力的局部坐標下,eg,.綠色坐標

Impulse, 表示沖量,根據物理當中的動量定理更適用於模擬力作用的瞬間效果,比如沖擊力和爆炸效果
VelocityChange, 函數的第一個參數force表示游戲對象的速度改變了,此時游戲對象的、礎運動速度,與其質量無關
//添加一個力 public class fvc_rigibody_force: MonoBehaviour{ private Rigibody rg; //通過代碼實現自由落體 void Start(){ rb = this. gameObject.AddComponent<Rigibody>(); rb.mass = 0.5f; rb.UseGracity = false; rb.AddForce(new Vector3(4,0,0), ForceMode.Force); print(fvx_tools.to_string(rb.velocity)); } void Update(){ print( fvc_tools.to_string(rb.velocity)); } //void FixedUpdate專門用於物理引擎中的模擬,越跑越快 } }
//給物體增加速度 public class fvc_rigibody_force: MonoBehaviour { private Rigibody rb; void Start(){ this.transform.Rotate(0,0,-20); rb = this.gameObject.AddComponent<rigibody>(); rb.useGravity = false; rb.AddRelativeForce(new Vector3(0,1,0) ForceMode.velocitychange); } }
public Vector3 inertiaTensor:
inertiaTensor表示剛體的慣性藏糧,慣性越大,力相同,旋轉的越困難
//例子 public class fvc_rigibody_inertia: MonoBehaviour{ Rigibody rb; void start(){ rb = this.gameObject.AddComponent<Rigibody>()’ rb.inertiaTensor = new Vector(0.05f, 0.05f, 0.05f); rb.mass = 0.5f; rb.angularDrag = 0.0f; rb.useGravity = false; rb.AddForceAtPosition(new Vector3(0.0f, 0.0f, 6.0f), transform.position + new Vector3(0.5f,0,0)); } }
//例子

public void AddTorque(Vector3 torque, ForceMode mode = ForceMode.Force);//加個力矩,全局坐標下,讓他旋轉
public void AddTorque(float x , float y , float z, ,ForceMode mode = ForceMode.Force)//局部坐標下加力矩
//例子
public Vector3 position; //如果通過position改變剛體的位置,游戲對象的transform會在下一個物理模擬時刻被更新,通過這種方式改變游戲對象的位置比直接使用Transform的position要快,因為后者要重新計算游戲對象中的碰撞器(Collider)位置,同理,通過Rigidbody的rotation改變剛體的姿態進而可以更新游戲對象的Transform,同時,也比直接通過改變Transform的rotation要快
public Quaternion rotation;
//例子

public void MovePosition(Vector3 position);
public void MoveRotation(Quaternion rot); //通過函數調用可以用差值計算,如果不想用差值計算,兩者是一樣的,但如果要用到,這個和上面的函數兩者之間有差別
只有當isKinematic設置為false,施加力矩,碰撞相關的函數才可以起作用
碰撞器
給物體施加碰撞器來檢驗碰撞效果。Unity中,2D和3D分為了兩部份,本課主要講3D碰撞器。場景復雜的時候計算量會很大。

簡單碰撞器
指盒子碰撞器(Box Collider),球形碰撞器和膠囊碰撞器。
bounds類描述一個軸對齊的淚,主要用於游戲對象的碰撞檢測中,其構造函數為:public Bounds(Vector3……)
把最小點和最大點定下來,就可以把碰撞器定下來。
is Trigger,該碰撞器是否用作觸發器,勾選時成為觸發器,觸發器是碰撞器的組成部分,當碰撞器用做觸發器時,會觸發事件,但不受物理引擎控制,與其他對象進行碰撞,而是會發生穿透。不需要避規。
//盒子碰撞器代碼 public class fvc_box_collider:MonoBehaviour{ void Stare(){ BoxCollider bc = this.gameObject.GetComponent<BoxCollider>(); print(bc.center); print(bc.bounds.center); } }
物理材質
用來模擬物體接觸面的摩擦和彈性屬性。
Assets面板點擊右鍵/creat/Physic Material
dynamic Fiction 動摩擦系數(0~1)
static Fiction 靜摩擦系數
Bounciness 彈性(0~1)
Friction Combine表示兩個碰撞的物體間摩擦的組合(或互相影響)方式
Bounce Combine表示兩個物體碰撞組合的方式
(可以用面板來使用該組件,同時也可以自己寫代碼來編寫)

//模擬兩個球體碰撞,給sphere1賦予速度,sphere2靜止並接受碰撞 public class crash: MonoBehaviour{ public GameObject sphere1; //定義游戲對象的類,一個叫做sphere2,一個叫做sphere2 public GameObject sphere2; void Start(){ //對攝像機的定義 Camera cam = Camera.main; //創建一個攝像機 Vector3 pos = (sphere2.transform.position-shere1. transform.position)*0.5f+ shere1. transform.position; //計算sphere1的運動位置距離 cam.transform.position = pos+new Vector3(0,12,0); //把計算后的距離移動值賦給攝像機的定位值 cam.transform.LookAt(pos, Vector3.forward); //攝像機的看的方向 Vector3 dir = (sphere2.transform.position – shere1.transform.position).normalized; //給sphere1定義剛體組件數據 Rigidbody rb1 = shpere1.AddComponet<Rigidbody>(); //給sphere1賦予剛體組件 rb1.useGravity = false; //使用重力 rb1.mass = 1.0f; //定義質量 rb1.velocity = dir*3.0f; //定義速度 //給sphere2定義剛體組件數據 Rigidbody rb2 = shere2.AddComponent<Rigidbody>(); //給sphere2賦予剛體組件 rb2.useGravity = false; rb2.mass = 1.0f; //給sphere1定義物理材質數據 PhysicMaterial pm1 = new PhysicMaterial(); //定義一個物理材質的類,然后給他開辟新的空間存放 pm1.bounciness = 1.0f; //給sphere1定義摩擦 sphere1.GetComponent<SphereCollider>().material = pm1; //給sphere1定義已經創建的物理材質pm1,並且給該球體添加球形碰撞器 //給sphere2定義物理材質數據 PhysicMaterial pm2 = new PhysicMaterial(); pm2.bounciness = 1.0f; sphere2.GetComponent<SphereCollider>().material = pm2; } //更新數據並打印在測試板塊處 void Update(){ print(sphere1.GetComponent<Rigidbody>().Velocity); print(sphere2.GetComponent<Rigidbody>().Velocity); } }
