Survival Shooter Tutorial 筆記

  • Survival Shooter Tutorial 是Unity官方提供的一個(gè)3D生存類游戲的一個(gè)資源包,里面包含了做一個(gè)簡(jiǎn)單3D射擊游戲的通常所需要使用到的功能代碼以及資源,也可以了解到資源的一些調(diào)整和設(shè)置,總體來(lái)說(shuō)是一個(gè)對(duì)于沒(méi)有做過(guò)3D游戲的初學(xué)者來(lái)說(shuō)是一個(gè)很不錯(cuò)的資源,并且代碼注釋也比較完整,理解難度也不高。
  • 適用Unity版本:4.7.1
  • 資源下載界面

花了點(diǎn)時(shí)間看了下這個(gè)資源,理解起來(lái)并不難,也是剛開(kāi)始學(xué)習(xí)3D游戲的制作,以前都是2D,記錄下在這個(gè)資源包中所了解到的一些關(guān)于3D或者2D的知識(shí)點(diǎn)。其實(shí)現(xiàn)在隨著Unity的發(fā)展,很多的要實(shí)現(xiàn)的功能已經(jīng)被封裝成了各式各樣的接口,調(diào)用起來(lái)也很方便,但是,這些接口背后所做的工作或是其他的一些數(shù)學(xué)物理基礎(chǔ)和概念,如果了解的話更容易理解這個(gè)接口的實(shí)現(xiàn)原理和為什么這樣去實(shí)現(xiàn)。

主要記錄一些腳本方面的筆記。

腳本部分主要接觸資源包腳本代碼的片段進(jìn)行各個(gè)腳本想要記錄的知識(shí)點(diǎn),需要注意的是資源包導(dǎo)入到工程中是有如果有兩份同名代碼的時(shí)候,需要記得區(qū)別游戲運(yùn)行的是哪個(gè)地址的腳本,否則打印調(diào)試的時(shí)候可能出現(xiàn)沒(méi)有反應(yīng)的情況。

CameraFollow.cs

這個(gè)腳本主要實(shí)現(xiàn)了攝像頭跟隨游戲主角移動(dòng)的功能。

        void FixedUpdate ()
        {
            // Create a postion the camera is aiming for based on the offset from the target.
            // 刷新相機(jī)當(dāng)前應(yīng)該所在位置
            Vector3 targetCamPos = target.position + offset;

            // Smoothly interpolate between the camera's current position and it's target position.
            // 平滑移動(dòng)相機(jī)的位置(當(dāng)前位置,目標(biāo)位置,移動(dòng)速度)
            transform.position = Vector3.Lerp (transform.position, targetCamPos, smoothing * Time.deltaTime);
        }

Note

  • FixedUpdate:這個(gè)方法將按照固定的幀率被調(diào)用,通常用來(lái)處理跟RigidBody,或者物理引擎相關(guān)的物體運(yùn)動(dòng)等方面的操作。
  • Vector3.Lerp:用作兩個(gè)坐標(biāo)點(diǎn)之間的線性插值,通過(guò)不斷的修改坐標(biāo)值,獲得一個(gè)相對(duì)于平滑的物體移動(dòng)軌跡,第三個(gè)參數(shù)值越大,移動(dòng)速度越快。2D環(huán)境下可以使用Vector2.Lerp。
EnemyManager.cs

這個(gè)腳本負(fù)責(zé)了怪物的創(chuàng)建,主要是調(diào)用循環(huán)執(zhí)行在規(guī)定的時(shí)間周期內(nèi)重復(fù)調(diào)用創(chuàng)建敵人。所有怪物的創(chuàng)建都通過(guò)該腳本,只是創(chuàng)建的怪物不一樣而已。

    // Call the Spawn function after a delay of the spawnTime and then continue to call after the same amount of time.
    // 間隔時(shí)間執(zhí)行
    InvokeRepeating ("Spawn", spawnTime, spawnTime);
    // Find a random index between zero and one less than the number of spawn points.
    // 隨機(jī)選擇出生地點(diǎn)
    int spawnPointIndex = Random.Range (0, spawnPoints.Length);

Note

  • InvokeRepeating("執(zhí)行方法名", 延后執(zhí)行時(shí)間, 周期時(shí)間)
  • Random.Range(下限, 上限),結(jié)果包含下限不包含上限

GameOverManager.cs

這個(gè)腳本主要負(fù)責(zé)的是玩家控制游戲的角色死亡之后的代碼邏輯。

    // ... tell the animator the game is over.
    // 播放游戲結(jié)束動(dòng)畫(huà)
    anim.SetTrigger ("GameOver");

Note

  • Animator.SetTrigger("狀態(tài)名") 方法是用作從當(dāng)前動(dòng)畫(huà)狀態(tài)切換到目標(biāo)動(dòng)畫(huà)狀態(tài),跟bool的區(qū)別是bool需要手動(dòng)去設(shè)置bool的值是True還是False,而SetTrigger則自動(dòng)回復(fù)狀態(tài),如果說(shuō)setBool是兩個(gè)狀態(tài)的來(lái)回切換的話,SetTrigger就是點(diǎn)一次觸發(fā)一次到目標(biāo)狀態(tài)。SetTrigger也可以從自身狀態(tài)轉(zhuǎn)到自身狀態(tài),在Transition的Sitting中設(shè)置。

