Unity3D指令碼--常用程式碼集
1. 訪問其它物體
1) 使用Find()和FindWithTag()命令Find和FindWithTag是非常耗費時間的命令,要避免在Update()中和每一幀都被呼叫的函式中使用。在Start()和Awake()中使用,使用公有變數把它儲存下來,以供後面使用。如: 公有變數= GameObject.Find("物體名"); 或 公有變數= GameObject.FindWithTag("物體標籤名");2) 把一個物體拖到公有變數上3) 引用指令碼所在的物體的元件上的引數,如下所示: transform.position = Vector3(0,5,4); renderer.material.color = Color.blue; light.intensity = 8 ;
4) SendMessge()命令:一個呼叫其它物體上指令(即物體上的指令碼中的函式)的方法5) GetComponent()命令:引用一個元件
例項程式碼如下所示:
#pragma strictvar thelight:GameObject;var thetxt:GameObject;var theCube1:GameObject;function Start () { thelight = GameObject.Find("Spotlight"); thetxt = GameObject.FindWithTag("txt"); theCube1 = GameObject.Find("Cube1" );}function Update () { if(Input.GetKey(KeyCode.L)){ thelight.light.intensity += 0.01; thetxt.GetComponent(GUIText).text = "當前亮度:"+thelight.light.intensity; } if(Input.GetKey(KeyCode.K)){ thelight.light.intensity -= 0.01; thetxt.GetComponent(GUIText).text = "當前亮度:"+thelight.light.intensity; } if(Input.GetKey(KeyCode.S)){ theCube1.SendMessage("OnMouseDown" ); //呼叫theCube1所有指令碼中的OnMouseDown函式 }}
2. 製作第一人稱控制器
第一人稱控制器指令碼程式碼如下所示:
#pragma strictvar speed:float=6.0;var jumpspeed:float=8.0;var gravity:float=20.0;private var movedirection:Vector3=Vector3.zero;private var grounded:boolean=false;function Start () {}function FixedUpdate () { if(grounded){ movedirection=Vector3(Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical")); //Transforms direction from local space to world space. movedirection=transform.TransformDirection(movedirection); movedirection *= speed; if(Input.GetButton("Jump")){ movedirection.y = jumpspeed; } } movedirection.y -= gravity*Time.deltaTime; //Move command var controller:CharacterController = GetComponent(CharacterController); var flags = controller.Move(movedirection*Time.deltaTime); //CollisionFlags.CollidedBelow 底部發生了碰撞 //CollisionFlags.CollidedSides 四周發生了碰撞 //CollisionFlags.CollidedAbove 頂端發生了碰撞 grounded = (flags & CollisionFlags.CollidedBelow)!=0;}//強制Unity為本指令碼所依附的物體增加角色控制器元件@script RequireComponent(CharacterController)
3. 匯入3DMax模型
在3DMax(.fbx檔案)把顯示單位和系統單位設定為cm,再匯入到Unity3D(單位為m)中時,則大小相同。
4. 互動功能(自動開關門)
4.1 ControllerColliderHit(碰撞檢測)
玩家撞到門時,門才能開。
其相關程式碼如下所示,需要對模型的動畫進行分割,以下指令碼綁在玩家身上:
#pragma strictprivate var doorisopen:boolean = false;private var doortimer:float = 0.0;private var currentdoor:GameObject;var door_open_time:float = 5.0;var door_open_sound:AudioClip;var door_shut_sound:AudioClip;function Update(){ if(doorisopen){ doortimer += Time.deltaTime; if(doortimer > door_open_time) { doortimer = 0.0; door(false,door_shut_sound,"doorshut",currentdoor); } }}//檢測玩家是否與門相撞function OnControllerColliderHit(hitt:ControllerColliderHit){ //hitt為與玩家相撞的碰撞體 print("test1"); if(hitt.gameObject.tag == "playerDoor" && doorisopen == false){ print("test2"); door(true,door_open_sound,"dooropen",hitt.gameObject); currentdoor = hitt.gameObject; }}function door(doorcheck:boolean,a_clip:AudioClip,ani_name:String,thisdoor:GameObject){ doorisopen=doorcheck; thisdoor.audio.PlayOneShot(a_clip); //聲音取消3D效果,否則無法播放 thisdoor.transform.parent.animation.Play(ani_name);}
4.2 RaycastHit(光線投射)
玩家必須面對門時,光線投射到門時,門才能開。
其檢測碰撞程式碼如下所示,以下指令碼綁在玩家身上:
function Update(){ var hit:RaycastHit; //hit為與投射光線相遇的碰撞體 if(Physics.Raycast(transform.position,transform.forward,hit,3)){ print("collider happen" + hit.collider.gameObject.tag); if(hit.collider.gameObject.tag == "playerDoor"){ var currentdoor:GameObject = hit.collider.gameObject; currentdoor.SendMessage("doorcheck"); print("call doorcheck"); } }}
門身上的指令碼如下所示:
#pragma strictprivate var doorisopen:boolean = false;private var doortimer:float = 0.0;//private var currentdoor:GameObject;var door_open_time:float = 5.0;var door_open_sound:AudioClip;var door_shut_sound:AudioClip;function Update(){ if(doorisopen){ doortimer += Time.deltaTime; if(doortimer > door_open_time) { doortimer = 0.0; door(false,door_shut_sound,"doorshut"); } }}function doorcheck(){ if(!doorisopen){ door(true,door_open_sound,"dooropen"); }}function door(doorcheck:boolean,a_clip:AudioClip,ani_name:String){ doorisopen=doorcheck; audio.PlayOneShot(a_clip); //聲音取消3D效果,否則無法播放 transform.parent.animation.Play(ani_name);}
4.3 OnTriggerEnter(觸發器)
只要一進入觸發區域,門就可以開啟。需要特別注意調整小房子的Box Collider的大小和位置。
以下指令碼綁在門所在的小房子上:
#pragma strictfunction OnTriggerEnter (col:Collider) { //col為闖入此區域的碰撞體 if(col.gameObject.tag == "Player"){ transform.FindChild("door").SendMessage("doorcheck"); }}
4.4 OnCollisionEnter
檢測兩個普通碰撞體之間的碰撞,需要發力,才能發生碰撞。不能與第一人稱控制器發生碰撞。
4.5 互動總結
1) OnControllerColliderHit
專門提供給角色控制器使用,以供角色控制器檢測與其它物體發生了碰撞。
它與觸發模式的碰撞體不能發生碰撞,而且還會穿過其物體。
以下指令碼繫結在玩家(第一人稱控制器)身上。
function OnControllerColliderHit (hit:ControllerColliderHit) { if(hit.gameObject.name != "Plane") gameObject.Find("wenzi").guiText.text = hit.gameObject.name;}
2) RaycastHit它不是一個事件,而是一個命令,可以需要的地方呼叫它來發射一條光線來進行檢測。
可以與觸發模式的碰撞體發生碰撞,但也會穿過其物體。
以下指令碼繫結在玩家(第一人稱控制器)身上。
#pragma strictvar hit:RaycastHit;function Update () { if(Physics.Raycast(transform.position,transform.forward,hit,2)){ if(hit.collider.gameObject.name != "Plane"){ gameObject.Find("wenzi").guiText.text = hit.collider.gameObject.name; } }}
3) OnTriggerEnter以下指令碼繫結在與第一人稱控制器相撞的物體上。
#pragma strictfunction OnTriggerEnter (col:Collider) { gameObject.Find("wenzi").guiText.text = col.gameObject.name;}
4) OnCollisionEnter
檢測兩個普通碰撞體之間的碰撞,需要發力,才能發生碰撞。不能與第一人稱控制器發生碰撞。
5. 播放聲音
5.1 audio.Play()
GameObject有Audio Source元件,且在Audio Source元件中設定了Audio Clip。
5.2 audio.PlayOneShot
var door_open_sound:AudioClip; //在檢測面板中設定audio clip;當然必須有Audio Source元件,但不需要設定Audio Clipfunction myAudioPlay(){ audio.PlayOneShot(door_open_sound); //聲音取消3D效果,否則無法播放}
5.3 AudioSource.PlayClipAtPoint
此種播放方式最佳,節約資源。
var collectSound:AudioClip; //在檢測面板中設定其值function pickupCell(){ //臨時申請一個AudioSource,播放完了即時銷燬 AudioSource.PlayClipAtPoint(collectSound,transform.position);}
6. 銷燬物體
Destroy(gameObject); //即時銷燬物體
Destroy(gameObject,3.0); // 3秒之後銷燬物體
7. 給剛體增加速度
方法一:
#pragma strictvar throwsound:AudioClip;var coconut_bl:Rigidbody; //為預製物體function Update () { if(Input.GetButtonDown("Fire1")){ audio.PlayOneShot(throwsound); var newcoconut:Rigidbody = Instantiate(coconut_bl,transform.position, transform.rotation); newcoconut.velocity=transform.forward*30.0; //設定剛體速度 }}
8. 忽視碰撞命令
使用這兩個碰撞器碰撞時不發生效果
Physics.IgnoreCollision(transform.root.collider,newcoconut.collider,true);
9. 協同程式及動畫播放
協同程式:類似子執行緒,在執行本程式碼的同時,運動指令碼中的其它程式碼。
#pragma strict// this script will be attached to target objectprivate var beenhit:boolean = false;private var targetroot:Animation; var hitsound:AudioClip;var resetsound:AudioClip;var resettime:float=3.0;function Start () { targetroot = transform.parent.transform.parent.animation;}function OnCollisionEnter (theobject:Collision) { if(beenhit == false && theobject.gameObject.name == "coconut"){ StartCoroutine("targethit"); //協同程式:類似子執行緒,在執行本程式碼的同時,運動指令碼中的其它程式碼 }}function targethit(){ audio.PlayOneShot(hitsound); // 播放聲音 targetroot.Play("down"); // 播放動畫 beenhit = true; yield new WaitForSeconds(resettime); // wait for 3s audio.PlayOneShot(resetsound); targetroot.Play("up"); beenhit=false;}
10. 動態新增和刪除指令碼
#pragma strictvar obj:GameObject;var myskin:GUISkin;function Start () {}function Update () {}function OnGUI(){ //GUI.skin = myskin; if(GUILayout.Button("Add_Component",GUILayout.Height(40),GUILayout.Width(110))){ obj.AddComponent("xuanzhuan"); // xuanzhuan為一個指令碼xuanzhuan。js } if(GUILayout.Button("Del_Component",GUILayout.Height(40),GUILayout.Width(110))){ var script:Object = obj.GetComponent("xuanzhuan"); Destroy(script); } }
11. 粒子系統
粒子系統是在三維空間中渲染出來的二維影象,主要用於表現煙、火、水滴和落葉等效果。
粒子系統由:粒子發射器、粒子動畫器和粒子渲染器組成。
12. for迴圈和陣列
使用Unity3D內建陣列:
var cms:Render[];fucntion Update(){ for(var co:Render in cms){ co.material.color = Color.red; }}
使用Unity3D非內建陣列Array:var wenzi_bl:GUIText;var arr = new Array(9,12,65,58); //靜態陣列var barr = new Array(); //動態陣列fucntion Start(){ barr.Push("push1"); barr.Push("push2"); arr.Sort(); wenzi_bl.text = arr.join(",") + " ,arr長度:" + arr.length+ " >>" + barr + " barr長度:" + barr.length;}
13. 延時函式及載入新場景
function OnMouseDown () { audio.PlayOneShot(beep); yield new WaitForSeconds(0.35); Application.LoadLevel(levelToload);}
14. 建立視窗及此視窗中的內容
static var windowSwitch:boolean = false;private var windowRect = Rect(300,280,240,200);function Update(){ if(Input.GetKeyDown(KeyCode.Escape)){ windowSwitch = !windowSwitch; }}function OnGUI(){ if(windowSwitch){ windowRect = GUI.Window(0,windowRect,WindowContain,"測試視窗"); }}// show window contentsfunction WindowContain(){ if(GUI.Button(Rect(70,70,100,20),"關閉音樂")){ gameObject.Find("Terrain").GetComponent(AudioSource).enabled = false; } if(GUI.Button(Rect(70,100,100,20),"播放音樂")){ gameObject.Find("Terrain").GetComponent(AudioSource).enabled = true; } if(GUI.Button(Rect(70,130,100,20),"關閉視窗")){ windowSwitch = false; } if(GUI.Button(Rect(70,160,100,20),"退出遊戲")){ Application.Quit(); } GUI.DragWindow(new Rect(0,0,1000,1000));}
15. 選單製作方法
1) GUITexture
2) GUI物件:GUI.Window和GUISkin。