- Survival Shooter Tutorial 是Unity官方提供的一個3D生存類游戲的一個資源包浑测,里面包含了做一個簡單3D射擊游戲的通常所需要使用到的功能代碼以及資源翅阵,也可以了解到資源的一些調整和設置,總體來說是一個對于沒有做過3D游戲的初學者來說是一個很不錯的資源迁央,并且代碼注釋也比較完整掷匠,理解難度也不高。
- 適用Unity版本:4.7.1
- 資源下載界面
花了點時間看了下這個資源岖圈,理解起來并不難讹语,也是剛開始學習3D游戲的制作,以前都是2D蜂科,記錄下在這個資源包中所了解到的一些關于3D或者2D的知識點顽决。其實現(xiàn)在隨著Unity的發(fā)展,很多的要實現(xiàn)的功能已經(jīng)被封裝成了各式各樣的接口导匣,調用起來也很方便才菠,但是,這些接口背后所做的工作或是其他的一些數(shù)學物理基礎和概念贡定,如果了解的話更容易理解這個接口的實現(xiàn)原理和為什么這樣去實現(xiàn)赋访。
主要記錄一些腳本方面的筆記。
腳本部分主要接觸資源包腳本代碼的片段進行各個腳本想要記錄的知識點缓待,需要注意的是資源包導入到工程中是有如果有兩份同名代碼的時候蚓耽,需要記得區(qū)別游戲運行的是哪個地址的腳本,否則打印調試的時候可能出現(xiàn)沒有反應的情況旋炒。
CameraFollow.cs
這個腳本主要實現(xiàn)了攝像頭跟隨游戲主角移動的功能步悠。
void FixedUpdate ()
{
// Create a postion the camera is aiming for based on the offset from the target.
// 刷新相機當前應該所在位置
Vector3 targetCamPos = target.position + offset;
// Smoothly interpolate between the camera's current position and it's target position.
// 平滑移動相機的位置(當前位置,目標位置瘫镇,移動速度)
transform.position = Vector3.Lerp (transform.position, targetCamPos, smoothing * Time.deltaTime);
}
Note
- FixedUpdate:這個方法將按照固定的幀率被調用鼎兽,通常用來處理跟RigidBody芹壕,或者物理引擎相關的物體運動等方面的操作。
- Vector3.Lerp:用作兩個坐標點之間的線性插值接奈,通過不斷的修改坐標值踢涌,獲得一個相對于平滑的物體移動軌跡,第三個參數(shù)值越大序宦,移動速度越快睁壁。2D環(huán)境下可以使用Vector2.Lerp还惠。
EnemyManager.cs
這個腳本負責了怪物的創(chuàng)建左冬,主要是調用循環(huán)執(zhí)行在規(guī)定的時間周期內重復調用創(chuàng)建敵人臊旭。所有怪物的創(chuàng)建都通過該腳本埠况,只是創(chuàng)建的怪物不一樣而已。
// Call the Spawn function after a delay of the spawnTime and then continue to call after the same amount of time.
// 間隔時間執(zhí)行
InvokeRepeating ("Spawn", spawnTime, spawnTime);
// Find a random index between zero and one less than the number of spawn points.
// 隨機選擇出生地點
int spawnPointIndex = Random.Range (0, spawnPoints.Length);
Note
- InvokeRepeating("執(zhí)行方法名", 延后執(zhí)行時間, 周期時間)
- Random.Range(下限, 上限)饺谬,結果包含下限不包含上限
GameOverManager.cs
這個腳本主要負責的是玩家控制游戲的角色死亡之后的代碼邏輯陷虎。
// ... tell the animator the game is over.
// 播放游戲結束動畫
anim.SetTrigger ("GameOver");
Note
- Animator.SetTrigger("狀態(tài)名") 方法是用作從當前動畫狀態(tài)切換到目標動畫狀態(tài)泰涂,跟bool的區(qū)別是bool需要手動去設置bool的值是True還是False腌巾,而SetTrigger則自動回復狀態(tài)遂填,如果說setBool是兩個狀態(tài)的來回切換的話,SetTrigger就是點一次觸發(fā)一次到目標狀態(tài)澈蝙。SetTrigger也可以從自身狀態(tài)轉到自身狀態(tài)吓坚,在Transition的Sitting中設置。
PauseManager.cs
這個腳本主要是停止游戲時間然后切換游戲音樂狀態(tài)
Time.timeScale = Time.timeScale == 0 ? 1 : 0;
void Lowpass()
{
if (Time.timeScale == 0)
{
paused.TransitionTo(.01f);
}
else
{
unpaused.TransitionTo(.01f);
}
}
Note
- Time.scale,用來調整依賴于時間進行的一系列物理運動灯荧,這是所指的時間并不是現(xiàn)實時間而是Unity中的時間概念礁击,通常會影響FixedUpdate的調用頻率而不影響Update和LateUpdate。
- AudioMixerSnapshot.TransitionTo(),在指定的時間間隔內對此快照執(zhí)行插值轉換逗载。暫時還不是很理解哆窿。(待解決)有興趣再挖一下。
EnemyAttack.cs
這個腳本主要判斷是否接觸了玩家厉斟,如果是的話則開始攻擊也就是扣血挚躯。
Note
- void OnTriggerEnter (Collider other)
- void OnTriggerExit(Collider other)
- void OnTriggerStay(Collider other)
- 這三個觸發(fā)器方法僅當碰撞體使用Trigger作為輸入的時候才有效也就是碰撞體上面的isTrigger
EnemyHealth.cs
這個腳本主要控制怪物的存亡和受到攻擊播放例子特效。
// Turn the collider into a trigger so shots can pass through it.
// 修改碰撞體isTrigger捏膨,使其被物理引擎忽略秧均,從而讓子彈穿過,也使得可以穿過碰撞體
capsuleCollider.isTrigger = true;
Note
- 當碰撞體上的IsTrigger被設置為True号涯,那么該物體就會不受到物理引擎的影響,從可以可以穿過其他碰撞體锯七。這里是為了可以讓怪物死后下沉以及讓射擊穿過已經(jīng)死亡的怪物链快。
EnemyMovement.cs
這個腳本主要控制怪物的朝向以及向玩家尋路靠近。
Update()
{
// ... set the destination of the nav mesh agent to the player.
// 使用Unity AI自動尋路
nav.SetDestination (player.position);
}
Note
- UnityEngine.AI.NavMeshAgent.setSetDestination(),提供了將綁定的物體尋路到固定坐標的方法眉尸,通過Update逐幀調用域蜗,從而不斷刷新尋路坐標而逐漸靠近目標坐標或者物體巨双。
PlayerMovement.cs
這個腳本主要負責響應玩家的輸入,對控制的角色進行移動以及瞄準方向的改變霉祸。
// Create a layer mask for the floor layer.
// 得到的值是2的需要獲取的Layer的次方筑累,用于模擬射線忽略其他的碰撞體
floorMask = LayerMask.GetMask ("Floor");
void Move (float h, float v)
{
// Set the movement vector based on the axis input.
// 設置方向
movement.Set (h, 0f, v);
// 歸一化方向向量,乘以速度和時間獲得移動距離
// Normalise the movement vector and make it proportional to the speed per second.
movement = movement.normalized * speed * Time.deltaTime;
// Move the player to it's current position plus the movement.
// 移動物體到新的坐標丝蹭,使用剛體的movePostion更自然流暢
playerRigidbody.MovePosition (transform.position + movement);
}
if(Physics.Raycast (camRay, out floorHit, camRayLength, floorMask))
Note
- 通過LayerMask.GetMask()獲得的Layer ID是Int 32位的二進制形式保存的慢宗,這也是為什么一共只有32個Layer可以設置,獲得的值也是2的冪次方奔穿。
- 使用RigidBody.MovePosition會比直接設置Transform的坐標更流暢自然镜沽。
- 模擬射線時傳入Layer的ID就可以模擬射線的時候忽略其他層的影響。
PlayerHealth.cs
這個腳本控制玩家的血量贱田,判斷玩家是否游戲結束缅茉。
// ... transition the colour back to clear.
// 從紅色到透明
damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
Note
- Color.Lerp用來做顏色的插值過渡。
PlayerShooting.cs
這個腳本主要負責玩家射擊功能男摧,射線模擬蔬墩,確認擊中的坐標,通知怪物播放受擊例子特效和扣血耗拓。
Input.GetButton ("Fire1")
gunLine.SetPosition (0, transform.position);
Note
- Input.GetButton用來獲取定義好的輸入信號筹我。
- LineRenderer.SetPosition用來設定描線的節(jié)點。