終於來到鐵人賽的最後一天了!
原先打算將製作好的遊戲放到網頁上,讓其他人也能直接遊玩,但在處理網頁部署時遇到一些問題,目前還沒辦法順利完成。
因此決定將先前已經完成、但尚未在文章中介紹的優化功能,作為最後一天的主題。這次主要介紹技能冷卻提示,讓玩家能更清楚知道技能什麼時候可以再次使用。
前幾天已經完成技能冷卻系統,但當時只有限制玩家在冷卻期間無法再次施放技能,畫面上並沒有明確顯示剩餘的冷卻時間。
因此這次在技能按鈕上加入黑色遮罩,透過Unity Image的fillAmount功能,讓遮罩隨著冷卻時間逐漸消失。
這樣玩家就能直接透過技能圖示,判斷冷卻是否結束。
這次主要修改原本的SkillManager,新增兩個技能的冷卻遮罩,並利用Coroutine製作共用的倒數功能。
技能一冷卻1秒,技能二冷卻5秒,兩種技能都能使用相同的方法控制遮罩。
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class SkillManager : MonoBehaviour
{
public static SkillManager Instance;
[Header("技能一 CD 轉圈遮罩")]
public Image skill1CooldownMask; // 拖入技能一按鈕上的黑遮罩 Image
private bool isClearScreenActive = false;
[Header("技能二 CD 轉圈遮罩")]
public Image skill2CooldownMask; // 拖入技能二按鈕上的黑遮罩 Image
private bool isSlowDownActive = false;
private void Awake()
{
if (Instance == null) Instance = this;
else Destroy(gameObject);
}
private void Start()
{
// 開局歸零遮罩
if (skill1CooldownMask != null) skill1CooldownMask.fillAmount = 0f;
if (skill2CooldownMask != null) skill2CooldownMask.fillAmount = 0f;
}
// 【技能一:全螢幕清場 (1 秒 CD)】
public void TriggerClearScreenSkill()
{
if (isClearScreenActive) return;
if (ScoreManager.Instance != null && ScoreManager.Instance.UseSkill1())
{
isClearScreenActive = true;
Target[] allTargets = FindObjectsOfType<Target>();
foreach (Target target in allTargets)
{
if (target != null) target.ForceKillBySkill();
}
StartCoroutine(CooldownRoutine(skill1CooldownMask, 1.0f, () => isClearScreenActive = false));
}
}
// 【技能二:全場緩速 (5 秒 CD)】
public void TriggerSlowDownSkill()
{
if (isSlowDownActive) return;
if (ScoreManager.Instance != null && ScoreManager.Instance.UseSkill2())
{
isSlowDownActive = true;
// 施加緩速
Target[] allTargets = FindObjectsOfType<Target>();
foreach (Target target in allTargets)
{
if (target != null) target.ApplySlowEffect(0.5f);
}
StartCoroutine(SlowDownEffectRoutine());
StartCoroutine(CooldownRoutine(skill2CooldownMask, 5.0f, () => isSlowDownActive = false));
}
}
// 5 秒後還原殭屍速度
private IEnumerator SlowDownEffectRoutine()
{
yield return new WaitForSeconds(5.0f);
Target[] remainingTargets = FindObjectsOfType<Target>();
foreach (Target target in remainingTargets)
{
if (target != null) target.RemoveSlowEffect();
}
}
// 通用 CD 轉圈倒數協程
private IEnumerator CooldownRoutine(Image maskImage, float cooldownTime, System.Action onComplete)
{
float timer = cooldownTime;
while (timer > 0f)
{
timer -= Time.deltaTime;
if (maskImage != null)
{
maskImage.fillAmount = timer / cooldownTime; // 隨時間減少填滿比例
}
yield return null;
}
if (maskImage != null) maskImage.fillAmount = 0f;
onComplete?.Invoke();
}
}
這次主要利用fillAmount控制黑色遮罩的顯示比例,冷卻開始時會先覆蓋技能圖示,再隨著時間逐漸減少,直到遮罩完全消失。
另外,也將冷卻倒數整理成共用的CooldownRoutine(),讓兩個技能能夠使用相同的程式碼,不需要分別製作倒數功能。
今天主要完成了以下幾個部分:
回顧這30天,從一開始練習HTML、CSS製作網頁,到後來使用Unity製作兩款不同玩法的小遊戲,過程中也接觸了不少新的功能與程式寫法。也讓我發現,除了土法煉鋼之外,還能透過共用方法等方式,讓程式碼變得更加精簡。
雖然有AI協助撰寫程式碼,但實際操作時還是會遇到各種問題,需要不斷測試與修改,才能讓不同的功能正常運作。
目前第一款小鳥遊戲已經先完成整理,第二款點擊目標遊戲則還有部分內容需要調整。原本希望能在最後一天將遊戲放到網頁上,但這次沒有順利完成。之後會再繼續研究Unity WebGL的發布方式,希望最終能讓其他人直接在網頁上遊玩。
最後,30天鐵人賽挑戰完成!