PauseManager.cs
這個(gè)腳本主要是停止游戲時(shí)間然后切換游戲音樂(lè)狀態(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,用來(lái)調(diào)整依賴于時(shí)間進(jìn)行的一系列物理運(yùn)動(dòng),這是所指的時(shí)間并不是現(xiàn)實(shí)時(shí)間而是Unity中的時(shí)間概念,通常會(huì)影響FixedUpdate的調(diào)用頻率而不影響Update和LateUpdate。
  • AudioMixerSnapshot.TransitionTo(),在指定的時(shí)間間隔內(nèi)對(duì)此快照?qǐng)?zhí)行插值轉(zhuǎn)換。暫時(shí)還不是很理解。(待解決)有興趣再挖一下。

EnemyAttack.cs
這個(gè)腳本主要判斷是否接觸了玩家,如果是的話則開(kāi)始攻擊也就是扣血。

Note

  • void OnTriggerEnter (Collider other)
  • void OnTriggerExit(Collider other)
  • void OnTriggerStay(Collider other)
  • 這三個(gè)觸發(fā)器方法僅當(dāng)碰撞體使用Trigger作為輸入的時(shí)候才有效也就是碰撞體上面的isTrigger

EnemyHealth.cs
這個(gè)腳本主要控制怪物的存亡和受到攻擊播放例子特效。

        // Turn the collider into a trigger so shots can pass through it.
        // 修改碰撞體isTrigger,使其被物理引擎忽略,從而讓子彈穿過(guò),也使得可以穿過(guò)碰撞體
            capsuleCollider.isTrigger = true;

Note

  • 當(dāng)碰撞體上的IsTrigger被設(shè)置為T(mén)rue,那么該物體就會(huì)不受到物理引擎的影響,從可以可以穿過(guò)其他碰撞體。這里是為了可以讓怪物死后下沉以及讓射擊穿過(guò)已經(jīng)死亡的怪物。

EnemyMovement.cs
這個(gè)腳本主要控制怪物的朝向以及向玩家尋路靠近。

    Update()
    {
        // ... set the destination of the nav mesh agent to the player.
        // 使用Unity AI自動(dòng)尋路
        nav.SetDestination (player.position);
    }

Note

  • UnityEngine.AI.NavMeshAgent.setSetDestination(),提供了將綁定的物體尋路到固定坐標(biāo)的方法,通過(guò)Update逐幀調(diào)用,從而不斷刷新尋路坐標(biāo)而逐漸靠近目標(biāo)坐標(biāo)或者物體。

PlayerMovement.cs
這個(gè)腳本主要負(fù)責(zé)響應(yīng)玩家的輸入,對(duì)控制的角色進(jìn)行移動(dòng)以及瞄準(zhǔn)方向的改變。

        // 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.
            // 設(shè)置方向
            movement.Set (h, 0f, v);
            // 歸一化方向向量,乘以速度和時(shí)間獲得移動(dòng)距離
            // 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.
            // 移動(dòng)物體到新的坐標(biāo),使用剛體的movePostion更自然流暢
            playerRigidbody.MovePosition (transform.position + movement);
        }
        if(Physics.Raycast (camRay, out floorHit, camRayLength, floorMask))

Note

  • 通過(guò)LayerMask.GetMask()獲得的Layer ID是Int 32位的二進(jìn)制形式保存的,這也是為什么一共只有32個(gè)Layer可以設(shè)置,獲得的值也是2的冪次方。
  • 使用RigidBody.MovePosition會(huì)比直接設(shè)置Transform的坐標(biāo)更流暢自然。
  • 模擬射線時(shí)傳入Layer的ID就可以模擬射線的時(shí)候忽略其他層的影響。

PlayerHealth.cs
這個(gè)腳本控制玩家的血量,判斷玩家是否游戲結(jié)束。

        // ... transition the colour back to clear.
        // 從紅色到透明
        damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);

Note

  • Color.Lerp用來(lái)做顏色的插值過(guò)渡。

PlayerShooting.cs
這個(gè)腳本主要負(fù)責(zé)玩家射擊功能,射線模擬,確認(rèn)擊中的坐標(biāo),通知怪物播放受擊例子特效和扣血。

Input.GetButton ("Fire1")
gunLine.SetPosition (0, transform.position);

Note

  • Input.GetButton用來(lái)獲取定義好的輸入信號(hào)。
  • LineRenderer.SetPosition用來(lái)設(shè)定描線的節(jié)點(diǎn)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • This article is a record of my journey to learn Game Deve...
    蔡子聰閱讀 4,098評(píng)論 0 9
  • 一、Unity簡(jiǎn)介 1. Unity界面 Shift + Space : 放大界面 Scene界面按鈕渲染模式2D...
    MYves閱讀 8,662評(píng)論 0 22
  • 111. [動(dòng)畫(huà)系統(tǒng)]如何將其他類型的動(dòng)畫(huà)轉(zhuǎn)換成關(guān)鍵幀動(dòng)畫(huà)? 動(dòng)畫(huà)->點(diǎn)緩存->關(guān)鍵幀 112. [動(dòng)畫(huà)]Unit...
    胤醚貔貅閱讀 13,510評(píng)論 3 88
  • 目錄 喬生媽媽走的那天,是5月21日。在那之前,她的病情已經(jīng)得到控制,一切都在朝好的方向發(fā)展,可誰(shuí)曾想到還是這樣走...
    dd仔閱讀 553評(píng)論 0 2
  • 01 三個(gè)月前,梔子從公司辭職。她收到了父親病危的通知。 父親是梔子在這世界上唯一的親人, 盡管她恨他—— 小時(shí)候...
    18372dad7cba閱讀 594評(píng)論 0 1

友情鏈接更多精彩內(nèi)容