原先今天想要把水管替換成其他物件,但自己嘗試遊完總感覺怪怪的,才發現是場景沒跟著動,所以今天就把目標定在場景能隨著水管的速度動。
這功能算是我第一次接觸,畢竟之前是做畫面跟玩家同步移動,所以請Gemini教我有哪一些方式能實現這種功能。
有兩種方式能實現。
雙圖拼接循環:先複製兩張圖,第二張圖緊貼第一張圖的右側。當第一張圖移出畫面後,將它移到第二張圖的後方,持續循環,達到移動的效果。
材質偏移:只需要一張圖,用程式碼推動圖片材質的UV座標。
我選擇用第一種方式,不用更改圖片設定就能達成。
因此我希望做到的功能主要有:
using UnityEngine;
public class BackgroundRepeat : MonoBehaviour
{
[Header("目標對象")]
[Tooltip("拉入場景中的 PipeSpawner 物件,用來同步最新速度")]
public PipeSpawner pipeSpawner;
[Header("滾動參數")]
[Tooltip("速度倍率:地板設為 1(與水管同速);遠景背景設為 0.3(呈現遠近景深)")]
public float speedMultiplier = 1f;
[Tooltip("單張圖片的寬度(若填 0,程式會自動讀取 SpriteRenderer)")]
public float textureWidth = 0f;
private Vector3 startPosition;
void Start()
{
// 紀錄最開始的起始位置
startPosition = transform.position;
// 如果 Inspector 裡面忘記拉 PipeSpawner,自動在場景中搜尋
if (pipeSpawner == null)
{
pipeSpawner = FindObjectOfType<PipeSpawner>();
}
// 自動計算單張圖片的寬度
if (textureWidth == 0)
{
SpriteRenderer sprite = GetComponentInChildren<SpriteRenderer>();
if (sprite != null)
{
textureWidth = sprite.bounds.size.x;
}
}
}
void Update()
{
// 1. 即時讀取 PipeSpawner 目前的速度(若找不到則預設為 4f)
float currentPipeSpeed = (pipeSpawner != null) ? pipeSpawner.currentSpeed : 4f;
// 2. 算出行進速度
float actualSpeed = currentPipeSpeed * speedMultiplier;
// 3. 向左移動
transform.position += Vector3.left * actualSpeed * Time.deltaTime;
// 4. 無縫歸位機制:當左移距離超過「一張圖的寬度」時,立刻重置回起點
if (transform.position.x <= startPosition.x - textureWidth)
{
transform.position = startPosition;
}
}
}
這次比較特別的是,背景的移動速度不是直接寫死,而是會取得目前水管的速度,再乘上設定好的速度倍率。
例如地板可以設定成與水管相同的速度,其他比較遠的背景則可以使用較慢的速度,讓不同的背景產生不同的移動速度。
這樣除了可以讓畫面持續移動,也能為之後增加視差效果留下空間。
沒意外的話會開始更改障礙物,不會只有單調的穿過縫隙,希望能做出上下分別生成,讓玩家繞過障礙物那種。
今天主要是讓遊戲的背景開始動起來。
從昨天只有水管移動,到今天連背景也能跟著遊戲一起移動,畫面開始比較有橫向捲軸遊戲的感覺。
這次同樣是先把自己想要的功能告訴 Gemini,再讓它協助產生程式碼,最後放進 Unity 中測試。
目前遊戲還在慢慢製作當中,接下來就繼續一步一步把缺少的功能補上。