目录
前言
从零开始,用 Unity 打造一个"字母拼词"小游戏!本系列将带你一步步完成从界面布局、逻辑实现到动画优化与发布的全过程。无需复杂算法,新手也能轻松上手,最终做出一款可玩又有趣的文字益智游戏。
创建通关进度UI
创建一个通过进度的UI,新建一个空的游戏物体,命名为ProgressUI,下面包含一个进度条的背景图Background(Image组件),一个进度条Progress(Image组件)和一个进度文本(Text组件)。

因为要制作进度条,Progress上面的Image组件需要做一些参数设置,Image Type需要设置为Filled(填充),Fill Method需要设置为Horizontal(水平),Fill Origin设置为Left(从左往右填充)。

多单词顺序通关进度逻辑
在GameManager代码中关联进度相关的组件,声明一个Image组件以及一个TMP Text组件,用来做进度的UI显示。
cs
[Header("Progression")]
[SerializeField] private TMP_Text _progressText;
[SerializeField] private Image _progressImage;
同时在GameManager中写死一个多单词字符串数组用来做测试,以及一个int型的序号记录当前单词到第几个了,此处声明了包含三个单词的字符串数组。
cs
private readonly string[] _words = {
"Apple", "Banana" , "Pear"
};
private int _currentWordIndex;
将之前的GameManager中的Start方法做修改,将生成单词字母的方法封装起来,因为后续进行下一个单词拼写的时候会复用,然后增加一个更新进度UI的方法。在Start方法中设置初始的单词序号为0,即从第一个单词开始,然后更新UI,并且设置单词字母。
cs
private void Start()
{
_resultBlocker.SetActive(false);
_resultImage.gameObject.SetActive(false);
_confirmButton.interactable = false;
_currentWordIndex = 0;
UpdateProgress();
SetupWordLetters();
}
private void UpdateProgress()
{
var currentWordNumber = _currentWordIndex + 1;
_progressText.text = $"{currentWordNumber}/{_words.Length}";
_progressImage.fillAmount = (float)currentWordNumber / _words.Length;
}
private void SetupWordLetters()
{
string firstWord = _words[_currentWordIndex];
var lettersArray = firstWord.ToCharArray();
var randomLettersArray = ShuffleLetters(lettersArray);
foreach (var letter in firstWord)
{
var wordLetterSlot = Instantiate(_wordLetterSlotPrefab, _wordLettersSlotsSpawnPoint);
wordLetterSlot.Initialize(letter.ToString());
wordLetterSlot.OnLetterClicked += HandleOnLetterSlotClicked;
_wordLetterSlots.Add(wordLetterSlot);
}
foreach (var randomLetter in randomLettersArray)
{
var wordLetter = Instantiate(_wordLetterPrefab, _wordLettersSpawnPoint);
wordLetter.Initialize(randomLetter.ToString());
wordLetter.OnLetterClicked += HandleOnLetterClicked;
_wordLetters.Add(wordLetter);
}
}
运行效果如下所示。
初始化第一个单词字母
完成了第一个单词字母拼写的逻辑后,接下来就是后续的单词字母。即点击Confirm后如果还有单词,则继续生成下一个。在点击Confirm按钮后,会先调用一个协程用来显示当前题目的结果,先暂时用1秒钟等待,等待期间需要显示一个Blocker的图片(透明度为1)防止玩家点击其他可交互的按钮出现Bug,1秒等待结束后,检测当前的单词序号是否已经达到当前单词组的最后一个,若最后一个则打出日志显示完成该词组。若未完成词组,则将当前序号加1,清除掉之前的单词,然后生成新的单词字母并更新UI进度。
cs
private void HandleOnConfirmButtonClicked()
{
_resultBlocker.SetActive(true);
var isCorrect = false;
foreach (var wordLetterSlot in _wordLetterSlots)
{
isCorrect = wordLetterSlot.CheckIsCorrect();
}
_resultImage.gameObject.SetActive(true);
_resultImage.sprite = isCorrect ? _correctSprite : _wrongSprite;
if (_resultDelayCoroutine != null)
{
StopCoroutine(_resultDelayCoroutine);
}
_resultDelayCoroutine = StartCoroutine(ResultDelay());
}
private IEnumerator ResultDelay()
{
yield return new WaitForSeconds(1f);
_resultBlocker.SetActive(false);
if (_currentWordIndex == _words.Length - 1)
{
Debug.Log("Complete");
yield break;
}
_currentWordIndex++;
ClearUpWordLetters();
_resultImage.gameObject.SetActive(false);
_confirmButton.interactable = false;
UpdateProgress();
SetupWordLetters();
}
private void ClearUpWordLetters()
{
foreach (var wordLetterSlot in _wordLetterSlots)
{
Destroy(wordLetterSlot.gameObject);
}
_wordLetterSlots.Clear();
foreach (var wordLetter in _wordLetters)
{
Destroy(wordLetter.gameObject);
}
_wordLetters.Clear();
}
最终的结果如下所示。
