博客 / 詳情

返回

植物大戰殭屍辣椒爆炸效果實現:從原理到代碼落地

在《植物大戰殭屍》中,火爆辣椒是核心AOE(範圍傷害)植物之一,其核心機制是“放置後立即觸發全屏橫向爆炸,秒殺多數殭屍、清除寒冰效果、對特殊殭屍造成比例傷害”。本文將從技術角度拆解辣椒爆炸的核心邏輯,基於C#(Unity引擎)實現完整的辣椒爆炸功能,涵蓋範圍判定、傷害計算、特效觸發、狀態清理等關鍵環節,幫助開發者理解經典遊戲玩法的底層實現邏輯。

一、核心技術原理拆解

火爆辣椒爆炸的核心邏輯可拆解為5個關鍵環節,也是本文代碼實現的核心脈絡:

環節 核心作用 技術要點
範圍判定 確定爆炸影響的殭屍/元素 矩形範圍檢測、遍歷場景內殭屍對象
傷害計算 區分殭屍類型執行傷害邏輯 秒殺邏輯、比例傷害、特殊殭屍豁免
狀態清理 清除寒冰等負面/正面狀態 殭屍狀態機重置、場景冰面清除
特效/音效 提升視覺/聽覺反饋 粒子特效播放、音效觸發、幀動畫
植物管控 消耗陽光+冷卻處理 陽光扣減、冷卻計時、禁用重複放置

二、環境與基礎準備

2.1 開發環境

  • 引擎:Unity 2021.3 LTS
  • 語言:C#
  • 基礎資源:殭屍預製體、辣椒預製體、爆炸粒子特效、音效文件

2.2 核心基礎類定義

先定義殭屍和植物的基礎抽象類,統一屬性和行為規範:

/// <summary>
/// 殭屍基礎類
/// </summary>
public abstract class ZombieBase : MonoBehaviour
{
    // 殭屍類型
    public enum ZombieType { Normal, Cone, Bucket, GigaGargantuar, Ice }
    public ZombieType zombieType;
    // 生命值
    public float hp;
    // 最大生命值
    public float maxHp;
    // 是否處於冰凍狀態
    public bool isFrozen;
    // 移動速度
    public float moveSpeed;

    /// <summary>
    /// 受到傷害
    /// </summary>
    /// <param name="damage">傷害值</param>
    public virtual void TakeDamage(float damage)
    {
        hp -= damage;
        if (hp <= 0)
        {
            Die();
        }
    }

    /// <summary>
    /// 死亡邏輯
    /// </summary>
    public virtual void Die()
    {
        // 播放死亡動畫/特效
        Destroy(gameObject, 0.5f);
    }

    /// <summary>
    /// 解除冰凍狀態
    /// </summary>
    public virtual void Unfreeze()
    {
        isFrozen = false;
        // 恢復移動速度
        moveSpeed = moveSpeed / 0.5f; // 假設冰凍時速度減半
    }
}

/// <summary>
/// 植物基礎類
/// </summary>
public abstract class PlantBase : MonoBehaviour
{
    // 陽光消耗
    public int sunCost;
    // 冷卻時間(秒)
    public float coolDownTime;
    // 是否處於冷卻中
    protected bool isCoolingDown;

    /// <summary>
    /// 放置植物
    /// </summary>
    /// <returns>是否放置成功</returns>
    public virtual bool PlacePlant()
    {
        if (isCoolingDown)
        {
            Debug.Log("植物還在冷卻中!");
            return false;
        }
        // 扣減陽光(需結合陽光管理器)
        if (SunManager.Instance.UseSun(sunCost))
        {
            StartCoroutine(CoolDownCoroutine());
            return true;
        }
        Debug.Log("陽光不足!");
        return false;
    }

    /// <summary>
    /// 冷卻協程
    /// </summary>
    /// <returns></returns>
    protected IEnumerator CoolDownCoroutine()
    {
        isCoolingDown = true;
        yield return new WaitForSeconds(coolDownTime);
        isCoolingDown = false;
    }
}

三、火爆辣椒核心代碼實現

3.1 辣椒類(ChiliPepper)

繼承植物基礎類,實現爆炸核心邏輯:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 火爆辣椒類
/// </summary>
public class ChiliPepper : PlantBase
{
    // 爆炸範圍(橫向全屏,縱向單格,可根據格子大小調整)
    public Vector2 explosionRange = new Vector2(10f, 1.5f);
    // 爆炸傷害(對普通殭屍秒殺,對巨人按比例)
    public float explosionDamage = 9999f;
    // 巨人殭屍傷害比例(例如50%)
    public float gigaDamageRatio = 0.5f;
    // 爆炸特效預製體
    public GameObject explosionEffectPrefab;
    // 爆炸音效
    public AudioClip explosionAudioClip;
    // 音效源
    private AudioSource audioSource;

    private void Awake()
    {
        audioSource = GetComponent<AudioSource>();
        // 初始化參數(可根據遊戲平衡調整)
        sunCost = 125; // 原版陽光消耗
        coolDownTime = 50f; // 原版冷卻時間
    }

    private void Start()
    {
        // 放置後立即觸發爆炸
        if (PlacePlant())
        {
            StartCoroutine(ExplodeCoroutine());
        }
        else
        {
            Destroy(gameObject);
        }
    }

    /// <summary>
    /// 爆炸協程(延遲觸發+效果執行)
    /// </summary>
    /// <returns></returns>
    private IEnumerator ExplodeCoroutine()
    {
        // 播放辣椒點燃動畫(0.5秒延遲)
        yield return new WaitForSeconds(0.5f);
        
        // 1. 觸發爆炸特效和音效
        PlayExplosionEffect();
        PlayExplosionAudio();

        // 2. 檢測範圍內的殭屍
        Collider2D[] colliders = Physics2D.OverlapBoxAll(transform.position, explosionRange, 0);
        foreach (var collider in colliders)
        {
            ZombieBase zombie = collider.GetComponent<ZombieBase>();
            if (zombie != null)
            {
                // 3. 解除殭屍冰凍狀態
                if (zombie.isFrozen)
                {
                    zombie.Unfreeze();
                }

                // 4. 按殭屍類型計算傷害
                if (zombie.zombieType == ZombieBase.ZombieType.GigaGargantuar)
                {
                    // 巨人殭屍按比例傷害
                    float gigaDamage = zombie.maxHp * gigaDamageRatio;
                    zombie.TakeDamage(gigaDamage);
                }
                else
                {
                    // 普通殭屍秒殺
                    zombie.TakeDamage(explosionDamage);
                }
            }
        }

        // 5. 清除場景內的冰面(可擴展IceGround類)
        ClearIceGround();

        // 6. 爆炸後銷燬辣椒對象
        Destroy(gameObject, 1f);
    }

    /// <summary>
    /// 播放爆炸特效
    /// </summary>
    private void PlayExplosionEffect()
    {
        if (explosionEffectPrefab != null)
        {
            GameObject effect = Instantiate(explosionEffectPrefab, transform.position, Quaternion.identity);
            // 特效播放完畢後銷燬
            Destroy(effect, 2f);
        }
    }

    /// <summary>
    /// 播放爆炸音效
    /// </summary>
    private void PlayExplosionAudio()
    {
        if (audioSource != null && explosionAudioClip != null)
        {
            audioSource.PlayOneShot(explosionAudioClip);
        }
    }

    /// <summary>
    /// 清除場景內的冰面
    /// </summary>
    private void ClearIceGround()
    {
        // 遍歷場景內所有冰面對象並銷燬/重置
        IceGround[] iceGrounds = FindObjectsOfType<IceGround>();
        foreach (var ice in iceGrounds)
        {
            ice.ClearIce();
        }
    }
}

3.2 輔助類:陽光管理器(SunManager)

單例模式管理陽光資源,供植物放置時調用:

public class SunManager : MonoBehaviour
{
    // 單例實例
    public static SunManager Instance;
    // 當前陽光數量
    public int currentSun = 0;

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }

    /// <summary>
    /// 使用陽光
    /// </summary>
    /// <param name="cost">消耗數量</param>
    /// <returns>是否成功</returns>
    public bool UseSun(int cost)
    {
        if (currentSun >= cost)
        {
            currentSun -= cost;
            UpdateSunUI();
            return true;
        }
        return false;
    }

    /// <summary>
    /// 增加陽光
    /// </summary>
    /// <param name="amount">增加數量</param>
    public void AddSun(int amount)
    {
        currentSun += amount;
        UpdateSunUI();
    }

    /// <summary>
    /// 更新陽光UI(需結合UI系統)
    /// </summary>
    private void UpdateSunUI()
    {
        // 示例:UIManager.Instance.UpdateSunText(currentSun);
        Debug.Log("當前陽光:" + currentSun);
    }
}

3.3 輔助類:冰面(IceGround)

處理辣椒爆炸清除冰面的邏輯:

public class IceGround : MonoBehaviour
{
    // 冰面激活狀態
    public bool isActive = true;

    /// <summary>
    /// 清除冰面
    /// </summary>
    public void ClearIce()
    {
        isActive = false;
        // 播放冰面融化特效
        Destroy(gameObject, 0.5f);
    }
}

四、核心代碼解析

4.1 範圍檢測邏輯

使用Physics2D.OverlapBoxAll實現矩形範圍檢測,參數説明:

  • transform.position:辣椒放置位置(爆炸中心);
  • explosionRange:爆炸範圍(橫向10f覆蓋全屏,縱向1.5f覆蓋單格);
  • 0:旋轉角度(無旋轉)。
    該方法會返回範圍內所有帶Collider2D的對象,通過GetComponent<ZombieBase>篩選出殭屍對象。

4.2 差異化傷害處理

  • 普通殭屍(Normal/Cone/Bucket/Ice):直接施加9999點傷害(秒殺);
  • 巨人殭屍(GigaGargantuar):按最大生命值的50%計算傷害(符合原版邏輯);
  • 冰凍僵屍:先調用Unfreeze()解除冰凍,再執行傷害邏輯。

4.3 特效與音效

  • 特效:實例化爆炸粒子預製體,播放後延遲2秒銷燬,避免內存泄漏;
  • 音效:通過AudioSource.PlayOneShot播放一次性音效,不影響其他音頻播放。

4.4 冷卻與陽光管控

  • 陽光:通過SunManager單例扣減陽光,不足時返回放置失敗;
  • 冷卻:通過協程實現50秒冷卻,冷卻期間禁止重複放置。

五、效果測試

5.1 測試場景搭建

  1. 在Unity場景中創建橫向格子(對應PVZ的9列);
  2. 放置不同類型殭屍(普通、路障、鐵桶、巨人、冰凍僵屍);
  3. 放置冰面對象,模擬寒冰菇/冰西瓜的效果;
  4. 給辣椒預製體掛載ChiliPepper腳本,賦值特效、音效等參數。

5.2 預期測試結果

測試項 預期結果
陽光不足(<125) 辣椒無法放置,控制枱輸出“陽光不足!”
冷卻中放置 辣椒無法放置,控制枱輸出“植物還在冷卻中!”
普通殭屍爆炸 殭屍秒殺,播放死亡動畫
巨人殭屍爆炸 生命值減少50%,未秒殺
冰凍僵屍爆炸 解除冰凍狀態,恢復移動速度,隨後秒殺
冰面爆炸 冰面銷燬,播放融化特效
特效/音效 爆炸粒子播放,音效正常發聲

六、優化方向

6.1 性能優化

  • 對象池:將爆炸特效、殭屍死亡特效改為對象池管理,減少頻繁Instantiate/Destroy的性能開銷;
  • 範圍檢測優化:預先將殭屍按行分組,爆炸時僅檢測當前行的殭屍,減少遍歷數量。

6.2 功能擴展

  • 傷害衰減:實現爆炸邊緣傷害衰減(原版無此邏輯,可自定義);
  • 火焰殘留:添加短暫火焰地面,對後續殭屍造成持續傷害;
  • 適配移動端:添加觸摸放置邏輯,適配手機端操作。

6.3 邏輯完善

  • 殭屍無敵狀態:增加isInvincible屬性,對無敵殭屍(如僵王)免疫爆炸傷害;
  • 音效音量控制:添加音量參數,支持全局音效音量調節;
  • UI反饋:爆炸時添加屏幕震動、傷害數字飄字等視覺反饋。

七、總結

本文從《植物大戰殭屍》火爆辣椒的核心玩法出發,拆解了爆炸效果的技術原理,並基於Unity+C#實現了完整的代碼邏輯,涵蓋範圍檢測、差異化傷害、狀態清理、特效音效、資源管控等關鍵環節。該實現既還原了原版遊戲的核心體驗,又保留了足夠的擴展空間,開發者可根據自身需求調整參數(如傷害值、冷卻時間、爆炸範圍)或擴展功能(如火焰殘留、移動端適配)。

核心要點回顧:

  1. 範圍檢測優先使用物理引擎API(如OverlapBoxAll),兼顧性能與準確性;
  2. 差異化邏輯通過枚舉+條件判斷實現,便於擴展新殭屍類型;
  3. 單例模式(SunManager)適合管理全局資源(陽光、冷卻);
  4. 協程是Unity中處理延遲/冷卻邏輯的高效方式。
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.