完整游戏项目

目录

08. 完整游戏项目

Unity完整游戏项目实战 - 从概念到发布的完整开发流程


📌 本章导航


2D平台跳跃游戏

项目概述

2D平台跳跃游戏是学习游戏开发的经典项目,它涵盖了角色控制、物理系统、关卡设计、敌人AI等核心概念。

核心功能:

  • 角色移动和跳跃
  • 物理碰撞检测
  • 敌人AI系统
  • 收集品系统
  • 关卡设计
  • UI界面

项目结构设计

// 2D平台跳跃游戏的项目结构
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

// 游戏管理器
public class PlatformerGameManager : MonoBehaviour
{
    [Header("游戏设置")]
    public int currentLevel = 1;
    public int maxLives = 3;
    public float timeLimit = 300f; // 5分钟

    [Header("玩家设置")]
    public GameObject playerPrefab;
    public Transform[] spawnPoints;
    public float respawnDelay = 3f;

    [Header("UI设置")]
    public PlatformerUIManager uiManager;
    public PlatformerAudioManager audioManager;

    [Header("游戏对象")]
    public List<GameObject> enemies = new List<GameObject>();
    public List<GameObject> collectibles = new List<GameObject>();
    public List<GameObject> platforms = new List<GameObject>();

    private int currentLives;
    private float currentTime;
    private bool isGameActive = false;
    private bool isLevelComplete = false;

    public static PlatformerGameManager Instance { get; private set; }

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

    void Start()
    {
        InitializeGame();
    }

    private void InitializeGame()
    {
        currentLives = maxLives;
        currentTime = 0f;
        isGameActive = true;
        isLevelComplete = false;

        SpawnPlayer();
        InitializeUI();
        StartGameTimer();
    }

    private void SpawnPlayer()
    {
        if (playerPrefab != null && spawnPoints.Length > 0)
        {
            Transform spawnPoint = spawnPoints[Random.Range(0, spawnPoints.Length)];
            GameObject player = Instantiate(playerPrefab, spawnPoint.position, spawnPoint.rotation);
            
            // 注册玩家事件
            PlayerController2D playerCtrl = player.GetComponent<PlayerController2D>();
            if (playerCtrl != null)
            {
                playerCtrl.OnPlayerDeath += OnPlayerDeath;
                playerCtrl.OnLevelComplete += OnLevelComplete;
            }
        }
    }

    private void InitializeUI()
    {
        if (uiManager != null)
        {
            uiManager.UpdateLives(currentLives);
            uiManager.UpdateLevel(currentLevel);
            uiManager.UpdateTime(timeLimit);
        }
    }

    private void StartGameTimer()
    {
        StartCoroutine(GameTimerCoroutine());
    }

    private IEnumerator GameTimerCoroutine()
    {
        while (isGameActive && !isLevelComplete)
        {
            currentTime += Time.deltaTime;
            
            if (currentTime >= timeLimit)
            {
                GameOver();
                yield break;
            }

            if (uiManager != null)
            {
                uiManager.UpdateTime(timeLimit - currentTime);
            }

            yield return null;
        }
    }

    private void OnPlayerDeath()
    {
        currentLives--;

        if (uiManager != null)
        {
            uiManager.UpdateLives(currentLives);
        }

        if (currentLives <= 0)
        {
            GameOver();
        }
        else
        {
            // 延迟重生
            Invoke("RespawnPlayer", respawnDelay);
        }
    }

    private void RespawnPlayer()
    {
        // 销毁当前玩家
        GameObject currentPlayer = GameObject.FindGameObjectWithTag("Player");
        if (currentPlayer != null)
        {
            Destroy(currentPlayer);
        }

        // 重生玩家
        SpawnPlayer();
    }

    private void OnLevelComplete()
    {
        isLevelComplete = true;
        isGameActive = false;

        if (uiManager != null)
        {
            uiManager.ShowLevelComplete();
        }

        // 延迟进入下一关
        Invoke("LoadNextLevel", 3f);
    }

    private void LoadNextLevel()
    {
        currentLevel++;
        
        // 重新加载场景或加载下一关
        UnityEngine.SceneManagement.SceneManager.LoadScene(
            UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex + 1);
    }

    private void GameOver()
    {
        isGameActive = false;
        
        if (uiManager != null)
        {
            uiManager.ShowGameOver();
        }
    }

    public void AddScore(int points)
    {
        if (uiManager != null)
        {
            uiManager.AddScore(points);
        }
    }

    public void CollectItem()
    {
        if (uiManager != null)
        {
            uiManager.UpdateCollectibles();
        }
    }
}

// 玩家控制器2D
[RequireComponent(typeof(Rigidbody2D))]
public class PlayerController2D : MonoBehaviour
{
    [Header("移动设置")]
    public float moveSpeed = 5f;
    public float jumpForce = 10f;
    public float fallMultiplier = 2.5f; // 下降倍数,让跳跃更可控
    public float lowJumpMultiplier = 2f; // 短跳倍数

    [Header("地面检测")]
    public Transform groundCheck;
    public float groundCheckRadius = 0.2f;
    public LayerMask groundLayerMask;

    [Header("动画设置")]
    public Animator animator;
    public SpriteRenderer spriteRenderer;

    private Rigidbody2D rb;
    private bool isGrounded;
    private bool isJumping;
    private bool facingRight = true;
    private float horizontalInput;
    private bool jumpInput;
    private bool jumpHeld;

    // 事件
    public System.Action OnPlayerDeath;
    public System.Action OnLevelComplete;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        
        if (animator == null)
        {
            animator = GetComponent<Animator>();
        }
        
        if (spriteRenderer == null)
        {
            spriteRenderer = GetComponent<SpriteRenderer>();
        }

        // 设置地面检测点
        if (groundCheck == null)
        {
            groundCheck = new GameObject("GroundCheck").transform;
            groundCheck.SetParent(transform);
            groundCheck.localPosition = new Vector3(0, -0.5f, 0);
        }
    }

    void Update()
    {
        HandleInput();
        CheckGrounded();
        UpdateAnimation();
    }

    void FixedUpdate()
    {
        Move();
        HandleJump();
    }

    private void HandleInput()
    {
        horizontalInput = Input.GetAxisRaw("Horizontal");
        jumpInput = Input.GetButtonDown("Jump");
        jumpHeld = Input.GetButton("Jump");
    }

    private void Move()
    {
        rb.velocity = new Vector2(horizontalInput * moveSpeed, rb.velocity.y);

        // 翻转精灵方向
        if (horizontalInput > 0 && !facingRight)
        {
            Flip();
        }
        else if (horizontalInput < 0 && facingRight)
        {
            Flip();
        }
    }

    private void HandleJump()
    {
        isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayerMask);

        if (isGrounded && jumpInput)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
            isJumping = true;
        }

        // 可变跳跃高度
        if (rb.velocity.y < 0)
        {
            rb.velocity += Vector2.up * Physics2D.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
        }
        else if (rb.velocity.y > 0 && !jumpHeld)
        {
            rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMultiplier - 1) * Time.deltaTime;
        }
    }

    private void CheckGrounded()
    {
        isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayerMask);
        
        if (isGrounded && isJumping)
        {
            isJumping = false;
        }
    }

    private void Flip()
    {
        facingRight = !facingRight;
        Vector3 scale = transform.localScale;
        scale.x *= -1;
        transform.localScale = scale;
    }

    private void UpdateAnimation()
    {
        if (animator != null)
        {
            animator.SetFloat("Speed", Mathf.Abs(horizontalInput));
            animator.SetBool("IsGrounded", isGrounded);
            animator.SetFloat("VerticalVelocity", rb.velocity.y);
        }
    }

    // 碰撞检测
    void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Enemy"))
        {
            TakeDamage();
        }
        else if (collision.gameObject.CompareTag("Hazard"))
        {
            Die();
        }
        else if (collision.gameObject.CompareTag("MovingPlatform"))
        {
            // 附加到移动平台
            transform.SetParent(collision.transform);
        }
    }

    void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("MovingPlatform"))
        {
            // 从移动平台分离
            transform.SetParent(null);
        }
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Collectible"))
        {
            CollectItem(other.gameObject);
        }
        else if (other.CompareTag("Goal"))
        {
            CompleteLevel();
        }
        else if (other.CompareTag("Checkpoint"))
        {
            SetCheckpoint(other.transform.position);
        }
    }

    private void TakeDamage()
    {
        // 可以添加无敌时间、闪烁效果等
        Die();
    }

    private void Die()
    {
        if (OnPlayerDeath != null)
        {
            OnPlayerDeath();
        }
        
        // 播放死亡效果
        gameObject.SetActive(false);
    }

    private void CollectItem(GameObject item)
    {
        // 添加分数
        PlatformerGameManager.Instance?.AddScore(10);
        
        // 播放收集音效
        PlatformerAudioManager.Instance?.PlaySFX("Collect");
        
        // 销毁收集品
        Destroy(item);
        
        // 通知游戏管理器
        PlatformerGameManager.Instance?.CollectItem();
    }

    private void CompleteLevel()
    {
        if (OnLevelComplete != null)
        {
            OnLevelComplete();
        }
    }

    private void SetCheckpoint(Vector3 position)
    {
        // 设置检查点,重生时从这里开始
        // 这里简化处理,实际应该有检查点系统
    }

    // 可视化地面检测
    void OnDrawGizmosSelected()
    {
        if (groundCheck != null)
        {
            Gizmos.color = isGrounded ? Color.green : Color.red;
            Gizmos.DrawWireSphere(groundCheck.position, groundCheckRadius);
        }
    }
}

敌人AI系统

using UnityEngine;
using System.Collections;

// 平台跳跃游戏敌人基类
public class PlatformerEnemy : MonoBehaviour
{
    [Header("敌人设置")]
    public float moveSpeed = 2f;
    public float detectionRange = 5f;
    public float attackRange = 1f;
    public int health = 1;
    public int damage = 1;
    public float knockbackForce = 5f;

    [Header("巡逻设置")]
    public Transform[] patrolPoints;
    public float waitTime = 2f;
    public bool isPatrolling = true;

    [Header("动画设置")]
    public Animator animator;

    protected Transform player;
    protected Rigidbody2D rb;
    protected bool facingRight = true;
    protected int currentPatrolIndex = 0;
    protected bool isMovingToPatrolPoint = false;
    protected bool isAggressive = false;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        
        if (animator == null)
        {
            animator = GetComponent<Animator>();
        }

        FindPlayer();
        
        if (isPatrolling && patrolPoints.Length > 0)
        {
            StartCoroutine(PatrolCoroutine());
        }
    }

    void Update()
    {
        FindPlayer();
        UpdateAnimation();
    }

    void FindPlayer()
    {
        if (player == null)
        {
            GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
            if (playerObj != null)
            {
                player = playerObj.transform;
            }
        }
    }

    void UpdateAnimation()
    {
        if (animator != null)
        {
            animator.SetFloat("Speed", rb.velocity.magnitude);
            animator.SetBool("IsAggressive", isAggressive);
        }
    }

    // 巡逻协程
    private IEnumerator PatrolCoroutine()
    {
        while (isPatrolling)
        {
            if (patrolPoints.Length > 0 && !isAggressive)
            {
                if (!isMovingToPatrolPoint)
                {
                    StartCoroutine(MoveToPatrolPoint());
                }
            }
            
            yield return new WaitForSeconds(0.1f);
        }
    }

    // 移动到巡逻点
    private IEnumerator MoveToPatrolPoint()
    {
        isMovingToPatrolPoint = true;
        
        Transform targetPoint = patrolPoints[currentPatrolIndex];
        
        while (Vector2.Distance(transform.position, targetPoint.position) > 0.5f)
        {
            Vector2 direction = (targetPoint.position - transform.position).normalized;
            rb.velocity = new Vector2(direction.x * moveSpeed, rb.velocity.y);
            
            // 翻转方向
            if (direction.x > 0 && !facingRight)
            {
                Flip();
            }
            else if (direction.x < 0 && facingRight)
            {
                Flip();
            }
            
            yield return null;
        }
        
        // 到达巡逻点,等待
        yield return new WaitForSeconds(waitTime);
        
        // 移动到下一个巡逻点
        currentPatrolIndex = (currentPatrolIndex + 1) % patrolPoints.Length;
        
        isMovingToPatrolPoint = false;
    }

    // 检测玩家
    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            isAggressive = true;
            StopCoroutine(PatrolCoroutine());
            StartCoroutine(ChasePlayerCoroutine());
        }
    }

    void OnTriggerExit2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            isAggressive = false;
            if (isPatrolling)
            {
                StartCoroutine(PatrolCoroutine());
            }
        }
    }

    // 追击玩家协程
    private IEnumerator ChasePlayerCoroutine()
    {
        while (isAggressive && player != null)
        {
            float distanceToPlayer = Vector2.Distance(transform.position, player.position);
            
            if (distanceToPlayer <= attackRange)
            {
                // 攻击玩家
                AttackPlayer();
            }
            else if (distanceToPlayer <= detectionRange)
            {
                // 追击玩家
                Vector2 direction = (player.position - transform.position).normalized;
                rb.velocity = new Vector2(direction.x * moveSpeed, rb.velocity.y);
                
                // 翻转方向
                if (direction.x > 0 && !facingRight)
                {
                    Flip();
                }
                else if (direction.x < 0 && facingRight)
                {
                    Flip();
                }
            }
            else
            {
                // 超出检测范围,停止追击
                isAggressive = false;
                if (isPatrolling)
                {
                    StartCoroutine(PatrolCoroutine());
                }
            }
            
            yield return null;
        }
    }

    // 攻击玩家
    protected virtual void AttackPlayer()
    {
        if (player != null)
        {
            PlayerController2D playerCtrl = player.GetComponent<PlayerController2D>();
            if (playerCtrl != null)
            {
                // 对玩家造成伤害
                playerCtrl.TakeDamage();
            }
        }
    }

    // 受伤
    public virtual void TakeDamage(int damageAmount = 1)
    {
        health -= damageAmount;
        
        if (health <= 0)
        {
            Die();
        }
        else
        {
            // 击退效果
            if (player != null)
            {
                Vector2 knockbackDirection = (transform.position - player.position).normalized;
                rb.AddForce(knockbackDirection * knockbackForce, ForceMode2D.Impulse);
            }
        }
    }

    // 死亡
    protected virtual void Die()
    {
        // 播放死亡效果
        if (PlatformerAudioManager.Instance != null)
        {
            PlatformerAudioManager.Instance.PlaySFX("EnemyDie");
        }
        
        // 给予玩家分数
        PlatformerGameManager.Instance?.AddScore(50);
        
        // 销毁敌人
        Destroy(gameObject);
    }

    // 翻转方向
    protected void Flip()
    {
        facingRight = !facingRight;
        Vector3 scale = transform.localScale;
        scale.x *= -1;
        transform.localScale = scale;
    }

    // 可视化检测范围
    void OnDrawGizmos()
    {
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere(transform.position, detectionRange);
        
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, attackRange);
        
        // 巡逻路径
        if (patrolPoints != null && patrolPoints.Length > 1)
        {
            Gizmos.color = Color.blue;
            for (int i = 0; i < patrolPoints.Length; i++)
            {
                if (patrolPoints[i] != null)
                {
                    Gizmos.DrawSphere(patrolPoints[i].position, 0.2f);
                    
                    if (i > 0)
                    {
                        Gizmos.DrawLine(patrolPoints[i-1].position, patrolPoints[i].position);
                    }
                }
            }
            
            // 闭合路径
            if (patrolPoints.Length > 2 && patrolPoints[0] != null)
            {
                Gizmos.DrawLine(patrolPoints[patrolPoints.Length-1].position, patrolPoints[0].position);
            }
        }
    }
}

// 特定类型的敌人 - 行走敌人
public class WalkingEnemy : PlatformerEnemy
{
    [Header("行走敌人特有设置")]
    public float jumpForce = 5f;
    public float jumpFrequency = 2f; // 跳跃频率
    private float lastJumpTime = 0f;

    protected override void AttackPlayer()
    {
        if (player != null && Time.time >= lastJumpTime + jumpFrequency)
        {
            // 跳向玩家
            Vector2 jumpDirection = (player.position - transform.position).normalized;
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
            
            lastJumpTime = Time.time;
        }
        
        base.AttackPlayer();
    }
}

// 特定类型的敌人 - 投射物敌人
public class ProjectileEnemy : PlatformerEnemy
{
    [Header("投射物敌人特有设置")]
    public GameObject projectilePrefab;
    public Transform firePoint;
    public float fireRate = 2f;
    private float lastFireTime = 0f;

    protected override void AttackPlayer()
    {
        if (player != null && Time.time >= lastFireTime + fireRate)
        {
            // 发射投射物
            if (projectilePrefab != null && firePoint != null)
            {
                GameObject projectile = Instantiate(projectilePrefab, firePoint.position, Quaternion.identity);
                Projectile proj = projectile.GetComponent<Projectile>();
                
                if (proj != null)
                {
                    Vector2 direction = (player.position - firePoint.position).normalized;
                    proj.Initialize(direction, 1); // 伤害值
                }
                
                lastFireTime = Time.time;
            }
        }
        
        base.AttackPlayer();
    }
}

// 投射物类
public class Projectile : MonoBehaviour
{
    public float speed = 10f;
    public int damage = 1;
    public float lifeTime = 5f;

    private Vector2 direction;
    private float lifeTimer = 0f;

    void Update()
    {
        transform.Translate(direction * speed * Time.deltaTime);
        lifeTimer += Time.deltaTime;

        if (lifeTimer >= lifeTime)
        {
            Destroy(gameObject);
        }
    }

    public void Initialize(Vector2 dir, int dmg)
    {
        direction = dir;
        damage = dmg;
        transform.right = direction; // 设置朝向
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            PlayerController2D player = other.GetComponent<PlayerController2D>();
            if (player != null)
            {
                player.TakeDamage();
            }
            
            Destroy(gameObject);
        }
        else if (other.CompareTag("Ground") || other.CompareTag("Obstacle"))
        {
            // 碰到地面或障碍物时销毁
            Destroy(gameObject);
        }
    }
}

UI和音频系统

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

// 2D平台跳跃游戏UI管理器
public class PlatformerUIManager : MonoBehaviour
{
    [Header("UI元素")]
    public Text scoreText;
    public Text livesText;
    public Text levelText;
    public Text timeText;
    public Text collectiblesText;
    public Slider healthBar;
    public Image fadeImage;

    [Header("面板")]
    public GameObject gamePanel;
    public GameObject pausePanel;
    public GameObject gameOverPanel;
    public GameObject levelCompletePanel;
    public GameObject collectibleEffect;

    [Header("动画")]
    public Animator uiAnimator;

    private int currentScore = 0;
    private int currentLives = 3;
    private int currentLevel = 1;
    private int totalCollectibles = 0;
    private int collectedCount = 0;
    private float currentTime = 0f;

    void Start()
    {
        InitializeUI();
    }

    private void InitializeUI()
    {
        UpdateScore(0);
        UpdateLives(PlatformerGameManager.Instance?.maxLives ?? 3);
        UpdateLevel(PlatformerGameManager.Instance?.currentLevel ?? 1);
        UpdateTime(PlatformerGameManager.Instance?.timeLimit ?? 300f);
        UpdateCollectibles();
    }

    public void UpdateScore(int points)
    {
        currentScore += points;
        if (scoreText != null)
        {
            scoreText.text = $"Score: {currentScore}";
        }
    }

    public void AddScore(int points)
    {
        currentScore += points;
        if (scoreText != null)
        {
            scoreText.text = $"Score: {currentScore}";
        }
    }

    public void UpdateLives(int lives)
    {
        currentLives = lives;
        if (livesText != null)
        {
            livesText.text = $"Lives: {currentLives}";
        }
    }

    public void UpdateLevel(int level)
    {
        currentLevel = level;
        if (levelText != null)
        {
            levelText.text = $"Level: {currentLevel}";
        }
    }

    public void UpdateTime(float timeLeft)
    {
        currentTime = timeLeft;
        if (timeText != null)
        {
            int minutes = Mathf.FloorToInt(timeLeft / 60);
            int seconds = Mathf.FloorToInt(timeLeft % 60);
            timeText.text = $"Time: {minutes:00}:{seconds:00}";
        }
    }

    public void UpdateCollectibles()
    {
        collectedCount++;
        if (collectiblesText != null)
        {
            collectiblesText.text = $"Items: {collectedCount}/{totalCollectibles}";
        }
        
        // 显示收集效果
        if (collectibleEffect != null)
        {
            Instantiate(collectibleEffect, Vector3.zero, Quaternion.identity);
        }
    }

    public void UpdateHealth(float healthPercentage)
    {
        if (healthBar != null)
        {
            healthBar.value = healthPercentage;
        }
    }

    public void ShowPauseMenu()
    {
        if (pausePanel != null)
        {
            pausePanel.SetActive(true);
        }
    }

    public void HidePauseMenu()
    {
        if (pausePanel != null)
        {
            pausePanel.SetActive(false);
        }
    }

    public void ShowGameOver()
    {
        if (gameOverPanel != null)
        {
            gameOverPanel.SetActive(true);
        }
        
        if (gamePanel != null)
        {
            gamePanel.SetActive(false);
        }
    }

    public void ShowLevelComplete()
    {
        if (levelCompletePanel != null)
        {
            levelCompletePanel.SetActive(true);
        }
        
        if (gamePanel != null)
        {
            gamePanel.SetActive(false);
        }
    }

    // 按钮事件
    public void OnPauseButton()
    {
        PlatformerGameManager.Instance?.PauseGame();
        ShowPauseMenu();
    }

    public void OnResumeButton()
    {
        PlatformerGameManager.Instance?.ResumeGame();
        HidePauseMenu();
    }

    public void OnRestartButton()
    {
        UnityEngine.SceneManagement.SceneManager.LoadScene(
            UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex);
    }

    public void OnNextLevelButton()
    {
        // 加载下一关
        int currentScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex;
        UnityEngine.SceneManagement.SceneManager.LoadScene(currentScene + 1);
    }

    public void OnQuitButton()
    {
        #if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
        #else
        Application.Quit();
        #endif
    }

    // 淡入淡出效果
    public IEnumerator FadeToBlack(float duration)
    {
        if (fadeImage != null)
        {
            Color color = fadeImage.color;
            color.a = 0;
            fadeImage.color = color;

            float time = 0;
            while (time < duration)
            {
                time += Time.deltaTime;
                color.a = Mathf.Lerp(0, 1, time / duration);
                fadeImage.color = color;
                yield return null;
            }
        }
    }

    public IEnumerator FadeFromBlack(float duration)
    {
        if (fadeImage != null)
        {
            Color color = fadeImage.color;
            color.a = 1;
            fadeImage.color = color;

            float time = 0;
            while (time < duration)
            {
                time += Time.deltaTime;
                color.a = Mathf.Lerp(1, 0, time / duration);
                fadeImage.color = color;
                yield return null;
            }
        }
    }
}

// 2D平台跳跃游戏音频管理器
public class PlatformerAudioManager : MonoBehaviour
{
    [Header("音频源")]
    public AudioSource bgmSource;
    public AudioSource sfxSource;
    public AudioSource ambientSource;

    [Header("音频剪辑")]
    public AudioClip[] bgmClips;
    public AudioClip[] sfxClips;
    public AudioClip[] ambientClips;

    private Dictionary<string, AudioClip> sfxDictionary = new Dictionary<string, AudioClip>();
    private Dictionary<string, AudioClip> bgmDictionary = new Dictionary<string, AudioClip>();

    public static PlatformerAudioManager Instance { get; private set; }

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

    void Start()
    {
        InitializeAudio();
    }

    private void InitializeAudio()
    {
        // 创建音频源(如果未设置)
        if (bgmSource == null)
        {
            GameObject bgmGO = new GameObject("BGMAudioSource");
            bgmGO.transform.SetParent(transform);
            bgmSource = bgmGO.AddComponent<AudioSource>();
            bgmSource.playOnAwake = false;
            bgmSource.loop = true;
        }

        if (sfxSource == null)
        {
            GameObject sfxGO = new GameObject("SFXAudioSource");
            sfxGO.transform.SetParent(transform);
            sfxSource = sfxGO.AddComponent<AudioSource>();
            sfxSource.playOnAwake = false;
            sfxSource.loop = false;
        }

        if (ambientSource == null)
        {
            GameObject ambientGO = new GameObject("AmbientAudioSource");
            ambientGO.transform.SetParent(transform);
            ambientSource = ambientGO.AddComponent<AudioSource>();
            ambientSource.playOnAwake = false;
            ambientSource.loop = true;
        }

        // 建立音频字典
        foreach (AudioClip clip in sfxClips)
        {
            if (clip != null)
            {
                sfxDictionary[clip.name] = clip;
            }
        }

        foreach (AudioClip clip in bgmClips)
        {
            if (clip != null)
            {
                bgmDictionary[clip.name] = clip;
            }
        }
    }

    public void PlaySFX(string sfxName)
    {
        if (sfxDictionary.TryGetValue(sfxName, out AudioClip clip))
        {
            sfxSource.PlayOneShot(clip);
        }
        else
        {
            Debug.LogWarning($"SFX '{sfxName}' not found!");
        }
    }

    public void PlayBGM(string bgmName, bool loop = true)
    {
        if (bgmDictionary.TryGetValue(bgmName, out AudioClip clip))
        {
            bgmSource.clip = clip;
            bgmSource.loop = loop;
            bgmSource.Play();
        }
        else
        {
            Debug.LogWarning($"BGM '{bgmName}' not found!");
        }
    }

    public void StopBGM()
    {
        bgmSource.Stop();
    }

    public void SetBGMVolume(float volume)
    {
        bgmSource.volume = volume;
    }

    public void SetSFXVolume(float volume)
    {
        sfxSource.volume = volume;
    }

    // 3D音效
    public void Play3DSound(AudioClip clip, Vector3 position, float volume = 1f)
    {
        if (clip == null) return;

        GameObject audioGO = new GameObject("3DAudioSource");
        audioGO.transform.position = position;
        AudioSource source = audioGO.AddComponent<AudioSource>();
        
        source.clip = clip;
        source.volume = volume;
        source.spatialBlend = 1f;
        source.maxDistance = 20f;
        
        source.Play();
        
        Destroy(audioGO, clip.length);
    }

    // 随机播放音效
    public void PlayRandomSFX(string[] sfxNames)
    {
        if (sfxNames.Length > 0)
        {
            string randomSFX = sfxNames[Random.Range(0, sfxNames.Length)];
            PlaySFX(randomSFX);
        }
    }
}

关卡设计和完成

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

// 关卡管理器
public class PlatformerLevelManager : MonoBehaviour
{
    [Header("关卡设置")]
    public int levelIndex;
    public string levelName;
    public int parTime = 180; // 标准时间(秒)
    public int parCollectibles = 10; // 标准收集品数量
    public int parScore = 1000; // 标准分数

    [Header("奖励设置")]
    public int timeBonus = 100; // 时间奖励
    public int collectibleBonus = 50; // 收集品奖励
    public int completionBonus = 500; // 完成奖励

    [Header("检查点")]
    public List<Transform> checkpoints = new List<Transform>();
    public Transform defaultSpawnPoint;

    [Header("关卡目标")]
    public List<LevelObjective> objectives = new List<LevelObjective>();

    private float levelStartTime;
    private int collectedItems = 0;
    private int destroyedEnemies = 0;
    private bool levelCompleted = false;

    void Start()
    {
        levelStartTime = Time.time;
        collectedItems = 0;
        destroyedEnemies = 0;
        levelCompleted = false;
    }

    // 更新收集品计数
    public void ItemCollected()
    {
        collectedItems++;
        CheckObjectives();
    }

    // 更新敌人消灭计数
    public void EnemyDestroyed()
    {
        destroyedEnemies++;
        CheckObjectives();
    }

    // 检查目标是否完成
    private void CheckObjectives()
    {
        bool allObjectivesMet = true;
        
        foreach (LevelObjective objective in objectives)
        {
            bool objectiveMet = false;
            
            switch (objective.type)
            {
                case ObjectiveType.CollectItems:
                    objectiveMet = collectedItems >= objective.targetCount;
                    break;
                case ObjectiveType.DestroyEnemies:
                    objectiveMet = destroyedEnemies >= objective.targetCount;
                    break;
                case ObjectiveType.ReachLocation:
                    // 这个需要在角色到达特定位置时手动设置
                    objectiveMet = objective.isCompleted;
                    break;
                case ObjectiveType.TimeLimit:
                    objectiveMet = (Time.time - levelStartTime) <= objective.targetTime;
                    break;
            }
            
            if (!objectiveMet)
            {
                allObjectivesMet = false;
                break;
            }
        }
        
        if (allObjectivesMet && !levelCompleted)
        {
            CompleteLevel();
        }
    }

    // 完成关卡
    private void CompleteLevel()
    {
        levelCompleted = true;
        
        // 计算奖励
        float levelTime = Time.time - levelStartTime;
        int timeBonus = Mathf.Max(0, Mathf.RoundToInt((parTime - levelTime) * timeBonus));
        int collectibleBonus = (collectedItems >= parCollectibles) ? parCollectibles * this.collectibleBonus : collectedItems * this.collectibleBonus;
        int completionBonus = this.completionBonus;
        
        int totalBonus = timeBonus + collectibleBonus + completionBonus;
        
        // 添加奖励分数
        PlatformerGameManager.Instance?.AddScore(totalBonus);
        
        // 保存关卡完成数据
        SaveLevelProgress();
        
        // 触发关卡完成事件
        PlatformerGameManager.Instance?.OnLevelComplete();
    }

    // 保存关卡进度
    private void SaveLevelProgress()
    {
        string levelKey = $"Level_{levelIndex}_Completed";
        PlayerPrefs.SetInt(levelKey, 1);
        
        string timeKey = $"Level_{levelIndex}_BestTime";
        float currentTime = Time.time - levelStartTime;
        if (!PlayerPrefs.HasKey(timeKey) || PlayerPrefs.GetFloat(timeKey) > currentTime)
        {
            PlayerPrefs.SetFloat(timeKey, currentTime);
        }
        
        string scoreKey = $"Level_{levelIndex}_BestScore";
        int currentScore = PlatformerGameManager.Instance?.currentScore ?? 0;
        if (!PlayerPrefs.HasKey(scoreKey) || PlayerPrefs.GetInt(scoreKey) < currentScore)
        {
            PlayerPrefs.SetInt(scoreKey, currentScore);
        }
        
        PlayerPrefs.Save();
    }

    // 设置检查点
    public void SetCurrentCheckpoint(Transform checkpoint)
    {
        // 在这里可以保存当前检查点信息
        // 用于角色死亡后重生
    }

    // 获取最近的检查点
    public Transform GetNearestCheckpoint(Vector3 position)
    {
        Transform nearest = null;
        float minDistance = float.MaxValue;
        
        foreach (Transform checkpoint in checkpoints)
        {
            float distance = Vector3.Distance(position, checkpoint.position);
            if (distance < minDistance)
            {
                minDistance = distance;
                nearest = checkpoint;
            }
        }
        
        return nearest ?? defaultSpawnPoint;
    }
}

// 关卡目标类型
public enum ObjectiveType
{
    CollectItems,
    DestroyEnemies,
    ReachLocation,
    TimeLimit
}

// 关卡目标
[System.Serializable]
public class LevelObjective
{
    public ObjectiveType type;
    public int targetCount = 1;
    public float targetTime = 60f;
    public string description;
    public bool isCompleted = false;
}

// 关卡目标触发器
public class LevelObjectiveTrigger : MonoBehaviour
{
    public ObjectiveType objectiveType;
    public int requiredCount = 1;
    public string targetTag;

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag(targetTag))
        {
            PlatformerLevelManager levelManager = FindObjectOfType<PlatformerLevelManager>();
            if (levelManager != null)
            {
                switch (objectiveType)
                {
                    case ObjectiveType.CollectItems:
                        levelManager.ItemCollected();
                        break;
                    case ObjectiveType.DestroyEnemies:
                        levelManager.EnemyDestroyed();
                        break;
                    case ObjectiveType.ReachLocation:
                        CompleteReachObjective(levelManager);
                        break;
                }
                
                // 销毁触发器(如果是单次触发)
                Destroy(gameObject);
            }
        }
    }

    private void CompleteReachObjective(PlatformerLevelManager levelManager)
    {
        // 找到对应的目标并标记为完成
        LevelObjective objective = levelManager.objectives.Find(obj => obj.type == ObjectiveType.ReachLocation);
        if (objective != null)
        {
            objective.isCompleted = true;
        }
    }
}

// 收集品脚本
public class CollectibleItem : MonoBehaviour
{
    [Header("收集品设置")]
    public int points = 10;
    public bool rotate = true;
    public float rotationSpeed = 60f;
    public GameObject collectEffect;
    public AudioClip collectSound;

    [Header("特殊类型")]
    public bool isPowerUp = false;
    public PowerUpType powerUpType = PowerUpType.None;
    public float powerUpDuration = 10f;

    void Update()
    {
        if (rotate)
        {
            transform.Rotate(Vector3.up, rotationSpeed * Time.deltaTime);
        }
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            Collect();
        }
    }

    private void Collect()
    {
        // 添加分数
        PlatformerGameManager.Instance?.AddScore(points);
        
        // 播放音效
        if (collectSound != null)
        {
            PlatformerAudioManager.Instance?.PlaySFX(collectSound.name);
        }
        
        // 创建效果
        if (collectEffect != null)
        {
            Instantiate(collectEffect, transform.position, Quaternion.identity);
        }
        
        // 更新UI
        PlatformerUIManager.Instance?.UpdateCollectibles();
        
        // 通知关卡管理器
        PlatformerLevelManager levelManager = FindObjectOfType<PlatformerLevelManager>();
        if (levelManager != null)
        {
            levelManager.ItemCollected();
        }
        
        // 如果是强化道具,应用效果
        if (isPowerUp)
        {
            ApplyPowerUp();
        }
        
        // 销毁收集品
        Destroy(gameObject);
    }

    private void ApplyPowerUp()
    {
        PlayerController2D player = FindObjectOfType<PlayerController2D>();
        if (player != null)
        {
            switch (powerUpType)
            {
                case PowerUpType.SpeedBoost:
                    StartCoroutine(ApplySpeedBoost(player));
                    break;
                case PowerUpType.JumpBoost:
                    StartCoroutine(ApplyJumpBoost(player));
                    break;
                case PowerUpType.Invulnerability:
                    StartCoroutine(ApplyInvulnerability(player));
                    break;
            }
        }
    }

    private IEnumerator ApplySpeedBoost(PlayerController2D player)
    {
        float originalSpeed = player.moveSpeed;
        player.moveSpeed *= 1.5f; // 50%速度提升
        
        yield return new WaitForSeconds(powerUpDuration);
        
        player.moveSpeed = originalSpeed;
    }

    private IEnumerator ApplyJumpBoost(PlayerController2D player)
    {
        float originalJumpForce = player.jumpForce;
        player.jumpForce *= 1.3f; // 30%跳跃力提升
        
        yield return new WaitForSeconds(powerUpDuration);
        
        player.jumpForce = originalJumpForce;
    }

    private IEnumerator ApplyInvulnerability(PlayerController2D player)
    {
        // 这里需要在PlayerController2D中实现无敌逻辑
        // 简化处理,实际应该有更复杂的无敌系统
        yield return new WaitForSeconds(powerUpDuration);
    }
}

public enum PowerUpType
{
    None,
    SpeedBoost,
    JumpBoost,
    Invulnerability,
    ExtraLife
}

塔防游戏

项目概述

塔防游戏(Tower Defense)是一种策略游戏类型,玩家需要建造防御塔来阻止敌人到达终点。这类游戏涉及路径寻找、波次管理、经济系统、塔的升级等复杂机制。

核心功能:

  • 路径系统和敌人移动
  • 防御塔建造和升级
  • 敌人AI和波次管理
  • 经济系统(金钱、生命值)
  • UI和游戏状态管理

核心系统设计

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

// 塔防游戏管理器
public class TowerDefenseManager : MonoBehaviour
{
    [Header("游戏设置")]
    public int startingMoney = 100;
    public int startingLives = 20;
    public int waveInterval = 10; // 波次间隔(秒)
    public int baseReward = 10; // 击杀基础奖励

    [Header("波次设置")]
    public List<WaveData> waves = new List<WaveData>();
    public int currentWave = 0;
    public int enemiesSpawned = 0;
    public int enemiesRemaining = 0;

    [Header("游戏状态")]
    public int currentMoney;
    public int currentLives;
    public bool isGameActive = false;
    public bool isWaveActive = false;

    [Header("引用")]
    public TowerDefenseUIManager uiManager;
    public TowerDefenseAudioManager audioManager;
    public PathManager pathManager;
    public List<Tower> towers = new List<Tower>();
    public List<Enemy> enemies = new List<Enemy>();

    public static TowerDefenseManager Instance { get; private set; }

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

    void Start()
    {
        InitializeGame();
    }

    private void InitializeGame()
    {
        currentMoney = startingMoney;
        currentLives = startingLives;
        currentWave = 0;
        isGameActive = true;
        isWaveActive = false;

        InitializeUI();
        StartGame();
    }

    private void InitializeUI()
    {
        if (uiManager != null)
        {
            uiManager.UpdateMoney(currentMoney);
            uiManager.UpdateLives(currentLives);
            uiManager.UpdateWave(currentWave, waves.Count);
        }
    }

    private void StartGame()
    {
        if (waves.Count > 0)
        {
            StartCoroutine(GameLoop());
        }
    }

    private IEnumerator GameLoop()
    {
        while (isGameActive)
        {
            if (currentWave < waves.Count)
            {
                yield return StartCoroutine(SpawnWave(waves[currentWave]));
                
                // 等待当前波次的所有敌人被消灭
                while (enemiesRemaining > 0 && isGameActive)
                {
                    yield return null;
                }
                
                if (!isGameActive) break; // 如果游戏结束则退出
                
                currentWave++;
                
                if (uiManager != null)
                {
                    uiManager.UpdateWave(currentWave, waves.Count);
                }
                
                // 波次间隔
                yield return new WaitForSeconds(waveInterval);
            }
            else
            {
                // 所有波次完成,游戏胜利
                GameWin();
                break;
            }
        }
    }

    private IEnumerator SpawnWave(WaveData wave)
    {
        isWaveActive = true;
        enemiesSpawned = 0;
        enemiesRemaining = wave.enemyCount;

        for (int i = 0; i < wave.enemyCount; i++)
        {
            SpawnEnemy(wave.enemyType);
            enemiesSpawned++;
            
            // 敌人生成间隔
            yield return new WaitForSeconds(wave.spawnInterval);
        }
    }

    private void SpawnEnemy(EnemyType enemyType)
    {
        if (pathManager != null)
        {
            Vector3 spawnPos = pathManager.GetStartPoint();
            GameObject enemyPrefab = GetEnemyPrefab(enemyType);
            
            if (enemyPrefab != null)
            {
                GameObject enemyGO = Instantiate(enemyPrefab, spawnPos, Quaternion.identity);
                Enemy enemy = enemyGO.GetComponent<Enemy>();
                
                if (enemy != null)
                {
                    enemy.Initialize(pathManager.GetPath(), GetEnemyStats(enemyType));
                    enemies.Add(enemy);
                    
                    // 订阅敌人事件
                    enemy.OnEnemyKilled += OnEnemyKilled;
                    enemy.OnEnemyReachedEnd += OnEnemyReachedEnd;
                }
            }
        }
    }

    private GameObject GetEnemyPrefab(EnemyType enemyType)
    {
        // 根据敌人类型返回对应的预制件
        // 这里简化处理,实际应该有配置表
        switch (enemyType)
        {
            case EnemyType.Basic:
                return Resources.Load<GameObject>("Prefabs/Enemies/BasicEnemy");
            case EnemyType.Fast:
                return Resources.Load<GameObject>("Prefabs/Enemies/FastEnemy");
            case EnemyType.Tank:
                return Resources.Load<GameObject>("Prefabs/Enemies/TankEnemy");
            case EnemyType.Armored:
                return Resources.Load<GameObject>("Prefabs/Enemies/ArmoredEnemy");
            default:
                return Resources.Load<GameObject>("Prefabs/Enemies/BasicEnemy");
        }
    }

    private EnemyStats GetEnemyStats(EnemyType enemyType)
    {
        // 根据敌人类型返回对应的属性
        switch (enemyType)
        {
            case EnemyType.Basic:
                return new EnemyStats { health = 50, speed = 2f, reward = baseReward, armor = 0 };
            case EnemyType.Fast:
                return new EnemyStats { health = 30, speed = 4f, reward = baseReward * 1, armor = 0 };
            case EnemyType.Tank:
                return new EnemyStats { health = 150, speed = 1f, reward = baseReward * 3, armor = 2 };
            case EnemyType.Armored:
                return new EnemyStats { health = 80, speed = 1.5f, reward = baseReward * 2, armor = 5 };
            default:
                return new EnemyStats { health = 50, speed = 2f, reward = baseReward, armor = 0 };
        }
    }

    private void OnEnemyKilled(Enemy enemy, int reward)
    {
        // 移除敌人引用
        enemies.Remove(enemy);
        enemiesRemaining--;
        
        // 给予奖励
        AddMoney(reward);
        
        // 更新UI
        if (uiManager != null)
        {
            uiManager.UpdateEnemiesRemaining(enemiesRemaining);
        }
    }

    private void OnEnemyReachedEnd(Enemy enemy)
    {
        // 移除敌人引用
        enemies.Remove(enemy);
        enemiesRemaining--;
        
        // 减少生命值
        TakeDamage(1);
    }

    public void AddMoney(int amount)
    {
        currentMoney += amount;
        
        if (uiManager != null)
        {
            uiManager.UpdateMoney(currentMoney);
        }
    }

    public bool SpendMoney(int amount)
    {
        if (currentMoney >= amount)
        {
            currentMoney -= amount;
            
            if (uiManager != null)
            {
                uiManager.UpdateMoney(currentMoney);
            }
            
            return true;
        }
        
        return false;
    }

    public void TakeDamage(int damage)
    {
        currentLives -= damage;
        
        if (uiManager != null)
        {
            uiManager.UpdateLives(currentLives);
        }
        
        if (currentLives <= 0)
        {
            GameOver();
        }
    }

    public void BuildTower(Tower tower, Vector3 position)
    {
        if (SpendMoney(tower.cost))
        {
            GameObject towerGO = Instantiate(tower.gameObject, position, Quaternion.identity);
            Tower newTower = towerGO.GetComponent<Tower>();
            
            if (newTower != null)
            {
                towers.Add(newTower);
                newTower.Initialize();
            }
        }
    }

    public void UpgradeTower(Tower tower)
    {
        if (tower != null && SpendMoney(tower.upgradeCost))
        {
            tower.Upgrade();
        }
    }

    private void GameOver()
    {
        isGameActive = false;
        
        if (uiManager != null)
        {
            uiManager.ShowGameOver();
        }
    }

    private void GameWin()
    {
        isGameActive = false;
        
        if (uiManager != null)
        {
            uiManager.ShowGameWin();
        }
    }
}

// 波次数据
[System.Serializable]
public class WaveData
{
    public string waveName;
    public int enemyCount = 10;
    public float spawnInterval = 1f;
    public EnemyType enemyType = EnemyType.Basic;
    public int rewardMultiplier = 1;
}

// 敌人类型
public enum EnemyType
{
    Basic,
    Fast,
    Tank,
    Armored
}

// 敌人属性
[System.Serializable]
public class EnemyStats
{
    public int health = 100;
    public float speed = 2f;
    public int reward = 10;
    public int armor = 0;
}

// 路径管理器
public class PathManager : MonoBehaviour
{
    public List<Transform> waypoints = new List<Transform>();
    public Transform startPoint;
    public Transform endPoint;

    void Start()
    {
        // 自动查找路径点
        if (waypoints.Count == 0)
        {
            FindWaypoints();
        }
    }

    private void FindWaypoints()
    {
        // 查找子对象中的路径点
        Transform[] children = GetComponentsInChildren<Transform>();
        
        foreach (Transform child in children)
        {
            if (child.CompareTag("Waypoint"))
            {
                waypoints.Add(child);
            }
            else if (child.CompareTag("StartPoint"))
            {
                startPoint = child;
            }
            else if (child.CompareTag("EndPoint"))
            {
                endPoint = child;
            }
        }
        
        // 按照名称排序路径点(Waypoint_0, Waypoint_1, ...)
        waypoints.Sort((a, b) => {
            string aNum = System.Text.RegularExpressions.Regex.Replace(a.name, "[^0-9]", "");
            string bNum = System.Text.RegularExpressions.Regex.Replace(b.name, "[^0-9]", "");
            
            int aInt = int.TryParse(aNum, out int numA) ? numA : 0;
            int bInt = int.TryParse(bNum, out int numB) ? numB : 0;
            
            return aInt.CompareTo(bInt);
        });
    }

    public List<Vector3> GetPath()
    {
        List<Vector3> path = new List<Vector3>();
        
        foreach (Transform waypoint in waypoints)
        {
            path.Add(waypoint.position);
        }
        
        if (endPoint != null)
        {
            path.Add(endPoint.position);
        }
        
        return path;
    }

    public Vector3 GetStartPoint()
    {
        return startPoint != null ? startPoint.position : Vector3.zero;
    }

    public Vector3 GetEndPoint()
    {
        return endPoint != null ? endPoint.position : Vector3.zero;
    }

    // 可视化路径
    void OnDrawGizmos()
    {
        if (waypoints.Count > 0)
        {
            Vector3 previousPoint = waypoints[0].position;
            
            foreach (Transform waypoint in waypoints)
            {
                Gizmos.color = Color.red;
                Gizmos.DrawSphere(waypoint.position, 0.5f);
                
                if (waypoint != waypoints[0])
                {
                    Gizmos.color = Color.yellow;
                    Gizmos.DrawLine(previousPoint, waypoint.position);
                }
                
                previousPoint = waypoint.position;
            }
            
            // 绘制到终点的连线
            if (endPoint != null)
            {
                Gizmos.color = Color.yellow;
                Gizmos.DrawLine(previousPoint, endPoint.position);
            }
        }
    }
}

防御塔系统

using UnityEngine;
using System.Collections.Generic;

// 防御塔基类
public abstract class Tower : MonoBehaviour
{
    [Header("塔的基本属性")]
    public string towerName = "Tower";
    public int cost = 50;
    public int upgradeCost = 30;
    public int maxLevel = 3;
    public int currentLevel = 1;

    [Header("攻击属性")]
    public float range = 5f;
    public float fireRate = 1f; // 每秒攻击次数
    public int damage = 10;
    public float projectileSpeed = 10f;
    public GameObject projectilePrefab;

    [Header("目标选择")]
    public TargetingMode targetingMode = TargetingMode.ClosestToGoal;
    public LayerMask enemyLayerMask;

    [Header("视觉效果")]
    public Transform turret; // 炮塔旋转部分
    public GameObject muzzleFlash;
    public GameObject rangeIndicator;

    protected float lastFireTime = 0f;
    protected List<Enemy> enemiesInRange = new List<Enemy>();
    protected Enemy currentTarget;
    protected bool isInitialized = false;

    // 属性修改器
    protected float rangeMultiplier = 1f;
    protected float damageMultiplier = 1f;
    protected float fireRateMultiplier = 1f;

    public virtual void Initialize()
    {
        if (isInitialized) return;

        isInitialized = true;

        // 设置范围指示器
        if (rangeIndicator != null)
        {
            rangeIndicator.transform.localScale = Vector3.one * range * 2f;
            rangeIndicator.SetActive(false); // 默认隐藏
        }

        // 开始检测敌人
        StartCoroutine(DetectEnemiesCoroutine());
    }

    // 检测敌人协程
    private IEnumerator DetectEnemiesCoroutine()
    {
        while (true)
        {
            DetectEnemies();
            yield return new WaitForSeconds(0.5f); // 每0.5秒检测一次
        }
    }

    // 检测范围内的敌人
    private void DetectEnemies()
    {
        Collider2D[] hitColliders = Physics2D.OverlapCircleAll(transform.position, range, enemyLayerMask);
        
        enemiesInRange.Clear();
        
        foreach (Collider2D collider in hitColliders)
        {
            Enemy enemy = collider.GetComponent<Enemy>();
            if (enemy != null && enemy.isActiveAndEnabled)
            {
                enemiesInRange.Add(enemy);
            }
        }

        // 选择目标
        SelectTarget();
    }

    // 选择攻击目标
    private void SelectTarget()
    {
        if (enemiesInRange.Count == 0)
        {
            currentTarget = null;
            return;
        }

        switch (targetingMode)
        {
            case TargetingMode.ClosestToGoal:
                currentTarget = GetClosestToGoal();
                break;
            case TargetingMode.Strongest:
                currentTarget = GetStrongest();
                break;
            case TargetingMode.Weakest:
                currentTarget = GetWeakest();
                break;
            case TargetingMode.FirstEntered:
                currentTarget = enemiesInRange[0];
                break;
        }
    }

    // 获取最接近终点的敌人
    private Enemy GetClosestToGoal()
    {
        Enemy closest = null;
        float minDistance = float.MaxValue;

        foreach (Enemy enemy in enemiesInRange)
        {
            if (TowerDefenseManager.Instance.pathManager != null)
            {
                float distance = Vector3.Distance(enemy.transform.position, 
                    TowerDefenseManager.Instance.pathManager.GetEndPoint());
                
                if (distance < minDistance)
                {
                    minDistance = distance;
                    closest = enemy;
                }
            }
        }

        return closest;
    }

    // 获取最强的敌人
    private Enemy GetStrongest()
    {
        Enemy strongest = null;
        int maxHealth = 0;

        foreach (Enemy enemy in enemiesInRange)
        {
            if (enemy.currentHealth > maxHealth)
            {
                maxHealth = enemy.currentHealth;
                strongest = enemy;
            }
        }

        return strongest;
    }

    // 获取最弱的敌人
    private Enemy GetWeakest()
    {
        Enemy weakest = null;
        int minHealth = int.MaxValue;

        foreach (Enemy enemy in enemiesInRange)
        {
            if (enemy.currentHealth < minHealth)
            {
                minHealth = enemy.currentHealth;
                weakest = enemy;
            }
        }

        return weakest;
    }

    void Update()
    {
        if (!isInitialized) return;

        // 攻击逻辑
        if (currentTarget != null && CanFire())
        {
            AimAtTarget();
            FireAtTarget();
        }

        // 转向目标
        if (currentTarget != null && turret != null)
        {
            Vector3 direction = currentTarget.transform.position - turret.position;
            float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
            turret.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
        }
    }

    // 是否可以开火
    private bool CanFire()
    {
        return Time.time >= lastFireTime + (1f / (fireRate * fireRateMultiplier));
    }

    // 瞄准目标
    private void AimAtTarget()
    {
        if (turret != null && currentTarget != null)
        {
            Vector3 direction = currentTarget.transform.position - turret.position;
            float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
            turret.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
        }
    }

    // 攻击目标
    protected virtual void FireAtTarget()
    {
        lastFireTime = Time.time;

        if (projectilePrefab != null)
        {
            Vector3 firePos = turret != null ? turret.position : transform.position;
            GameObject projectileGO = Instantiate(projectilePrefab, firePos, turret.rotation);
            Projectile projectile = projectileGO.GetComponent<Projectile>();

            if (projectile != null)
            {
                projectile.Initialize(currentTarget, damage * damageMultiplier, projectileSpeed);
            }
        }

        // 显示枪口闪光
        if (muzzleFlash != null)
        {
            muzzleFlash.SetActive(true);
            Invoke("HideMuzzleFlash", 0.05f);
        }

        // 播放音效
        if (TowerDefenseAudioManager.Instance != null)
        {
            TowerDefenseAudioManager.Instance.PlaySFX("TowerShoot");
        }
    }

    private void HideMuzzleFlash()
    {
        if (muzzleFlash != null)
        {
            muzzleFlash.SetActive(false);
        }
    }

    // 升级塔
    public virtual void Upgrade()
    {
        if (currentLevel < maxLevel)
        {
            currentLevel++;
            ApplyUpgradeStats();
        }
    }

    // 应用升级属性
    protected virtual void ApplyUpgradeStats()
    {
        // 基础升级效果
        damage = Mathf.RoundToInt(damage * 1.3f);
        range = range * 1.1f;
        fireRate = fireRate * 1.1f;
    }

    // 应用属性修改器
    public void ApplyModifier(TowerModifier modifier)
    {
        switch (modifier.type)
        {
            case ModifierType.Range:
                rangeMultiplier *= modifier.value;
                break;
            case ModifierType.Damage:
                damageMultiplier *= modifier.value;
                break;
            case ModifierType.FireRate:
                fireRateMultiplier *= modifier.value;
                break;
        }
    }

    // 移除属性修改器
    public void RemoveModifier(TowerModifier modifier)
    {
        switch (modifier.type)
        {
            case ModifierType.Range:
                rangeMultiplier /= modifier.value;
                break;
            case ModifierType.Damage:
                damageMultiplier /= modifier.value;
                break;
            case ModifierType.FireRate:
                fireRateMultiplier /= modifier.value;
                break;
        }
    }

    // 显示范围
    public void ShowRange(bool show)
    {
        if (rangeIndicator != null)
        {
            rangeIndicator.SetActive(show);
        }
    }

    // 可视化范围
    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, range);
    }
}

// 目标选择模式
public enum TargetingMode
{
    ClosestToGoal,  // 最接近终点
    Strongest,      // 最强的
    Weakest,        // 最弱的
    FirstEntered    // 第一个进入范围的
}

// 塔的属性修改器
[System.Serializable]
public class TowerModifier
{
    public ModifierType type;
    public float value = 1.1f; // 增加的倍数
    public float duration = -1f; // 持续时间,-1表示永久
}

public enum ModifierType
{
    Range,
    Damage,
    FireRate
}

// 具体的塔类型 - 炮塔
public class CannonTower : Tower
{
    [Header("炮塔特有属性")]
    public float explosionRadius = 2f;
    public int explosionDamage = 15;

    protected override void FireAtTarget()
    {
        lastFireTime = Time.time;

        // 发射爆炸炮弹
        if (projectilePrefab != null)
        {
            Vector3 firePos = turret != null ? turret.position : transform.position;
            GameObject projectileGO = Instantiate(projectilePrefab, firePos, turret.rotation);
            ExplosionProjectile projectile = projectileGO.GetComponent<ExplosionProjectile>();

            if (projectile != null)
            {
                projectile.Initialize(currentTarget, damage * damageMultiplier, projectileSpeed, explosionRadius, explosionDamage * damageMultiplier);
            }
        }

        // 显示枪口闪光
        if (muzzleFlash != null)
        {
            muzzleFlash.SetActive(true);
            Invoke("HideMuzzleFlash", 0.05f);
        }

        // 播放音效
        if (TowerDefenseAudioManager.Instance != null)
        {
            TowerDefenseAudioManager.Instance.PlaySFX("CannonShoot");
        }
    }

    protected override void ApplyUpgradeStats()
    {
        base.ApplyUpgradeStats();
        
        // 炮塔特有升级
        explosionRadius *= 1.1f;
        explosionDamage = Mathf.RoundToInt(explosionDamage * 1.2f);
    }
}

// 具体的塔类型 - 箭塔
public class ArrowTower : Tower
{
    [Header("箭塔特有属性")]
    public float slowPercentage = 0.3f; // 减速百分比
    public float slowDuration = 1f; // 减速持续时间

    protected override void FireAtTarget()
    {
        lastFireTime = Time.time;

        // 发射减速箭
        if (projectilePrefab != null)
        {
            Vector3 firePos = turret != null ? turret.position : transform.position;
            GameObject projectileGO = Instantiate(projectilePrefab, firePos, turret.rotation);
            SlowProjectile projectile = projectileGO.GetComponent<SlowProjectile>();

            if (projectile != null)
            {
                projectile.Initialize(currentTarget, damage * damageMultiplier, projectileSpeed, slowPercentage, slowDuration);
            }
        }

        // 显示枪口闪光
        if (muzzleFlash != null)
        {
            muzzleFlash.SetActive(true);
            Invoke("HideMuzzleFlash", 0.05f);
        }

        // 播放音效
        if (TowerDefenseAudioManager.Instance != null)
        {
            TowerDefenseAudioManager.Instance.PlaySFX("ArrowShoot");
        }
    }

    protected override void ApplyUpgradeStats()
    {
        base.ApplyUpgradeStats();
        
        // 箭塔特有升级
        slowPercentage += 0.05f;
        slowDuration += 0.2f;
    }
}

// 具体的塔类型 - 激光塔
public class LaserTower : Tower
{
    [Header("激光塔特有属性")]
    public LineRenderer laserLine;
    public float laserWidth = 0.1f;
    public float pierceCount = 1; // 穿透数量

    void Start()
    {
        if (laserLine == null)
        {
            laserLine = GetComponent<LineRenderer>();
            if (laserLine == null)
            {
                laserLine = gameObject.AddComponent<LineRenderer>();
            }
        }

        if (laserLine != null)
        {
            laserLine.startWidth = laserWidth;
            laserLine.endWidth = laserWidth;
            laserLine.enabled = false;
        }
    }

    void Update()
    {
        if (!isInitialized) return;

        if (currentTarget != null && Vector3.Distance(transform.position, currentTarget.transform.position) <= range)
        {
            if (CanFire())
            {
                AimAtTarget();
                FireAtTarget();
            }
        }
        else
        {
            if (laserLine != null)
            {
                laserLine.enabled = false;
            }
        }
    }

    protected override void FireAtTarget()
    {
        if (laserLine != null && currentTarget != null)
        {
            laserLine.enabled = true;
            laserLine.SetPosition(0, transform.position);
            laserLine.SetPosition(1, currentTarget.transform.position);

            // 对目标造成持续伤害
            currentTarget.TakeDamage(damage * damageMultiplier * Time.deltaTime);
        }

        // 激光塔不需要重置lastFireTime,因为是持续攻击
    }

    protected override void ApplyUpgradeStats()
    {
        base.ApplyUpgradeStats();
        
        // 激光塔特有升级
        pierceCount += 1;
        damage = Mathf.RoundToInt(damage * 1.1f);
    }
}

// 投射物类
public abstract class Projectile : MonoBehaviour
{
    protected Enemy target;
    protected int damage;
    protected float speed;
    protected Vector3 direction;
    protected float lifeTime = 5f;
    protected float lifeTimer = 0f;

    public virtual void Initialize(Enemy target, int damage, float speed)
    {
        this.target = target;
        this.damage = damage;
        this.speed = speed;
        
        if (target != null)
        {
            direction = (target.transform.position - transform.position).normalized;
            transform.right = direction; // 设置朝向
        }
    }

    void Update()
    {
        Move();
        lifeTimer += Time.deltaTime;

        if (lifeTimer >= lifeTime || target == null)
        {
            Destroy(gameObject);
        }
    }

    protected virtual void Move()
    {
        transform.Translate(direction * speed * Time.deltaTime);
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Enemy") && other.gameObject == target.gameObject)
        {
            OnHitEnemy(other.GetComponent<Enemy>());
            OnHit();
        }
        else if (other.CompareTag("Obstacle"))
        {
            OnHit();
        }
    }

    protected virtual void OnHitEnemy(Enemy enemy)
    {
        if (enemy != null)
        {
            enemy.TakeDamage(damage);
        }
    }

    protected virtual void OnHit()
    {
        // 投射物命中后的处理
        Destroy(gameObject);
    }
}

// 爆炸投射物
public class ExplosionProjectile : Projectile
{
    public float explosionRadius = 2f;
    public int explosionDamage = 15;
    public GameObject explosionEffect;

    public void Initialize(Enemy target, int damage, float speed, float explosionRadius, int explosionDamage)
    {
        base.Initialize(target, damage, speed);
        this.explosionRadius = explosionRadius;
        this.explosionDamage = explosionDamage;
    }

    protected override void OnHit()
    {
        // 创建爆炸效果
        if (explosionEffect != null)
        {
            Instantiate(explosionEffect, transform.position, Quaternion.identity);
        }

        // 对范围内的敌人造成伤害
        Collider2D[] hitColliders = Physics2D.OverlapCircleAll(transform.position, explosionRadius);
        
        foreach (Collider2D collider in hitColliders)
        {
            if (collider.CompareTag("Enemy"))
            {
                Enemy enemy = collider.GetComponent<Enemy>();
                if (enemy != null)
                {
                    enemy.TakeDamage(explosionDamage);
                }
            }
        }

        // 播放音效
        if (TowerDefenseAudioManager.Instance != null)
        {
            TowerDefenseAudioManager.Instance.PlaySFX("Explosion");
        }

        Destroy(gameObject);
    }
}

// 减速投射物
public class SlowProjectile : Projectile
{
    public float slowPercentage = 0.3f;
    public float slowDuration = 1f;

    public void Initialize(Enemy target, int damage, float speed, float slowPercentage, float slowDuration)
    {
        base.Initialize(target, damage, speed);
        this.slowPercentage = slowPercentage;
        this.slowDuration = slowDuration;
    }

    protected override void OnHitEnemy(Enemy enemy)
    {
        if (enemy != null)
        {
            enemy.TakeDamage(damage);
            enemy.ApplySlow(slowPercentage, slowDuration);
        }
    }
}

敌人系统

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

// 敌人类
[RequireComponent(typeof(Rigidbody2D))]
public class Enemy : MonoBehaviour
{
    [Header("敌人属性")]
    public EnemyType enemyType;
    public int maxHealth = 100;
    public int currentHealth;
    public float speed = 2f;
    public int reward = 10;
    public int armor = 0;
    public float slowResistance = 0.5f; // 减速抵抗

    [Header("视觉效果")]
    public SpriteRenderer spriteRenderer;
    public GameObject deathEffect;
    public Material slowMaterial; // 减速时的材质

    [Header("状态")]
    public bool isSlowed = false;
    public float slowMultiplier = 1f;
    public float slowDuration = 0f;

    private Rigidbody2D rb;
    private List<Vector3> path;
    private int currentWaypointIndex = 0;
    private Material originalMaterial;
    private bool hasReachedEnd = false;

    // 事件
    public System.Action<Enemy, int> OnEnemyKilled;
    public System.Action<Enemy> OnEnemyReachedEnd;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        
        if (spriteRenderer == null)
        {
            spriteRenderer = GetComponent<SpriteRenderer>();
        }

        currentHealth = maxHealth;

        // 保存原始材质
        if (spriteRenderer != null)
        {
            originalMaterial = spriteRenderer.material;
        }
    }

    public void Initialize(List<Vector3> path, EnemyStats stats)
    {
        this.path = path;
        this.maxHealth = stats.health;
        this.currentHealth = stats.health;
        this.speed = stats.speed;
        this.reward = stats.reward;
        this.armor = stats.armor;
    }

    void Update()
    {
        if (path != null && currentWaypointIndex < path.Count && !hasReachedEnd)
        {
            MoveAlongPath();
        }

        UpdateSlowEffect();
    }

    private void MoveAlongPath()
    {
        if (currentWaypointIndex >= path.Count)
        {
            // 到达终点
            if (!hasReachedEnd)
            {
                hasReachedEnd = true;
                if (OnEnemyReachedEnd != null)
                {
                    OnEnemyReachedEnd(this);
                }
                Destroy(gameObject);
            }
            return;
        }

        Vector3 targetPosition = path[currentWaypointIndex];
        Vector3 direction = (targetPosition - transform.position).normalized;

        rb.velocity = direction * speed * slowMultiplier;

        // 检查是否到达当前路径点
        if (Vector3.Distance(transform.position, targetPosition) < 0.1f)
        {
            currentWaypointIndex++;
        }
    }

    // 受到伤害
    public void TakeDamage(int damage)
    {
        // 计算护甲减免
        int actualDamage = Mathf.Max(1, damage - armor);
        currentHealth -= actualDamage;

        // 更新视觉效果(比如血量条)
        UpdateVisualEffect();

        if (currentHealth <= 0)
        {
            Die();
        }
    }

    // 应用减速效果
    public void ApplySlow(float slowPercentage, float duration)
    {
        // 考虑减速抵抗
        float actualSlow = slowPercentage * (1f - slowResistance);
        slowMultiplier = 1f - actualSlow;
        slowDuration = duration;

        // 应用减速视觉效果
        ApplySlowVisualEffect();
    }

    // 更新减速效果
    private void UpdateSlowEffect()
    {
        if (isSlowed)
        {
            slowDuration -= Time.deltaTime;
            if (slowDuration <= 0)
            {
                ResetSlowEffect();
            }
        }
    }

    // 重置减速效果
    private void ResetSlowEffect()
    {
        isSlowed = false;
        slowMultiplier = 1f;
        
        // 移除减速视觉效果
        if (spriteRenderer != null && originalMaterial != null)
        {
            spriteRenderer.material = originalMaterial;
        }
    }

    // 应用减速视觉效果
    private void ApplySlowVisualEffect()
    {
        isSlowed = true;
        if (spriteRenderer != null && slowMaterial != null)
        {
            spriteRenderer.material = slowMaterial;
        }
    }

    // 更新视觉效果
    private void UpdateVisualEffect()
    {
        // 这里可以更新血量条、闪烁效果等
        if (spriteRenderer != null)
        {
            // 简单的受伤闪烁效果
            StartCoroutine(FlashRed());
        }
    }

    // 受伤闪烁效果
    private IEnumerator FlashRed()
    {
        if (spriteRenderer != null)
        {
            Color originalColor = spriteRenderer.color;
            spriteRenderer.color = Color.red;
            yield return new WaitForSeconds(0.1f);
            spriteRenderer.color = originalColor;
        }
    }

    // 死亡
    private void Die()
    {
        // 播放死亡效果
        if (deathEffect != null)
        {
            Instantiate(deathEffect, transform.position, Quaternion.identity);
        }

        // 给予奖励
        if (OnEnemyKilled != null)
        {
            OnEnemyKilled(this, reward);
        }

        // 播放音效
        if (TowerDefenseAudioManager.Instance != null)
        {
            TowerDefenseAudioManager.Instance.PlaySFX("EnemyDie");
        }

        // 销毁敌人
        Destroy(gameObject);
    }

    // 获取生命值百分比
    public float GetHealthPercentage()
    {
        return (float)currentHealth / maxHealth;
    }

    // 可视化生命值
    void OnDrawGizmos()
    {
        // 显示生命值条
        if (currentHealth < maxHealth)
        {
            Vector3 screenPos = Camera.current.WorldToScreenPoint(transform.position + Vector3.up * 1f);
            if (Camera.current != null)
            {
                // 绘制生命值条(在场景视图中)
                Gizmos.color = Color.red;
                Vector3 healthBarSize = new Vector3(1f, 0.1f, 0f);
                Vector3 healthBarPos = transform.position + Vector3.up * 0.5f;
                Gizmos.DrawCube(healthBarPos, healthBarSize);

                Gizmos.color = Color.green;
                Vector3 filledHealthBarSize = new Vector3(1f * GetHealthPercentage(), 0.1f, 0f);
                Vector3 filledHealthBarPos = healthBarPos + Vector3.left * (1f - GetHealthPercentage()) / 2f;
                Gizmos.DrawCube(filledHealthBarPos, filledHealthBarSize);
            }
        }
    }
}

UI和游戏控制

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

// 塔防游戏UI管理器
public class TowerDefenseUIManager : MonoBehaviour
{
    [Header("游戏UI")]
    public Text moneyText;
    public Text livesText;
    public Text waveText;
    public Text enemiesRemainingText;
    public Slider buildProgressSlider;
    public Text buildProgressText;

    [Header("建造菜单")]
    public GameObject buildMenu;
    public Button[] towerButtons;
    public Text[] towerCostTexts;

    [Header("游戏面板")]
    public GameObject gamePanel;
    public GameObject pausePanel;
    public GameObject gameOverPanel;
    public GameObject gameWinPanel;
    public GameObject towerInfoPanel;
    public Text towerInfoText;

    [Header("音效控制")]
    public Slider bgmVolumeSlider;
    public Slider sfxVolumeSlider;

    private bool isBuildMenuActive = false;
    private Tower selectedTowerForUpgrade;

    void Start()
    {
        InitializeUI();
        SetupVolumeSliders();
    }

    private void InitializeUI()
    {
        UpdateMoney(TowerDefenseManager.Instance?.currentMoney ?? 0);
        UpdateLives(TowerDefenseManager.Instance?.currentLives ?? 20);
        UpdateWave(TowerDefenseManager.Instance?.currentWave ?? 0, 
                  TowerDefenseManager.Instance?.waves.Count ?? 0);
        UpdateEnemiesRemaining(TowerDefenseManager.Instance?.enemiesRemaining ?? 0);
    }

    private void SetupVolumeSliders()
    {
        if (bgmVolumeSlider != null)
        {
            bgmVolumeSlider.onValueChanged.AddListener(OnBGMVolumeChanged);
        }

        if (sfxVolumeSlider != null)
        {
            sfxVolumeSlider.onValueChanged.AddListener(OnSFXVolumeChanged);
        }
    }

    public void UpdateMoney(int money)
    {
        if (moneyText != null)
        {
            moneyText.text = $"Money: ${money}";
        }
    }

    public void UpdateLives(int lives)
    {
        if (livesText != null)
        {
            livesText.text = $"Lives: {lives}";
        }
    }

    public void UpdateWave(int currentWave, int totalWaves)
    {
        if (waveText != null)
        {
            waveText.text = $"Wave: {currentWave + 1}/{totalWaves}";
        }
    }

    public void UpdateEnemiesRemaining(int remaining)
    {
        if (enemiesRemainingText != null)
        {
            enemiesRemainingText.text = $"Enemies: {remaining}";
        }
    }

    public void ShowBuildMenu(bool show)
    {
        isBuildMenuActive = show;
        if (buildMenu != null)
        {
            buildMenu.SetActive(show);
        }
    }

    public void ShowTowerInfo(Tower tower)
    {
        if (towerInfoPanel != null && towerInfoText != null)
        {
            towerInfoPanel.SetActive(true);
            
            string info = $"<b>{tower.towerName}</b>\n" +
                         $"Level: {tower.currentLevel}\n" +
                         $"Damage: {tower.damage}\n" +
                         $"Range: {tower.range:F1}\n" +
                         $"Fire Rate: {tower.fireRate:F1}/s\n" +
                         $"Cost: ${tower.upgradeCost}";
            
            towerInfoText.text = info;
            
            selectedTowerForUpgrade = tower;
        }
    }

    public void HideTowerInfo()
    {
        if (towerInfoPanel != null)
        {
            towerInfoPanel.SetActive(false);
        }
        selectedTowerForUpgrade = null;
    }

    public void ShowPauseMenu()
    {
        if (pausePanel != null)
        {
            pausePanel.SetActive(true);
        }
    }

    public void HidePauseMenu()
    {
        if (pausePanel != null)
        {
            pausePanel.SetActive(false);
        }
    }

    public void ShowGameOver()
    {
        if (gameOverPanel != null)
        {
            gameOverPanel.SetActive(true);
        }
        
        if (gamePanel != null)
        {
            gamePanel.SetActive(false);
        }
    }

    public void ShowGameWin()
    {
        if (gameWinPanel != null)
        {
            gameWinPanel.SetActive(true);
        }
        
        if (gamePanel != null)
        {
            gamePanel.SetActive(false);
        }
    }

    // 建造按钮事件
    public void OnCannonTowerButton()
    {
        if (TowerDefenseManager.Instance != null)
        {
            TowerDefenseManager.Instance.BuildTower(
                Resources.Load<Tower>("Prefabs/Towers/CannonTower"), 
                GetBuildPosition());
        }
    }

    public void OnArrowTowerButton()
    {
        if (TowerDefenseManager.Instance != null)
        {
            TowerDefenseManager.Instance.BuildTower(
                Resources.Load<Tower>("Prefabs/Towers/ArrowTower"), 
                GetBuildPosition());
        }
    }

    public void OnLaserTowerButton()
    {
        if (TowerDefenseManager.Instance != null)
        {
            TowerDefenseManager.Instance.BuildTower(
                Resources.Load<Tower>("Prefabs/Towers/LaserTower"), 
                GetBuildPosition());
        }
    }

    private Vector3 GetBuildPosition()
    {
        // 这里应该获取鼠标位置并转换为世界坐标
        // 简化处理,返回一个默认位置
        return Camera.main.ScreenToWorldPoint(Input.mousePosition + Vector3.forward * 10);
    }

    // 升级按钮事件
    public void OnUpgradeTowerButton()
    {
        if (selectedTowerForUpgrade != null && TowerDefenseManager.Instance != null)
        {
            TowerDefenseManager.Instance.UpgradeTower(selectedTowerForUpgrade);
            HideTowerInfo();
        }
    }

    // 按钮事件
    public void OnPauseButton()
    {
        Time.timeScale = 0f;
        ShowPauseMenu();
    }

    public void OnResumeButton()
    {
        Time.timeScale = 1f;
        HidePauseMenu();
    }

    public void OnRestartButton()
    {
        Time.timeScale = 1f;
        UnityEngine.SceneManagement.SceneManager.LoadScene(
            UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex);
    }

    public void OnMainMenuButton()
    {
        Time.timeScale = 1f;
        UnityEngine.SceneManagement.SceneManager.LoadScene(0); // 主菜单场景
    }

    public void OnQuitButton()
    {
        #if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
        #else
        Application.Quit();
        #endif
    }

    // 音量控制事件
    private void OnBGMVolumeChanged(float volume)
    {
        if (TowerDefenseAudioManager.Instance != null)
        {
            TowerDefenseAudioManager.Instance.SetBGMVolume(volume);
        }
    }

    private void OnSFXVolumeChanged(float volume)
    {
        if (TowerDefenseAudioManager.Instance != null)
        {
            TowerDefenseAudioManager.Instance.SetSFXVolume(volume);
        }
    }

    // 更新建造进度(如果有的话)
    public void UpdateBuildProgress(float progress, string status)
    {
        if (buildProgressSlider != null)
        {
            buildProgressSlider.value = progress;
        }

        if (buildProgressText != null)
        {
            buildProgressText.text = status;
        }
    }

    void Update()
    {
        // ESC键暂停游戏
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (pausePanel.activeSelf)
            {
                OnResumeButton();
            }
            else
            {
                OnPauseButton();
            }
        }
    }
}

// 塔防游戏音频管理器
public class TowerDefenseAudioManager : MonoBehaviour
{
    [Header("音频源")]
    public AudioSource bgmSource;
    public AudioSource sfxSource;

    [Header("音频剪辑")]
    public AudioClip[] bgmClips;
    public AudioClip[] sfxClips;

    private Dictionary<string, AudioClip> sfxDictionary = new Dictionary<string, AudioClip>();
    private Dictionary<string, AudioClip> bgmDictionary = new Dictionary<string, AudioClip>();

    public static TowerDefenseAudioManager Instance { get; private set; }

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

    void Start()
    {
        InitializeAudio();
    }

    private void InitializeAudio()
    {
        // 创建音频源(如果未设置)
        if (bgmSource == null)
        {
            GameObject bgmGO = new GameObject("TD_BGM_AudioSource");
            bgmGO.transform.SetParent(transform);
            bgmSource = bgmGO.AddComponent<AudioSource>();
            bgmSource.playOnAwake = false;
            bgmSource.loop = true;
        }

        if (sfxSource == null)
        {
            GameObject sfxGO = new GameObject("TD_SFX_AudioSource");
            sfxGO.transform.SetParent(transform);
            sfxSource = sfxGO.AddComponent<AudioSource>();
            sfxSource.playOnAwake = false;
            sfxSource.loop = false;
        }

        // 建立音频字典
        foreach (AudioClip clip in sfxClips)
        {
            if (clip != null)
            {
                sfxDictionary[clip.name] = clip;
            }
        }

        foreach (AudioClip clip in bgmClips)
        {
            if (clip != null)
            {
                bgmDictionary[clip.name] = clip;
            }
        }
    }

    public void PlaySFX(string sfxName)
    {
        if (sfxDictionary.TryGetValue(sfxName, out AudioClip clip))
        {
            sfxSource.PlayOneShot(clip);
        }
        else
        {
            Debug.LogWarning($"SFX '{sfxName}' not found!");
        }
    }

    public void PlayBGM(string bgmName, bool loop = true)
    {
        if (bgmDictionary.TryGetValue(bgmName, out AudioClip clip))
        {
            bgmSource.clip = clip;
            bgmSource.loop = loop;
            bgmSource.Play();
        }
        else
        {
            Debug.LogWarning($"BGM '{bgmName}' not found!");
        }
    }

    public void SetBGMVolume(float volume)
    {
        bgmSource.volume = volume;
    }

    public void SetSFXVolume(float volume)
    {
        sfxSource.volume = volume;
    }

    public void StopBGM()
    {
        bgmSource.Stop();
    }

    public void StopSFX()
    {
        sfxSource.Stop();
    }
}

// 建造控制器
public class BuildController : MonoBehaviour
{
    [Header("建造设置")]
    public LayerMask buildableLayerMask;
    public LayerMask enemyLayerMask;
    public GameObject buildPreview;
    public Color validBuildColor = Color.green;
    public Color invalidBuildColor = Color.red;

    private bool isBuilding = false;
    private Tower towerToBuild;
    private Vector3 buildPosition;
    private bool canBuild = false;

    void Update()
    {
        if (isBuilding)
        {
            UpdateBuildPreview();
            HandleBuildInput();
        }
    }

    public void StartBuilding(Tower tower)
    {
        if (TowerDefenseManager.Instance.SpendMoney(tower.cost))
        {
            isBuilding = true;
            towerToBuild = tower;
            
            if (buildPreview != null)
            {
                buildPreview.SetActive(true);
            }
        }
    }

    private void UpdateBuildPreview()
    {
        // 获取鼠标位置
        Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition + Vector3.forward * 10);
        
        // 将Y坐标设置为0(2D游戏)
        mousePos.z = 0;
        
        buildPosition = mousePos;
        
        if (buildPreview != null)
        {
            buildPreview.transform.position = buildPosition;
            
            // 检查是否可以建造
            canBuild = CanBuildAtPosition(buildPosition);
            
            // 设置预览颜色
            SpriteRenderer previewRenderer = buildPreview.GetComponent<SpriteRenderer>();
            if (previewRenderer != null)
            {
                previewRenderer.color = canBuild ? validBuildColor : invalidBuildColor;
            }
        }
    }

    private bool CanBuildAtPosition(Vector3 position)
    {
        // 检查是否有足够的金钱
        if (TowerDefenseManager.Instance.currentMoney < towerToBuild.cost)
        {
            return false;
        }

        // 检查是否有其他物体
        Collider2D[] colliders = Physics2D.OverlapCircleAll(position, 0.5f);
        
        foreach (Collider2D collider in colliders)
        {
            if (collider.CompareTag("Tower") || collider.CompareTag("Obstacle"))
            {
                return false; // 有塔或其他障碍物,不能建造
            }
        }

        // 检查是否在路径上
        PathManager pathManager = TowerDefenseManager.Instance.pathManager;
        if (pathManager != null)
        {
            foreach (Vector3 waypoint in pathManager.GetPath())
            {
                if (Vector3.Distance(position, waypoint) < 1f)
                {
                    return false; // 在路径上,不能建造
                }
            }
        }

        return true;
    }

    private void HandleBuildInput()
    {
        if (Input.GetMouseButtonDown(0) && canBuild)
        {
            BuildTower();
        }
        else if (Input.GetMouseButtonDown(1))
        {
            CancelBuilding();
        }
    }

    private void BuildTower()
    {
        if (towerToBuild != null && canBuild)
        {
            TowerDefenseManager.Instance.BuildTower(towerToBuild, buildPosition);
            EndBuilding();
        }
    }

    private void CancelBuilding()
    {
        // 退还金钱
        TowerDefenseManager.Instance.AddMoney(towerToBuild.cost);
        EndBuilding();
    }

    private void EndBuilding()
    {
        isBuilding = false;
        
        if (buildPreview != null)
        {
            buildPreview.SetActive(false);
        }
        
        towerToBuild = null;
    }

    // 可视化建造范围
    void OnDrawGizmos()
    {
        if (isBuilding && buildPreview != null)
        {
            Gizmos.color = canBuild ? Color.green : Color.red;
            Gizmos.DrawWireSphere(buildPosition, 0.5f);
        }
    }
}

RPG游戏系统

项目概述

RPG(Role-Playing Game)游戏类型强调角色成长、故事叙述和探索。这类游戏通常包含复杂的角色系统、技能树、装备系统、任务系统等。

核心功能:

  • 角色创建和成长系统
  • 战斗系统(回合制或即时制)
  • 技能和法术系统
  • 装备和物品系统
  • 任务和对话系统
  • 世界探索

角色和战斗系统

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

// RPG游戏管理器
public class RPGGameManager : MonoBehaviour
{
    [Header("游戏设置")]
    public int maxLevel = 99;
    public float experienceMultiplier = 1.5f;
    public float goldMultiplier = 1.2f;

    [Header("玩家设置")]
    public PlayerCharacter player;
    public List<CharacterClass> characterClasses = new List<CharacterClass>();
    public List<Skill> allSkills = new List<Skill>();
    public List<Item> allItems = new List<Item>();
    public List<Quest> allQuests = new List<Quest>();

    [Header("游戏系统")]
    public RPGUIManager uiManager;
    public RPGBattleSystem battleSystem;
    public RPGInventorySystem inventorySystem;
    public RPGQuestSystem questSystem;

    public static RPGGameManager Instance { get; private set; }

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

    void Start()
    {
        InitializeGame();
    }

    private void InitializeGame()
    {
        // 初始化玩家
        if (player == null)
        {
            player = new PlayerCharacter();
            player.Initialize("Hero", CharacterClassType.Warrior);
        }

        // 初始化各个系统
        InitializeSystems();
    }

    private void InitializeSystems()
    {
        if (battleSystem != null)
        {
            battleSystem.Initialize();
        }

        if (inventorySystem != null)
        {
            inventorySystem.Initialize();
        }

        if (questSystem != null)
        {
            questSystem.Initialize();
        }

        if (uiManager != null)
        {
            uiManager.Initialize();
        }
    }

    // 计算升级所需经验
    public int GetExperienceForLevel(int level)
    {
        // 使用公式:Exp = Base * (Multiplier ^ Level)
        int baseExp = 100;
        return Mathf.RoundToInt(baseExp * Mathf.Pow(experienceMultiplier, level - 1));
    }

    // 添加经验值
    public void AddExperience(int exp)
    {
        if (player != null)
        {
            int expBefore = player.experience;
            player.AddExperience(exp);

            // 检查是否升级
            if (player.level > expBefore / GetExperienceForLevel(expBefore))
            {
                OnLevelUp(player.level);
            }

            // 更新UI
            if (uiManager != null)
            {
                uiManager.UpdateExperience(player.experience, GetExperienceForLevel(player.level));
                uiManager.UpdateLevel(player.level);
            }
        }
    }

    // 等级提升事件
    private void OnLevelUp(int newLevel)
    {
        if (uiManager != null)
        {
            uiManager.ShowLevelUp(newLevel);
        }

        // 播放升级音效
        if (RPGAudioManager.Instance != null)
        {
            RPGAudioManager.Instance.PlaySFX("LevelUp");
        }

        // 给予属性点
        if (player != null)
        {
            player.attributePoints += 5; // 每级给予5个属性点
            player.skillPoints += 1; // 每级给予1个技能点
        }
    }

    // 添加金币
    public void AddGold(int amount)
    {
        if (player != null)
        {
            player.AddGold(amount);
            
            if (uiManager != null)
            {
                uiManager.UpdateGold(player.gold);
            }
        }
    }

    // 获取角色职业数据
    public CharacterClass GetCharacterClass(CharacterClassType classType)
    {
        return characterClasses.Find(c => c.classType == classType);
    }

    // 获取技能数据
    public Skill GetSkill(string skillName)
    {
        return allSkills.Find(s => s.skillName == skillName);
    }

    // 获取物品数据
    public Item GetItem(string itemName)
    {
        return allItems.Find(i => i.itemName == itemName);
    }

    // 获取任务数据
    public Quest GetQuest(string questName)
    {
        return allQuests.Find(q => q.questName == questName);
    }
}

// 角色类型
public enum CharacterClassType
{
    Warrior,
    Mage,
    Rogue,
    Cleric,
    Ranger,
    Paladin
}

// 角色职业数据
[System.Serializable]
public class CharacterClass
{
    public CharacterClassType classType;
    public string className;
    public string description;
    public float healthMultiplier = 1f;
    public float manaMultiplier = 1f;
    public float staminaMultiplier = 1f;
    public float strengthGrowth = 1f;
    public float dexterityGrowth = 1f;
    public float intelligenceGrowth = 1f;
    public float constitutionGrowth = 1f;
    public float luckGrowth = 1f;
    public List<string> startingSkills = new List<string>();
    public List<string> startingItems = new List<string>();
    public Color classColor = Color.white;
}

// 技能类型
public enum SkillType
{
    Active,
    Passive,
    Ultimate
}

// 技能目标类型
public enum SkillTargetType
{
    Self,
    Enemy,
    Ally,
    Area,
    Projectile
}

// 技能数据
[System.Serializable]
public class Skill
{
    public string skillName;
    public string description;
    public SkillType skillType;
    public SkillTargetType targetType;
    public int manaCost = 10;
    public float cooldown = 1f;
    public int requiredLevel = 1;
    public int damage = 0;
    public float range = 5f;
    public float castTime = 0f;
    public float duration = 0f;
    public int maxLevel = 1;
    public List<SkillUpgrade> upgrades = new List<SkillUpgrade>();
    public string animationName;
    public AudioClip castSound;
    public GameObject effectPrefab;
}

[System.Serializable]
public class SkillUpgrade
{
    public int level;
    public int damageIncrease;
    public float rangeIncrease;
    public float cooldownReduction;
    public string description;
}

// 物品类型
public enum ItemType
{
    Weapon,
    Armor,
    Consumable,
    QuestItem,
    Material,
    Accessory
}

// 物品稀有度
public enum ItemRarity
{
    Common,
    Uncommon,
    Rare,
    Epic,
    Legendary,
    Artifact
}

// 物品数据
[System.Serializable]
public class Item
{
    public string itemName;
    public string description;
    public ItemType itemType;
    public ItemRarity rarity;
    public int buyPrice = 10;
    public int sellPrice = 5;
    public int requiredLevel = 1;
    public int stackLimit = 1;
    public bool isConsumable = false;
    public bool isSoulbound = false;
    public bool isUnique = false;
    
    // 装备属性
    public int strength = 0;
    public int dexterity = 0;
    public int intelligence = 0;
    public int constitution = 0;
    public int luck = 0;
    public int healthBonus = 0;
    public int manaBonus = 0;
    public int armorBonus = 0;
    public int damageBonus = 0;
    public int magicPower = 0;
    public int criticalChance = 0;
    public int attackSpeed = 0;
    public int movementSpeed = 0;
    
    // 消耗品属性
    public int healthRestore = 0;
    public int manaRestore = 0;
    public float restorePercentage = 0f;
    public float duration = 0f;
    public int effectValue = 0;
    public string effectType;
    
    public Sprite icon;
    public GameObject prefab;
}

// 任务类型
public enum QuestType
{
    Fetch,
    Kill,
    Escort,
    Explore,
    Deliver,
    Defend
}

// 任务状态
public enum QuestStatus
{
    NotStarted,
    InProgress,
    Completed,
    Failed,
    Rewarded
}

// 任务数据
[System.Serializable]
public class Quest
{
    public string questName;
    public string description;
    public string objective;
    public QuestType questType;
    public int requiredLevel = 1;
    public int experienceReward = 100;
    public int goldReward = 50;
    public List<ItemReward> itemRewards = new List<ItemReward>();
    public List<QuestObjective> objectives = new List<QuestObjective>();
    public bool isRepeatable = false;
    public bool isMainQuest = false;
    public string questGiver;
    public string nextQuest;
    public float timeLimit = 0f; // 0表示无时间限制
}

[System.Serializable]
public class ItemReward
{
    public string itemName;
    public int quantity = 1;
    public int chance = 100; // 出现几率(0-100)
}

[System.Serializable]
public class QuestObjective
{
    public string description;
    public int targetCount = 1;
    public int currentCount = 0;
    public string targetName; // 敌人名称、物品名称等
    public bool isCompleted = false;
}

// 玩家角色类
public class PlayerCharacter
{
    // 基本信息
    public string characterName;
    public CharacterClassType characterClassType;
    public CharacterClass characterClass;

    // 等级和经验
    public int level = 1;
    public int experience = 0;
    public int skillPoints = 0;
    public int attributePoints = 0;

    // 属性
    public int strength = 10;
    public int dexterity = 10;
    public int intelligence = 10;
    public int constitution = 10;
    public int luck = 10;

    // 生命值和法力值
    public int maxHealth = 100;
    public int currentHealth = 100;
    public int maxMana = 50;
    public int currentMana = 50;
    public int maxStamina = 100;
    public int currentStamina = 100;

    // 战斗属性
    public int armor = 5;
    public int magicResist = 5;
    public int attackPower = 10;
    public int magicPower = 5;
    public int criticalChance = 5;
    public int attackSpeed = 100; // 百分比
    public int movementSpeed = 100; // 百分比

    // 经济
    public int gold = 100;

    // 装备
    public Dictionary<EquipmentSlot, Item> equipment = new Dictionary<EquipmentSlot, Item>();

    // 技能
    public List<Skill> knownSkills = new List<Skill>();
    public List<Skill> activeSkills = new List<Skill>();

    // 物品
    public List<Item> inventory = new List<Item>();
    public int inventorySize = 30;

    // 任务
    public List<Quest> activeQuests = new List<Quest>();
    public List<Quest> completedQuests = new List<Quest>();

    // 状态
    public bool isAlive = true;
    public bool isCasting = false;
    public bool isStunned = false;
    public bool isSilenced = false;

    public PlayerCharacter()
    {
        // 初始化装备槽
        foreach (EquipmentSlot slot in System.Enum.GetValues(typeof(EquipmentSlot)))
        {
            equipment[slot] = null;
        }
    }

    public void Initialize(string name, CharacterClassType classType)
    {
        characterName = name;
        characterClassType = classType;
        characterClass = RPGGameManager.Instance.GetCharacterClass(classType);

        // 根据职业设置基础属性
        if (characterClass != null)
        {
            strength = Mathf.RoundToInt(10 * characterClass.strengthGrowth);
            dexterity = Mathf.RoundToInt(10 * characterClass.dexterityGrowth);
            intelligence = Mathf.RoundToInt(10 * characterClass.intelligenceGrowth);
            constitution = Mathf.RoundToInt(10 * characterClass.constitutionGrowth);
            luck = Mathf.RoundToInt(10 * characterClass.luckGrowth);

            maxHealth = Mathf.RoundToInt(100 * characterClass.healthMultiplier);
            currentHealth = maxHealth;
            maxMana = Mathf.RoundToInt(50 * characterClass.manaMultiplier);
            currentMana = maxMana;
            maxStamina = Mathf.RoundToInt(100 * characterClass.staminaMultiplier);
            currentStamina = maxStamina;

            // 添加职业技能
            foreach (string skillName in characterClass.startingSkills)
            {
                Skill skill = RPGGameManager.Instance.GetSkill(skillName);
                if (skill != null)
                {
                    knownSkills.Add(skill);
                }
            }

            // 添加初始物品
            foreach (string itemName in characterClass.startingItems)
            {
                Item item = RPGGameManager.Instance.GetItem(itemName);
                if (item != null)
                {
                    AddItem(item, 1);
                }
            }
        }
    }

    // 添加经验值
    public void AddExperience(int exp)
    {
        experience += exp;

        // 检查是否升级
        int expForNextLevel = RPGGameManager.Instance.GetExperienceForLevel(level + 1);
        while (experience >= expForNextLevel && level < RPGGameManager.Instance.maxLevel)
        {
            level++;
            experience -= expForNextLevel;
            skillPoints++;
            attributePoints += 5;

            // 升级属性
            maxHealth = Mathf.RoundToInt(maxHealth * 1.1f);
            currentHealth = maxHealth;
            maxMana = Mathf.RoundToInt(maxMana * 1.1f);
            currentMana = maxMana;
            maxStamina = Mathf.RoundToInt(maxStamina * 1.1f);
            currentStamina = maxStamina;

            expForNextLevel = RPGGameManager.Instance.GetExperienceForLevel(level + 1);
        }
    }

    // 添加金币
    public void AddGold(int amount)
    {
        gold += amount;
    }

    // 添加物品到背包
    public bool AddItem(Item item, int quantity = 1)
    {
        if (inventory.Count >= inventorySize)
        {
            return false; // 背包已满
        }

        // 检查是否已有相同物品且可堆叠
        Item existingItem = inventory.Find(i => i.itemName == item.itemName && i.stackLimit > 1);
        if (existingItem != null && existingItem.stackLimit > existingItem.quantity)
        {
            int newQuantity = Mathf.Min(existingItem.quantity + quantity, existingItem.stackLimit);
            existingItem.quantity = newQuantity;
            return true;
        }
        else if (inventory.Count < inventorySize)
        {
            Item newItem = CreateItemCopy(item);
            newItem.quantity = quantity;
            inventory.Add(newItem);
            return true;
        }

        return false; // 无法添加
    }

    // 移除物品
    public bool RemoveItem(string itemName, int quantity = 1)
    {
        Item item = inventory.Find(i => i.itemName == itemName);
        if (item != null)
        {
            if (item.quantity > quantity)
            {
                item.quantity -= quantity;
            }
            else
            {
                inventory.Remove(item);
            }
            return true;
        }
        return false;
    }

    // 创建物品副本
    private Item CreateItemCopy(Item original)
    {
        Item copy = new Item();
        System.Reflection.FieldInfo[] fields = typeof(Item).GetFields();
        foreach (System.Reflection.FieldInfo field in fields)
        {
            field.SetValue(copy, field.GetValue(original));
        }
        return copy;
    }

    // 装备物品
    public bool EquipItem(Item item)
    {
        if (item.itemType != ItemType.Weapon && 
            item.itemType != ItemType.Armor && 
            item.itemType != ItemType.Accessory)
        {
            return false; // 只能装备武器、护甲和饰品
        }

        EquipmentSlot slot = GetEquipmentSlot(item);
        if (slot == EquipmentSlot.None)
        {
            return false;
        }

        // 如果该槽位已有装备,先卸下
        if (equipment[slot] != null)
        {
            UnequipItem(slot);
        }

        // 装备新物品
        equipment[slot] = item;

        // 应用属性加成
        ApplyItemStats(item, true);

        return true;
    }

    // 卸下物品
    public bool UnequipItem(EquipmentSlot slot)
    {
        if (equipment.ContainsKey(slot) && equipment[slot] != null)
        {
            Item item = equipment[slot];
            equipment[slot] = null;

            // 移除属性加成
            ApplyItemStats(item, false);

            // 将物品放回背包
            AddItem(item, 1);

            return true;
        }
        return false;
    }

    // 获取装备槽
    private EquipmentSlot GetEquipmentSlot(Item item)
    {
        switch (item.itemType)
        {
            case ItemType.Weapon:
                return EquipmentSlot.Weapon;
            case ItemType.Armor:
                if (item.itemName.Contains("Helmet") || item.itemName.Contains("Head"))
                    return EquipmentSlot.Head;
                else if (item.itemName.Contains("Chest") || item.itemName.Contains("Armor"))
                    return EquipmentSlot.Chest;
                else if (item.itemName.Contains("Legs") || item.itemName.Contains("Pants"))
                    return EquipmentSlot.Legs;
                else if (item.itemName.Contains("Boots") || item.itemName.Contains("Shoes"))
                    return EquipmentSlot.Feet;
                else if (item.itemName.Contains("Gloves"))
                    return EquipmentSlot.Hands;
                break;
            case ItemType.Accessory:
                if (equipment[EquipmentSlot.Accessory1] == null)
                    return EquipmentSlot.Accessory1;
                else if (equipment[EquipmentSlot.Accessory2] == null)
                    return EquipmentSlot.Accessory2;
                break;
        }

        return EquipmentSlot.None;
    }

    // 应用物品属性
    private void ApplyItemStats(Item item, bool isEquipping)
    {
        int multiplier = isEquipping ? 1 : -1;

        strength += item.strength * multiplier;
        dexterity += item.dexterity * multiplier;
        intelligence += item.intelligence * multiplier;
        constitution += item.constitution * multiplier;
        luck += item.luck * multiplier;

        maxHealth += item.healthBonus * multiplier;
        maxMana += item.manaBonus * multiplier;
        armor += item.armorBonus * multiplier;
        attackPower += item.damageBonus * multiplier;
        magicPower += item.magicPower * multiplier;
        criticalChance += item.criticalChance * multiplier;
        attackSpeed += item.attackSpeed * multiplier;
        movementSpeed += item.movementSpeed * multiplier;
    }

    // 学习技能
    public bool LearnSkill(string skillName)
    {
        if (skillPoints <= 0)
        {
            return false;
        }

        Skill skill = RPGGameManager.Instance.GetSkill(skillName);
        if (skill != null && skill.requiredLevel <= level)
        {
            if (!knownSkills.Contains(skill))
            {
                knownSkills.Add(skill);
                skillPoints--;
                return true;
            }
        }

        return false;
    }

    // 使用技能
    public bool UseSkill(string skillName, Character target = null)
    {
        if (isCasting || isStunned || isSilenced)
        {
            return false;
        }

        Skill skill = knownSkills.Find(s => s.skillName == skillName);
        if (skill == null || currentMana < skill.manaCost)
        {
            return false;
        }

        // 检查冷却
        if (activeSkills.Contains(skill))
        {
            return false; // 技能在冷却中
        }

        // 扣除法力值
        currentMana -= skill.manaCost;

        // 开始施法
        if (skill.castTime > 0)
        {
            isCasting = true;
            // 这里可以添加施法条UI
        }

        // 立即生效的技能
        if (skill.castTime == 0)
        {
            ExecuteSkill(skill, target);
        }

        // 添加到激活技能列表(用于冷却)
        activeSkills.Add(skill);

        // 开始冷却计时
        StartCoroutine(EndSkillCooldown(skill));

        return true;
    }

    // 执行技能效果
    private void ExecuteSkill(Skill skill, Character target)
    {
        switch (skill.skillType)
        {
            case SkillType.Active:
                // 对目标造成伤害或治疗
                if (target != null)
                {
                    if (skill.damage > 0)
                    {
                        int damage = Mathf.RoundToInt(skill.damage * (1 + magicPower / 100f));
                        target.TakeDamage(damage);
                    }
                }
                break;
            case SkillType.Passive:
                // 被动技能效果在属性计算时应用
                break;
            case SkillType.Ultimate:
                // 终极技能特殊效果
                break;
        }

        // 播放技能效果
        if (skill.effectPrefab != null)
        {
            // 实例化技能效果
        }

        // 播放音效
        if (skill.castSound != null && RPGAudioManager.Instance != null)
        {
            RPGAudioManager.Instance.PlaySFX(skill.castSound.name);
        }
    }

    // 技能冷却协程
    private IEnumerator EndSkillCooldown(Skill skill)
    {
        yield return new WaitForSeconds(skill.cooldown);
        activeSkills.Remove(skill);
        isCasting = false;
    }

    // 受到伤害
    public void TakeDamage(int damage)
    {
        if (!isAlive) return;

        // 计算护甲减免
        int armorReduction = Mathf.RoundToInt(damage * armor / (armor + 100f));
        int finalDamage = damage - armorReduction;

        currentHealth -= finalDamage;

        if (currentHealth <= 0)
        {
            Die();
        }
    }

    // 治疗
    public void Heal(int amount)
    {
        currentHealth = Mathf.Min(maxHealth, currentHealth + amount);
    }

    // 恢复法力
    public void RestoreMana(int amount)
    {
        currentMana = Mathf.Min(maxMana, currentMana + amount);
    }

    // 死亡
    private void Die()
    {
        isAlive = false;

        // 可以添加死亡效果
        if (RPGAudioManager.Instance != null)
        {
            RPGAudioManager.Instance.PlaySFX("PlayerDie");
        }

        // 可以添加复活逻辑
    }

    // 使用物品
    public bool UseItem(string itemName)
    {
        Item item = inventory.Find(i => i.itemName == itemName && i.isConsumable);
        if (item != null)
        {
            // 应用物品效果
            if (item.healthRestore > 0)
            {
                Heal(item.healthRestore);
            }

            if (item.manaRestore > 0)
            {
                RestoreMana(item.manaRestore);
            }

            // 按比例恢复
            if (item.restorePercentage > 0)
            {
                Heal(Mathf.RoundToInt(maxHealth * item.restorePercentage / 100f));
                RestoreMana(Mathf.RoundToInt(maxMana * item.restorePercentage / 100f));
            }

            // 移除使用过的物品
            RemoveItem(itemName, 1);

            return true;
        }

        return false;
    }

    // 获取属性总和(包括装备加成)
    public int GetTotalStrength() { return strength + GetEquipmentStat(e => e.strength); }
    public int GetTotalDexterity() { return dexterity + GetEquipmentStat(e => e.dexterity); }
    public int GetTotalIntelligence() { return intelligence + GetEquipmentStat(e => e.intelligence); }
    public int GetTotalConstitution() { return constitution + GetEquipmentStat(e => e.constitution); }
    public int GetTotalLuck() { return luck + GetEquipmentStat(e => e.luck); }

    // 获取装备提供的特定属性总和
    private int GetEquipmentStat(System.Func<Item, int> statSelector)
    {
        int total = 0;
        foreach (Item item in equipment.Values)
        {
            if (item != null)
            {
                total += statSelector(item);
            }
        }
        return total;
    }
}

// 装备槽枚举
public enum EquipmentSlot
{
    None,
    Weapon,
    Head,
    Chest,
    Legs,
    Feet,
    Hands,
    Accessory1,
    Accessory2
}

// 角色基类(用于玩家和敌人)
public abstract class Character : MonoBehaviour
{
    public string characterName;
    public int level = 1;
    public int maxHealth = 100;
    public int currentHealth;
    public int maxMana = 50;
    public int currentMana;
    public int attackPower = 10;
    public int magicPower = 5;
    public int armor = 5;
    public int magicResist = 5;
    public int criticalChance = 5;
    public float movementSpeed = 5f;

    public System.Action<Character> OnCharacterDeath;

    protected virtual void Start()
    {
        currentHealth = maxHealth;
        currentMana = maxMana;
    }

    // 受到伤害
    public virtual void TakeDamage(int damage)
    {
        // 计算护甲减免
        int armorReduction = Mathf.RoundToInt(damage * armor / (armor + 100f));
        int finalDamage = damage - armorReduction;

        currentHealth -= finalDamage;

        if (currentHealth <= 0)
        {
            Die();
        }
    }

    // 治疗
    public virtual void Heal(int amount)
    {
        currentHealth = Mathf.Min(maxHealth, currentHealth + amount);
    }

    // 恢复法力
    public virtual void RestoreMana(int amount)
    {
        currentMana = Mathf.Min(maxMana, currentMana + amount);
    }

    // 死亡
    protected virtual void Die()
    {
        if (OnCharacterDeath != null)
        {
            OnCharacterDeath(this);
        }

        // 给予经验值和金币
        PlayerCharacter player = FindObjectOfType<PlayerCharacter>();
        if (player != null)
        {
            int expReward = Mathf.RoundToInt(50 * (level / (float)player.level));
            int goldReward = Mathf.RoundToInt(20 * (level / (float)player.level));
            
            RPGGameManager.Instance.AddExperience(expReward);
            RPGGameManager.Instance.AddGold(goldReward);
        }

        // 销毁角色
        Destroy(gameObject);
    }

    // 获取生命值百分比
    public float GetHealthPercentage()
    {
        return (float)currentHealth / maxHealth;
    }

    // 获取法力值百分比
    public float GetManaPercentage()
    {
        return (float)currentMana / maxMana;
    }
}

战斗系统

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

// RPG战斗系统
public class RPGBattleSystem : MonoBehaviour
{
    [Header("战斗设置")]
    public BattleType battleType = BattleType.RealTime;
    public float turnDuration = 30f; // 回合制战斗的回合时长
    public float actionDelay = 0.5f; // 行动延迟

    [Header("战斗队伍")]
    public List<Character> playerTeam = new List<Character>();
    public List<Character> enemyTeam = new List<Character>();

    [Header("战斗状态")]
    public bool isBattleActive = false;
    public bool isPlayerTurn = true;
    public Character currentActor;
    public List<Character> battleQueue = new List<Character>();

    [Header("UI引用")]
    public RPGBattleUI battleUI;

    private Queue<BattleAction> actionQueue = new Queue<BattleAction>();
    private float turnTimer = 0f;
    private bool isProcessingAction = false;

    public void Initialize()
    {
        // 初始化战斗系统
    }

    // 开始战斗
    public void StartBattle(List<Character> playerCharacters, List<Character> enemyCharacters)
    {
        playerTeam = playerCharacters;
        enemyTeam = enemyCharacters;
        isBattleActive = true;
        isPlayerTurn = true;

        // 初始化战斗队列(根据速度排序)
        InitializeBattleQueue();

        if (battleUI != null)
        {
            battleUI.ShowBattleUI(true);
            UpdateBattleUI();
        }

        if (battleType == BattleType.TurnBased)
        {
            StartTurn();
        }
    }

    // 初始化战斗队列
    private void InitializeBattleQueue()
    {
        battleQueue.Clear();
        
        // 合并所有角色
        List<Character> allCharacters = new List<Character>();
        allCharacters.AddRange(playerTeam);
        allCharacters.AddRange(enemyTeam);

        // 根据速度排序(速度高的先行动)
        allCharacters.Sort((a, b) => b.movementSpeed.CompareTo(a.movementSpeed));
        
        battleQueue.AddRange(allCharacters);
    }

    // 开始回合
    private void StartTurn()
    {
        if (battleQueue.Count == 0)
        {
            EndBattle();
            return;
        }

        currentActor = battleQueue[0];
        battleQueue.RemoveAt(0);
        battleQueue.Add(currentActor); // 将行动者移到队尾

        turnTimer = turnDuration;

        if (currentActor is PlayerCharacter)
        {
            isPlayerTurn = true;
            if (battleUI != null)
            {
                battleUI.ShowActionSelection(currentActor);
            }
        }
        else
        {
            isPlayerTurn = false;
            StartCoroutine(EnemyTurn());
        }

        UpdateBattleUI();
    }

    // 敌人回合
    private IEnumerator EnemyTurn()
    {
        yield return new WaitForSeconds(actionDelay);

        // AI选择行动
        BattleAction action = SelectEnemyAction(currentActor);

        if (action != null)
        {
            ProcessAction(action);
        }
        else
        {
            EndTurn();
        }
    }

    // 选择敌人行动
    private BattleAction SelectEnemyAction(Character enemy)
    {
        // 简单的AI:随机选择目标并使用基础攻击
        List<Character> targets = isPlayerTurn ? new List<Character>(playerTeam) : new List<Character>(enemyTeam);
        
        // 移除已死亡的目标
        targets.RemoveAll(c => c.currentHealth <= 0);

        if (targets.Count > 0)
        {
            Character target = targets[Random.Range(0, targets.Count)];
            
            return new BattleAction
            {
                actor = enemy,
                actionType = BattleActionType.Attack,
                target = target,
                skill = null
            };
        }

        return null;
    }

    // 玩家选择行动
    public void PlayerSelectAction(BattleAction action)
    {
        if (isPlayerTurn && currentActor == action.actor)
        {
            actionQueue.Enqueue(action);
            
            if (battleUI != null)
            {
                battleUI.HideActionSelection();
            }

            // 立即处理行动或等待所有玩家行动
            if (battleType == BattleType.TurnBased)
            {
                ProcessAction(action);
            }
        }
    }

    // 处理行动
    private void ProcessAction(BattleAction action)
    {
        if (isProcessingAction) return;

        isProcessingAction = true;
        StartCoroutine(ExecuteAction(action));
    }

    // 执行行动协程
    private IEnumerator ExecuteAction(BattleAction action)
    {
        yield return new WaitForSeconds(actionDelay);

        switch (action.actionType)
        {
            case BattleActionType.Attack:
                ExecuteAttack(action);
                break;
            case BattleActionType.Skill:
                ExecuteSkill(action);
                break;
            case BattleActionType.Item:
                ExecuteItem(action);
                break;
            case BattleActionType.Defend:
                ExecuteDefend(action);
                break;
        }

        yield return new WaitForSeconds(actionDelay);

        isProcessingAction = false;

        if (battleType == BattleType.TurnBased)
        {
            // 检查战斗是否结束
            if (!CheckBattleEnd())
            {
                EndTurn();
            }
        }
        else
        {
            // 即时战斗继续
            UpdateBattleUI();
        }
    }

    // 执行攻击
    private void ExecuteAttack(BattleAction action)
    {
        if (action.target != null)
        {
            int damage = Mathf.RoundToInt(action.actor.attackPower * (1f + Random.Range(-0.1f, 0.1f)));
            
            // 检查暴击
            if (Random.Range(0, 100) < action.actor.criticalChance)
            {
                damage *= 2;
                if (battleUI != null)
                {
                    battleUI.ShowCriticalHit(action.target);
                }
            }

            action.target.TakeDamage(damage);

            if (battleUI != null)
            {
                battleUI.ShowDamage(action.target, damage);
            }

            // 播放攻击音效
            if (RPGAudioManager.Instance != null)
            {
                RPGAudioManager.Instance.PlaySFX("Attack");
            }
        }
    }

    // 执行技能
    private void ExecuteSkill(BattleAction action)
    {
        if (action.skill != null && action.target != null)
        {
            // 扣除法力值
            if (action.actor is PlayerCharacter player)
            {
                player.currentMana -= action.skill.manaCost;
            }

            // 计算技能伤害
            int damage = Mathf.RoundToInt(action.skill.damage * (1f + action.actor.magicPower / 100f));
            action.target.TakeDamage(damage);

            if (battleUI != null)
            {
                battleUI.ShowSkillEffect(action.skill, action.target, damage);
            }

            // 播放技能音效
            if (action.skill.castSound != null && RPGAudioManager.Instance != null)
            {
                RPGAudioManager.Instance.PlaySFX(action.skill.castSound.name);
            }
        }
    }

    // 使用物品
    private void ExecuteItem(BattleAction action)
    {
        if (action.item != null && action.target != null)
        {
            // 应用物品效果到目标
            if (action.item.healthRestore > 0)
            {
                action.target.Heal(action.item.healthRestore);
                if (battleUI != null)
                {
                    battleUI.ShowHealEffect(action.target, action.item.healthRestore);
                }
            }

            // 从玩家背包中移除物品
            if (action.actor is PlayerCharacter player)
            {
                player.RemoveItem(action.item.itemName, 1);
            }
        }
    }

    // 防御
    private void ExecuteDefend(BattleAction action)
    {
        // 防御状态,减少受到的伤害
        // 这里可以设置一个防御标志或临时增加护甲
        if (battleUI != null)
        {
            battleUI.ShowDefendEffect(action.actor);
        }
    }

    // 结束回合
    private void EndTurn()
    {
        if (battleType == BattleType.TurnBased)
        {
            StartTurn();
        }
    }

    // 检查战斗是否结束
    private bool CheckBattleEnd()
    {
        bool playerTeamDefeated = true;
        bool enemyTeamDefeated = true;

        foreach (Character character in playerTeam)
        {
            if (character.currentHealth > 0)
            {
                playerTeamDefeated = false;
                break;
            }
        }

        foreach (Character character in enemyTeam)
        {
            if (character.currentHealth > 0)
            {
                enemyTeamDefeated = false;
                break;
            }
        }

        if (playerTeamDefeated)
        {
            EndBattle(false); // 玩家失败
            return true;
        }
        else if (enemyTeamDefeated)
        {
            EndBattle(true); // 玩家胜利
            return true;
        }

        return false;
    }

    // 结束战斗
    private void EndBattle(bool playerVictory = false)
    {
        isBattleActive = false;

        if (battleUI != null)
        {
            battleUI.ShowBattleUI(false);
            battleUI.ShowBattleResult(playerVictory);
        }

        // 给予战斗奖励
        if (playerVictory)
        {
            // 计算经验值和金币奖励
            int totalExp = 0;
            int totalGold = 0;

            foreach (Character enemy in enemyTeam)
            {
                totalExp += Mathf.RoundToInt(50 * enemy.level);
                totalGold += Mathf.RoundToInt(20 * enemy.level);
            }

            RPGGameManager.Instance.AddExperience(totalExp);
            RPGGameManager.Instance.AddGold(totalGold);
        }

        // 重置战斗状态
        playerTeam.Clear();
        enemyTeam.Clear();
        battleQueue.Clear();
    }

    // 更新战斗UI
    private void UpdateBattleUI()
    {
        if (battleUI != null)
        {
            battleUI.UpdateCharacterStatus(playerTeam, enemyTeam);
            battleUI.UpdateTurnIndicator(currentActor, isPlayerTurn);
        }
    }

    void Update()
    {
        if (isBattleActive && battleType == TurnBased)
        {
            turnTimer -= Time.deltaTime;
            
            if (turnTimer <= 0 && isPlayerTurn)
            {
                // 玩家超时,自动执行防御行动
                BattleAction timeoutAction = new BattleAction
                {
                    actor = currentActor,
                    actionType = BattleActionType.Defend,
                    target = currentActor
                };
                
                PlayerSelectAction(timeoutAction);
            }
        }
    }
}

// 战斗类型
public enum BattleType
{
    TurnBased,
    RealTime
}

// 战斗行动类型
public enum BattleActionType
{
    Attack,
    Skill,
    Item,
    Defend,
    Flee
}

// 战斗行动类
public class BattleAction
{
    public Character actor;
    public BattleActionType actionType;
    public Character target;
    public Skill skill;
    public Item item;
    public string additionalData; // 额外数据,如逃跑成功率等
}

// 战斗UI管理器
public class RPGBattleUI : MonoBehaviour
{
    [Header("战斗UI元素")]
    public GameObject battlePanel;
    public GameObject actionSelectionPanel;
    public GameObject battleResultPanel;
    public Text battleResultText;
    public Slider[] playerHealthBars;
    public Slider[] enemyHealthBars;
    public Text[] playerNames;
    public Text[] enemyNames;
    public GameObject turnIndicator;
    public Text turnText;

    [Header("行动按钮")]
    public Button attackButton;
    public Button skillButton;
    public Button itemButton;
    public Button defendButton;

    private List<Character> playerTeam;
    private List<Character> enemyTeam;

    public void ShowBattleUI(bool show)
    {
        if (battlePanel != null)
        {
            battlePanel.SetActive(show);
        }
    }

    public void ShowActionSelection(Character actor)
    {
        if (actionSelectionPanel != null)
        {
            actionSelectionPanel.SetActive(true);
        }
    }

    public void HideActionSelection()
    {
        if (actionSelectionPanel != null)
        {
            actionSelectionPanel.SetActive(false);
        }
    }

    public void UpdateCharacterStatus(List<Character> players, List<Character> enemies)
    {
        playerTeam = players;
        enemyTeam = enemies;

        // 更新玩家状态条
        for (int i = 0; i < playerHealthBars.Length && i < players.Count; i++)
        {
            if (playerHealthBars[i] != null)
            {
                playerHealthBars[i].value = players[i].GetHealthPercentage();
            }

            if (playerNames[i] != null)
            {
                playerNames[i].text = $"{players[i].characterName}\nHP: {players[i].currentHealth}/{players[i].maxHealth}";
            }
        }

        // 更新敌人状态条
        for (int i = 0; i < enemyHealthBars.Length && i < enemies.Count; i++)
        {
            if (enemyHealthBars[i] != null)
            {
                enemyHealthBars[i].value = enemies[i].GetHealthPercentage();
            }

            if (enemyNames[i] != null)
            {
                enemyNames[i].text = $"{enemies[i].characterName}\nHP: {enemies[i].currentHealth}/{enemies[i].maxHealth}";
            }
        }
    }

    public void UpdateTurnIndicator(Character currentActor, bool isPlayerTurn)
    {
        if (turnIndicator != null)
        {
            turnIndicator.SetActive(true);
        }

        if (turnText != null)
        {
            turnText.text = isPlayerTurn ? 
                $"Player Turn: {currentActor.characterName}" : 
                $"Enemy Turn: {currentActor.characterName}";
        }
    }

    public void ShowDamage(Character target, int damage)
    {
        // 显示伤害数字
        StartCoroutine(ShowFloatingText(target, $"-{damage}", Color.red));
    }

    public void ShowHealEffect(Character target, int amount)
    {
        // 显示治疗效果
        StartCoroutine(ShowFloatingText(target, $"+{amount}", Color.green));
    }

    public void ShowCriticalHit(Character target)
    {
        // 显示暴击效果
        StartCoroutine(ShowFloatingText(target, "CRITICAL!", Color.yellow, 1.5f));
    }

    public void ShowSkillEffect(Skill skill, Character target, int damage)
    {
        // 显示技能效果
        StartCoroutine(ShowFloatingText(target, $"{skill.skillName}\n-{damage}", Color.blue));
    }

    public void ShowDefendEffect(Character character)
    {
        // 显示防御效果
        StartCoroutine(ShowFloatingText(character, "DEFENDING", Color.gray, 0.8f));
    }

    public void ShowBattleResult(bool playerVictory)
    {
        if (battleResultPanel != null)
        {
            battleResultPanel.SetActive(true);
        }

        if (battleResultText != null)
        {
            battleResultText.text = playerVictory ? "Victory!" : "Defeat!";
        }
    }

    private IEnumerator ShowFloatingText(Character target, string text, Color color, float scale = 1f)
    {
        // 这里需要创建浮动文字效果
        // 由于没有具体的UI元素,这里只是示例
        yield return new WaitForSeconds(1.5f);
    }

    // 按钮事件
    public void OnAttackButton()
    {
        if (RPGBattleSystem.Instance != null)
        {
            BattleAction action = new BattleAction
            {
                actor = RPGBattleSystem.Instance.currentActor,
                actionType = BattleActionType.Attack,
                target = SelectTarget() // 这里需要实现目标选择逻辑
            };
            
            RPGBattleSystem.Instance.PlayerSelectAction(action);
        }
    }

    public void OnSkillButton()
    {
        // 技能选择逻辑
    }

    public void OnItemButton()
    {
        // 物品选择逻辑
    }

    public void OnDefendButton()
    {
        if (RPGBattleSystem.Instance != null)
        {
            BattleAction action = new BattleAction
            {
                actor = RPGBattleSystem.Instance.currentActor,
                actionType = BattleActionType.Defend,
                target = RPGBattleSystem.Instance.currentActor
            };
            
            RPGBattleSystem.Instance.PlayerSelectAction(action);
        }
    }

    private Character SelectTarget()
    {
        // 简单的目标选择:选择第一个敌人
        if (RPGBattleSystem.Instance != null)
        {
            foreach (Character enemy in RPGBattleSystem.Instance.enemyTeam)
            {
                if (enemy.currentHealth > 0)
                {
                    return enemy;
                }
            }
        }
        return null;
    }
}

// 战斗系统单例
public class RPGBattleSystem
{
    public static RPGBattleSystem Instance { get; private set; }
    
    public Character currentActor;
    public List<Character> playerTeam = new List<Character>();
    public List<Character> enemyTeam = new List<Character>();
    
    static RPGBattleSystem()
    {
        Instance = new RPGBattleSystem();
    }
}

任务和对话系统

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

// RPG任务系统
public class RPGQuestSystem : MonoBehaviour
{
    [Header("任务数据")]
    public List<Quest> availableQuests = new List<Quest>();
    public List<Quest> activeQuests = new List<Quest>();
    public List<Quest> completedQuests = new List<Quest>();

    [Header("任务UI")]
    public RPGQuestUI questUI;
    public RPGDialogueSystem dialogueSystem;

    [Header("NPC引用")]
    public List<NPC> npcs = new List<NPC>();

    private PlayerCharacter player;

    public void Initialize()
    {
        player = RPGGameManager.Instance.player;
        
        // 初始化可用任务列表
        availableQuests = new List<Quest>(RPGGameManager.Instance.allQuests);
    }

    // 接受任务
    public bool AcceptQuest(string questName)
    {
        Quest quest = availableQuests.Find(q => q.questName == questName);
        if (quest != null && player.level >= quest.requiredLevel)
        {
            activeQuests.Add(quest);
            availableQuests.Remove(quest);
            
            // 通知UI更新
            if (questUI != null)
            {
                questUI.UpdateQuestList();
            }
            
            // 开始任务计时(如果有时间限制)
            if (quest.timeLimit > 0)
            {
                StartCoroutine(QuestTimeLimitCoroutine(quest));
            }
            
            return true;
        }
        
        return false;
    }

    // 完成任务
    public bool CompleteQuest(string questName)
    {
        Quest quest = activeQuests.Find(q => q.questName == questName);
        if (quest != null && IsQuestCompleted(quest))
        {
            activeQuests.Remove(quest);
            completedQuests.Add(quest);
            
            // 给予奖励
            GiveQuestRewards(quest);
            
            // 通知UI更新
            if (questUI != null)
            {
                questUI.UpdateQuestList();
            }
            
            return true;
        }
        
        return false;
    }

    // 检查任务是否完成
    public bool IsQuestCompleted(Quest quest)
    {
        foreach (QuestObjective objective in quest.objectives)
        {
            if (!objective.isCompleted)
            {
                return false;
            }
        }
        return true;
    }

    // 更新任务目标
    public void UpdateQuestObjective(string questName, string targetName, int amount = 1)
    {
        Quest quest = activeQuests.Find(q => q.questName == questName);
        if (quest != null)
        {
            QuestObjective objective = quest.objectives.Find(o => o.targetName == targetName);
            if (objective != null)
            {
                objective.currentCount = Mathf.Min(objective.targetCount, objective.currentCount + amount);
                objective.isCompleted = objective.currentCount >= objective.targetCount;
                
                // 通知UI更新
                if (questUI != null)
                {
                    questUI.UpdateActiveQuests();
                }
                
                // 检查是否完成任务
                if (IsQuestCompleted(quest))
                {
                    if (questUI != null)
                    {
                        questUI.ShowQuestComplete(quest);
                    }
                }
            }
        }
    }

    // 给予任务奖励
    private void GiveQuestRewards(Quest quest)
    {
        // 经验奖励
        RPGGameManager.Instance.AddExperience(quest.experienceReward);
        
        // 金币奖励
        RPGGameManager.Instance.AddGold(quest.goldReward);
        
        // 物品奖励
        foreach (ItemReward reward in quest.itemRewards)
        {
            if (Random.Range(0, 100) < reward.chance)
            {
                Item item = RPGGameManager.Instance.GetItem(reward.itemName);
                if (item != null)
                {
                    player.AddItem(item, reward.quantity);
                }
            }
        }
        
        // 播放奖励音效
        if (RPGAudioManager.Instance != null)
        {
            RPGAudioManager.Instance.PlaySFX("QuestComplete");
        }
    }

    // 任务时间限制协程
    private IEnumerator QuestTimeLimitCoroutine(Quest quest)
    {
        float timeLeft = quest.timeLimit;
        
        while (timeLeft > 0 && activeQuests.Contains(quest))
        {
            timeLeft -= Time.deltaTime;
            
            // 更新UI显示时间
            if (questUI != null)
            {
                questUI.UpdateQuestTime(quest, timeLeft);
            }
            
            yield return null;
        }
        
        // 时间到,任务失败
        if (activeQuests.Contains(quest))
        {
            FailQuest(quest.questName);
        }
    }

    // 任务失败
    private void FailQuest(string questName)
    {
        Quest quest = activeQuests.Find(q => q.questName == questName);
        if (quest != null)
        {
            activeQuests.Remove(quest);
            availableQuests.Add(quest); // 任务失败后可能可以重新接受
            
            // 通知UI
            if (questUI != null)
            {
                questUI.ShowQuestFailed(quest);
            }
        }
    }

    // 获取NPC的可用任务
    public List<Quest> GetAvailableQuestsForNPC(string npcName)
    {
        List<Quest> npcQuests = new List<Quest>();
        
        foreach (Quest quest in availableQuests)
        {
            if (quest.questGiver == npcName && player.level >= quest.requiredLevel)
            {
                npcQuests.Add(quest);
            }
        }
        
        return npcQuests;
    }

    // 获取NPC的进行中任务
    public List<Quest> GetActiveQuestsForNPC(string npcName)
    {
        List<Quest> npcQuests = new List<Quest>();
        
        foreach (Quest quest in activeQuests)
        {
            // 检查是否是交付任务的NPC
            // 这里简化处理,实际应该有更复杂的逻辑
            npcQuests.Add(quest);
        }
        
        return npcQuests;
    }
}

// NPC类
public class NPC : MonoBehaviour
{
    [Header("NPC信息")]
    public string npcName;
    public string npcType; // QuestGiver, Merchant, Trainer等
    public List<string> dialogueLines = new List<string>();
    public List<string> availableQuests = new List<string>();
    public List<string> shopItems = new List<string>();

    [Header("外观")]
    public Sprite portrait;
    public Color nameColor = Color.white;

    private RPGQuestSystem questSystem;
    private RPGDialogueSystem dialogueSystem;

    void Start()
    {
        questSystem = FindObjectOfType<RPGQuestSystem>();
        dialogueSystem = FindObjectOfType<RPGDialogueSystem>();
    }

    // 与NPC交互
    public void Interact()
    {
        if (questSystem != null)
        {
            // 检查是否有可接受的任务
            List<Quest> available = questSystem.GetAvailableQuestsForNPC(npcName);
            
            if (available.Count > 0)
            {
                // 显示任务对话
                if (RPGQuestUI.Instance != null)
                {
                    RPGQuestUI.Instance.ShowQuestOffer(available[0]);
                }
                return;
            }

            // 检查是否有可交付的任务
            List<Quest> active = questSystem.GetActiveQuestsForNPC(npcName);
            foreach (Quest quest in active)
            {
                if (questSystem.IsQuestCompleted(quest))
                {
                    // 显示完成任务对话
                    if (RPGQuestUI.Instance != null)
                    {
                        RPGQuestUI.Instance.ShowQuestCompletion(quest);
                    }
                    return;
                }
            }
        }

        // 如果没有任务相关的内容,显示对话
        if (dialogueSystem != null && dialogueLines.Count > 0)
        {
            dialogueSystem.StartDialogue(npcName, dialogueLines, portrait);
        }
    }
}

// RPG对话系统
public class RPGDialogueSystem : MonoBehaviour
{
    [Header("对话UI")]
    public GameObject dialoguePanel;
    public Text npcNameText;
    public Text dialogueText;
    public Image npcPortrait;
    public Button continueButton;
    public GameObject choicesPanel;
    public Transform choicesParent;

    private Queue<string> sentences;
    private List<string> currentDialogue;
    private int currentSentenceIndex = 0;
    private System.Action onDialogueEnd;

    void Start()
    {
        dialoguePanel.SetActive(false);
        sentences = new Queue<string>();
    }

    // 开始对话
    public void StartDialogue(string npcName, List<string> dialogue, Sprite portrait = null, System.Action callback = null)
    {
        onDialogueEnd = callback;
        
        if (npcNameText != null)
        {
            npcNameText.text = npcName;
        }
        
        if (npcPortrait != null && portrait != null)
        {
            npcPortrait.sprite = portrait;
        }
        
        currentDialogue = dialogue;
        currentSentenceIndex = 0;
        
        ShowNextSentence();
    }

    // 显示下一句话
    public void ShowNextSentence()
    {
        if (currentSentenceIndex < currentDialogue.Count)
        {
            string sentence = currentDialogue[currentSentenceIndex];
            currentSentenceIndex++;
            
            if (dialogueText != null)
            {
                dialogueText.text = sentence;
            }
            
            if (dialoguePanel != null)
            {
                dialoguePanel.SetActive(true);
            }
        }
        else
        {
            EndDialogue();
        }
    }

    // 结束对话
    private void EndDialogue()
    {
        if (dialoguePanel != null)
        {
            dialoguePanel.SetActive(false);
        }
        
        if (onDialogueEnd != null)
        {
            onDialogueEnd();
        }
    }

    // 显示对话选择
    public void ShowChoices(List<DialogueChoice> choices)
    {
        if (choicesPanel != null)
        {
            choicesPanel.SetActive(true);
        }
        
        // 清除旧的选择按钮
        foreach (Transform child in choicesParent)
        {
            Destroy(child.gameObject);
        }
        
        // 创建新的选择按钮
        foreach (DialogueChoice choice in choices)
        {
            GameObject choiceButtonGO = new GameObject("ChoiceButton");
            choiceButtonGO.transform.SetParent(choicesParent);
            
            Button choiceButton = choiceButtonGO.AddComponent<Button>();
            Text choiceText = choiceButtonGO.AddComponent<Text>();
            choiceText.text = choice.text;
            
            choiceButton.onClick.AddListener(() => {
                choice.onSelected();
                HideChoices();
            });
        }
    }

    // 隐藏选择
    private void HideChoices()
    {
        if (choicesPanel != null)
        {
            choicesPanel.SetActive(false);
        }
    }

    // 按钮事件
    public void OnContinueButton()
    {
        ShowNextSentence();
    }
}

// 对话选择
[System.Serializable]
public class DialogueChoice
{
    public string text;
    public System.Action onSelected;
}

// RPG任务UI
public class RPGQuestUI : MonoBehaviour
{
    public static RPGQuestUI Instance { get; private set; }

    [Header("任务面板")]
    public GameObject questPanel;
    public GameObject questLogPanel;
    public GameObject questOfferPanel;
    public GameObject questCompletePanel;

    [Header("任务列表")]
    public Transform availableQuestsParent;
    public Transform activeQuestsParent;
    public Transform completedQuestsParent;

    [Header("任务详情")]
    public Text questTitleText;
    public Text questDescriptionText;
    public Text questObjectivesText;
    public Text questRewardsText;

    [Header("任务按钮")]
    public Button acceptButton;
    public Button completeButton;
    public Button cancelButton;

    private RPGQuestSystem questSystem;

    void Awake()
    {
        Instance = this;
    }

    void Start()
    {
        questSystem = FindObjectOfType<RPGQuestSystem>();
        questPanel.SetActive(false);
    }

    // 更新任务列表
    public void UpdateQuestList()
    {
        ClearQuestList(availableQuestsParent);
        ClearQuestList(activeQuestsParent);
        ClearQuestList(completedQuestsParent);

        // 添加可用任务
        foreach (Quest quest in questSystem.availableQuests)
        {
            CreateQuestButton(quest, availableQuestsParent, OnQuestClick);
        }

        // 添加进行中任务
        foreach (Quest quest in questSystem.activeQuests)
        {
            CreateQuestButton(quest, activeQuestsParent, OnActiveQuestClick);
        }

        // 添加已完成任务
        foreach (Quest quest in questSystem.completedQuests)
        {
            CreateQuestButton(quest, completedQuestsParent, OnCompletedQuestClick);
        }
    }

    // 更新进行中的任务
    public void UpdateActiveQuests()
    {
        ClearQuestList(activeQuestsParent);

        foreach (Quest quest in questSystem.activeQuests)
        {
            CreateQuestButton(quest, activeQuestsParent, OnActiveQuestClick);
        }
    }

    // 创建任务按钮
    private void CreateQuestButton(Quest quest, Transform parent, System.Action<Quest> onClick)
    {
        GameObject buttonGO = new GameObject(quest.questName);
        buttonGO.transform.SetParent(parent);

        Button button = buttonGO.AddComponent<Button>();
        Text text = buttonGO.AddComponent<Text>();
        text.text = quest.questName;

        button.onClick.AddListener(() => onClick(quest));
    }

    // 清空任务列表
    private void ClearQuestList(Transform parent)
    {
        foreach (Transform child in parent)
        {
            Destroy(child.gameObject);
        }
    }

    // 任务点击事件
    private void OnQuestClick(Quest quest)
    {
        ShowQuestDetails(quest);
        if (acceptButton != null)
        {
            acceptButton.gameObject.SetActive(true);
            acceptButton.onClick.RemoveAllListeners();
            acceptButton.onClick.AddListener(() => OnAcceptQuest(quest));
        }
    }

    // 进行中任务点击事件
    private void OnActiveQuestClick(Quest quest)
    {
        ShowQuestDetails(quest);
        if (completeButton != null)
        {
            completeButton.gameObject.SetActive(questSystem.IsQuestCompleted(quest));
            completeButton.onClick.RemoveAllListeners();
            completeButton.onClick.AddListener(() => OnCompleteQuest(quest));
        }
    }

    // 已完成任务点击事件
    private void OnCompletedQuestClick(Quest quest)
    {
        ShowQuestDetails(quest);
    }

    // 显示任务详情
    private void ShowQuestDetails(Quest quest)
    {
        if (questTitleText != null)
        {
            questTitleText.text = quest.questName;
        }

        if (questDescriptionText != null)
        {
            questDescriptionText.text = quest.description;
        }

        if (questObjectivesText != null)
        {
            string objectives = "Objectives:\n";
            foreach (QuestObjective objective in quest.objectives)
            {
                objectives += $"• {objective.description}: {objective.currentCount}/{objective.targetCount}\n";
            }
            questObjectivesText.text = objectives;
        }

        if (questRewardsText != null)
        {
            string rewards = $"Rewards:\n+{quest.experienceReward} EXP\n+{quest.goldReward} Gold";
            foreach (ItemReward reward in quest.itemRewards)
            {
                rewards += $"\n+{reward.quantity} {reward.itemName}";
            }
            questRewardsText.text = rewards;
        }
    }

    // 接受任务
    private void OnAcceptQuest(Quest quest)
    {
        if (questSystem.AcceptQuest(quest.questName))
        {
            UpdateQuestList();
            if (questOfferPanel != null)
            {
                questOfferPanel.SetActive(false);
            }
        }
    }

    // 完成任务
    private void OnCompleteQuest(Quest quest)
    {
        if (questSystem.CompleteQuest(quest.questName))
        {
            UpdateQuestList();
            if (questCompletePanel != null)
            {
                questCompletePanel.SetActive(false);
            }
        }
    }

    // 显示/隐藏任务面板
    public void ToggleQuestPanel()
    {
        if (questPanel != null)
        {
            bool isActive = !questPanel.activeSelf;
            questPanel.SetActive(isActive);
            
            if (isActive)
            {
                UpdateQuestList();
            }
        }
    }

    // 显示任务提供
    public void ShowQuestOffer(Quest quest)
    {
        if (questOfferPanel != null)
        {
            questOfferPanel.SetActive(true);
            ShowQuestDetails(quest);
            
            if (acceptButton != null)
            {
                acceptButton.gameObject.SetActive(true);
                acceptButton.onClick.RemoveAllListeners();
                acceptButton.onClick.AddListener(() => OnAcceptQuest(quest));
            }
            
            if (cancelButton != null)
            {
                cancelButton.onClick.RemoveAllListeners();
                cancelButton.onClick.AddListener(() => questOfferPanel.SetActive(false));
            }
        }
    }

    // 显示任务完成
    public void ShowQuestCompletion(Quest quest)
    {
        if (questCompletePanel != null)
        {
            questCompletePanel.SetActive(true);
            ShowQuestDetails(quest);
            
            if (completeButton != null)
            {
                completeButton.gameObject.SetActive(true);
                completeButton.onClick.RemoveAllListeners();
                completeButton.onClick.AddListener(() => OnCompleteQuest(quest));
            }
            
            if (cancelButton != null)
            {
                cancelButton.onClick.RemoveAllListeners();
                cancelButton.onClick.AddListener(() => questCompletePanel.SetActive(false));
            }
        }
    }

    // 显示任务完成结果
    public void ShowQuestComplete(Quest quest)
    {
        // 这里可以显示任务完成的特殊UI或效果
        Debug.Log($"Quest completed: {quest.questName}");
    }

    // 显示任务失败
    public void ShowQuestFailed(Quest quest)
    {
        // 这里可以显示任务失败的UI或效果
        Debug.Log($"Quest failed: {quest.questName}");
    }

    // 更新任务时间
    public void UpdateQuestTime(Quest quest, float timeLeft)
    {
        // 这里可以更新UI显示剩余时间
    }
}

背包和商店系统

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

// RPG背包系统
public class RPGInventorySystem : MonoBehaviour
{
    [Header("背包设置")]
    public int inventorySize = 30;
    public int equipmentSlots = 10;

    [Header("UI引用")]
    public RPGInventoryUI inventoryUI;
    public RPGShopUI shopUI;

    private PlayerCharacter player;
    private List<Item> inventory = new List<Item>();
    private Dictionary<EquipmentSlot, Item> equipment = new Dictionary<EquipmentSlot, Item>();

    public void Initialize()
    {
        player = RPGGameManager.Instance.player;
        
        // 初始化装备槽
        foreach (EquipmentSlot slot in System.Enum.GetValues(typeof(EquipmentSlot)))
        {
            if (slot != EquipmentSlot.None)
            {
                equipment[slot] = null;
            }
        }
    }

    // 添加物品到背包
    public bool AddItem(Item item, int quantity = 1)
    {
        if (player == null) return false;

        // 检查背包是否已满
        if (inventory.Count >= inventorySize)
        {
            // 检查是否可以堆叠
            Item existingItem = FindItem(item.itemName);
            if (existingItem != null && existingItem.stackLimit > 1 && 
                existingItem.quantity < existingItem.stackLimit)
            {
                int newQuantity = Mathf.Min(existingItem.quantity + quantity, existingItem.stackLimit);
                existingItem.quantity = newQuantity;
                
                if (inventoryUI != null)
                {
                    inventoryUI.UpdateItemQuantity(existingItem);
                }
                
                return true;
            }
            else
            {
                return false; // 背包已满且无法堆叠
            }
        }

        // 检查是否可以与现有物品堆叠
        Item stackableItem = FindItem(item.itemName);
        if (stackableItem != null && stackableItem.stackLimit > 1)
        {
            int spaceAvailable = stackableItem.stackLimit - stackableItem.quantity;
            int toAdd = Mathf.Min(quantity, spaceAvailable);
            
            stackableItem.quantity += toAdd;
            quantity -= toAdd;
            
            if (inventoryUI != null)
            {
                inventoryUI.UpdateItemQuantity(stackableItem);
            }
        }

        // 添加剩余物品
        if (quantity > 0)
        {
            Item newItem = CreateItemCopy(item);
            newItem.quantity = quantity;
            inventory.Add(newItem);
            
            if (inventoryUI != null)
            {
                inventoryUI.AddItemToUI(newItem);
            }
        }

        return true;
    }

    // 移除物品
    public bool RemoveItem(string itemName, int quantity = 1)
    {
        Item item = FindItem(itemName);
        if (item != null)
        {
            if (item.quantity > quantity)
            {
                item.quantity -= quantity;
                
                if (inventoryUI != null)
                {
                    inventoryUI.UpdateItemQuantity(item);
                }
            }
            else
            {
                inventory.Remove(item);
                
                if (inventoryUI != null)
                {
                    inventoryUI.RemoveItemFromUI(item);
                }
            }
            
            return true;
        }
        
        return false;
    }

    // 使用物品
    public bool UseItem(string itemName)
    {
        Item item = FindItem(itemName);
        if (item != null && item.isConsumable)
        {
            // 应用物品效果
            ApplyItemEffect(item);
            
            // 减少数量或移除
            if (item.quantity > 1)
            {
                item.quantity--;
                
                if (inventoryUI != null)
                {
                    inventoryUI.UpdateItemQuantity(item);
                }
            }
            else
            {
                inventory.Remove(item);
                
                if (inventoryUI != null)
                {
                    inventoryUI.RemoveItemFromUI(item);
                }
            }
            
            return true;
        }
        
        return false;
    }

    // 装备物品
    public bool EquipItem(string itemName)
    {
        Item item = FindItem(itemName);
        if (item != null)
        {
            EquipmentSlot slot = GetEquipmentSlot(item);
            if (slot != EquipmentSlot.None)
            {
                // 如果该槽位已有装备,先卸下
                if (equipment[slot] != null)
                {
                    UnequipItem(slot);
                }

                // 从背包中移除物品
                inventory.Remove(item);

                // 装备物品
                equipment[slot] = item;

                // 应用属性加成
                ApplyEquipmentStats(item, true);

                if (inventoryUI != null)
                {
                    inventoryUI.UpdateEquipment(slot, item);
                    inventoryUI.RemoveItemFromUI(item);
                }

                return true;
            }
        }
        
        return false;
    }

    // 卸下装备
    public bool UnequipItem(EquipmentSlot slot)
    {
        if (equipment.ContainsKey(slot) && equipment[slot] != null)
        {
            Item item = equipment[slot];
            
            // 移除属性加成
            ApplyEquipmentStats(item, false);

            // 将物品放回背包
            if (!AddItem(item, 1))
            {
                // 如果背包满了,丢弃物品(或者有其他处理方式)
                Debug.LogWarning("Cannot unequip item: inventory full");
                return false;
            }

            // 清空装备槽
            equipment[slot] = null;

            if (inventoryUI != null)
            {
                inventoryUI.UpdateEquipment(slot, null);
            }

            return true;
        }
        
        return false;
    }

    // 购买物品
    public bool BuyItem(Item item, int quantity = 1)
    {
        int totalCost = item.buyPrice * quantity;
        
        if (player.gold >= totalCost)
        {
            player.gold -= totalCost;
            
            if (AddItem(item, quantity))
            {
                if (inventoryUI != null)
                {
                    inventoryUI.UpdateGoldDisplay(player.gold);
                }
                return true;
            }
            else
            {
                // 如果添加失败,退还金币
                player.gold += totalCost;
                return false;
            }
        }
        
        return false;
    }

    // 出售物品
    public bool SellItem(string itemName, int quantity = 1)
    {
        Item item = FindItem(itemName);
        if (item != null && item.quantity >= quantity)
        {
            int sellPrice = Mathf.RoundToInt(item.sellPrice * quantity * player.GetTotalLuck() / 100f);
            player.gold += sellPrice;

            if (item.quantity > quantity)
            {
                item.quantity -= quantity;
                
                if (inventoryUI != null)
                {
                    inventoryUI.UpdateItemQuantity(item);
                }
            }
            else
            {
                inventory.Remove(item);
                
                if (inventoryUI != null)
                {
                    inventoryUI.RemoveItemFromUI(item);
                }
            }

            if (inventoryUI != null)
            {
                inventoryUI.UpdateGoldDisplay(player.gold);
            }

            return true;
        }
        
        return false;
    }

    // 查找物品
    private Item FindItem(string itemName)
    {
        return inventory.Find(item => item.itemName == itemName);
    }

    // 获取装备槽
    private EquipmentSlot GetEquipmentSlot(Item item)
    {
        switch (item.itemType)
        {
            case ItemType.Weapon:
                return EquipmentSlot.Weapon;
            case ItemType.Armor:
                if (item.itemName.Contains("Helmet") || item.itemName.Contains("Head"))
                    return EquipmentSlot.Head;
                else if (item.itemName.Contains("Chest") || item.itemName.Contains("Armor"))
                    return EquipmentSlot.Chest;
                else if (item.itemName.Contains("Legs") || item.itemName.Contains("Pants"))
                    return EquipmentSlot.Legs;
                else if (item.itemName.Contains("Boots") || item.itemName.Contains("Shoes"))
                    return EquipmentSlot.Feet;
                else if (item.itemName.Contains("Gloves"))
                    return EquipmentSlot.Hands;
                break;
            case ItemType.Accessory:
                // 这里可以实现多个饰品槽
                if (equipment[EquipmentSlot.Accessory1] == null)
                    return EquipmentSlot.Accessory1;
                else if (equipment[EquipmentSlot.Accessory2] == null)
                    return EquipmentSlot.Accessory2;
                break;
        }

        return EquipmentSlot.None;
    }

    // 应用物品效果
    private void ApplyItemEffect(Item item)
    {
        if (player != null)
        {
            if (item.healthRestore > 0)
            {
                player.Heal(item.healthRestore);
            }

            if (item.manaRestore > 0)
            {
                player.RestoreMana(item.manaRestore);
            }

            if (item.restorePercentage > 0)
            {
                int healthRestore = Mathf.RoundToInt(player.maxHealth * item.restorePercentage / 100f);
                int manaRestore = Mathf.RoundToInt(player.maxMana * item.restorePercentage / 100f);
                player.Heal(healthRestore);
                player.RestoreMana(manaRestore);
            }

            // 其他效果,如临时属性提升等
            if (item.duration > 0 && !string.IsNullOrEmpty(item.effectType))
            {
                ApplyTemporaryEffect(item);
            }
        }
    }

    // 应用临时效果
    private void ApplyTemporaryEffect(Item item)
    {
        // 这里可以实现临时属性提升效果
        // 例如:增加攻击力、防御力等,持续item.duration秒
        StartCoroutine(ApplyTemporaryEffectCoroutine(item));
    }

    // 临时效果协程
    private System.Collections.IEnumerator ApplyTemporaryEffectCoroutine(Item item)
    {
        // 应用效果
        switch (item.effectType)
        {
            case "StrengthBoost":
                player.strength += item.effectValue;
                break;
            case "DefenseBoost":
                player.armor += item.effectValue;
                break;
            case "SpeedBoost":
                player.movementSpeed += item.effectValue;
                break;
        }

        // 等待持续时间
        yield return new UnityEngine.WaitForSeconds(item.duration);

        // 移除效果
        switch (item.effectType)
        {
            case "StrengthBoost":
                player.strength -= item.effectValue;
                break;
            case "DefenseBoost":
                player.armor -= item.effectValue;
                break;
            case "SpeedBoost":
                player.movementSpeed -= item.effectValue;
                break;
        }
    }

    // 应用装备属性
    private void ApplyEquipmentStats(Item item, bool isEquipping)
    {
        if (player == null) return;

        int multiplier = isEquipping ? 1 : -1;

        player.strength += item.strength * multiplier;
        player.dexterity += item.dexterity * multiplier;
        player.intelligence += item.intelligence * multiplier;
        player.constitution += item.constitution * multiplier;
        player.luck += item.luck * multiplier;

        player.maxHealth += item.healthBonus * multiplier;
        player.armor += item.armorBonus * multiplier;
        player.attackPower += item.damageBonus * multiplier;
        player.magicPower += item.magicPower * multiplier;
        player.criticalChance += item.criticalChance * multiplier;
        player.attackSpeed += item.attackSpeed * multiplier;
        player.movementSpeed += item.movementSpeed * multiplier;

        // 如果是武器,可能需要更新玩家的攻击动画或攻击方式
    }

    // 创建物品副本
    private Item CreateItemCopy(Item original)
    {
        Item copy = new Item();
        System.Reflection.FieldInfo[] fields = typeof(Item).GetFields();
        foreach (System.Reflection.FieldInfo field in fields)
        {
            field.SetValue(copy, field.GetValue(original));
        }
        return copy;
    }

    // 获取背包中物品数量
    public int GetItemCount(string itemName)
    {
        Item item = FindItem(itemName);
        return item != null ? item.quantity : 0;
    }

    // 获取背包占用空间
    public int GetInventoryUsage()
    {
        return inventory.Count;
    }

    // 获取背包剩余空间
    public int GetRemainingInventorySpace()
    {
        return inventorySize - inventory.Count;
    }

    // 获取所有物品
    public List<Item> GetAllItems()
    {
        return new List<Item>(inventory);
    }

    // 获取装备
    public Dictionary<EquipmentSlot, Item> GetEquipment()
    {
        return new Dictionary<EquipmentSlot, Item>(equipment);
    }
}

// RPG背包UI
public class RPGInventoryUI : MonoBehaviour
{
    [Header("背包面板")]
    public GameObject inventoryPanel;
    public Transform inventoryGrid;
    public Transform equipmentGrid;

    [Header("物品按钮预制件")]
    public GameObject itemButtonPrefab;
    public GameObject equipmentSlotPrefab;

    [Header("信息面板")]
    public Text goldText;
    public Text inventoryInfoText;
    public Image itemIcon;
    public Text itemNameText;
    public Text itemDescriptionText;
    public Text itemStatsText;

    private Dictionary<Item, GameObject> itemButtons = new Dictionary<Item, GameObject>();
    private Dictionary<EquipmentSlot, GameObject> equipmentSlots = new Dictionary<EquipmentSlot, GameObject>();
    private Item selectedItem;

    void Start()
    {
        inventoryPanel.SetActive(false);
        InitializeEquipmentSlots();
    }

    // 初始化装备槽
    private void InitializeEquipmentSlots()
    {
        foreach (EquipmentSlot slot in System.Enum.GetValues(typeof(EquipmentSlot)))
        {
            if (slot != EquipmentSlot.None)
            {
                GameObject slotGO = Instantiate(equipmentSlotPrefab, equipmentGrid);
                slotGO.name = slot.ToString();
                
                // 添加点击事件
                Button slotButton = slotGO.GetComponent<Button>();
                EquipmentSlot capturedSlot = slot; // 避免闭包问题
                slotButton.onClick.AddListener(() => OnEquipmentSlotClick(capturedSlot));
                
                equipmentSlots[slot] = slotGO;
            }
        }
    }

    // 添加物品到UI
    public void AddItemToUI(Item item)
    {
        if (itemButtonPrefab != null && inventoryGrid != null)
        {
            GameObject itemGO = Instantiate(itemButtonPrefab, inventoryGrid);
            itemGO.name = item.itemName;

            // 设置物品信息
            SetItemButtonInfo(itemGO, item);

            // 添加点击事件
            Button button = itemGO.GetComponent<Button>();
            button.onClick.AddListener(() => OnItemClick(item));

            itemButtons[item] = itemGO;
        }
    }

    // 更新物品数量显示
    public void UpdateItemQuantity(Item item)
    {
        if (itemButtons.ContainsKey(item))
        {
            GameObject itemGO = itemButtons[item];
            Text quantityText = itemGO.GetComponentInChildren<Text>();
            if (quantityText != null)
            {
                quantityText.text = item.quantity > 1 ? item.quantity.ToString() : "";
            }
        }
    }

    // 从UI移除物品
    public void RemoveItemFromUI(Item item)
    {
        if (itemButtons.ContainsKey(item))
        {
            GameObject itemGO = itemButtons[item];
            Destroy(itemGO);
            itemButtons.Remove(item);
        }
    }

    // 更新装备显示
    public void UpdateEquipment(EquipmentSlot slot, Item item)
    {
        if (equipmentSlots.ContainsKey(slot))
        {
            GameObject slotGO = equipmentSlots[slot];
            
            // 设置装备图标
            if (item != null && item.icon != null)
            {
                Image iconImage = slotGO.GetComponent<Image>();
                if (iconImage != null)
                {
                    iconImage.sprite = item.icon;
                }
            }
            else
            {
                Image iconImage = slotGO.GetComponent<Image>();
                if (iconImage != null)
                {
                    iconImage.sprite = null; // 或设置为空装备图标
                }
            }
        }
    }

    // 设置物品按钮信息
    private void SetItemButtonInfo(GameObject buttonGO, Item item)
    {
        Image iconImage = buttonGO.GetComponent<Image>();
        if (iconImage != null && item.icon != null)
        {
            iconImage.sprite = item.icon;
        }

        Text quantityText = buttonGO.GetComponentInChildren<Text>();
        if (quantityText != null)
        {
            quantityText.text = item.quantity > 1 ? item.quantity.ToString() : "";
        }
    }

    // 更新金币显示
    public void UpdateGoldDisplay(int gold)
    {
        if (goldText != null)
        {
            goldText.text = $"Gold: {gold}";
        }
    }

    // 更新背包信息
    public void UpdateInventoryInfo(int usedSpace, int totalSpace)
    {
        if (inventoryInfoText != null)
        {
            inventoryInfoText.text = $"Inventory: {usedSpace}/{totalSpace}";
        }
    }

    // 显示/隐藏背包面板
    public void ToggleInventoryPanel()
    {
        if (inventoryPanel != null)
        {
            bool isActive = !inventoryPanel.activeSelf;
            inventoryPanel.SetActive(isActive);
            
            if (isActive)
            {
                RefreshInventoryDisplay();
            }
        }
    }

    // 刷新背包显示
    public void RefreshInventoryDisplay()
    {
        // 清除现有的物品按钮
        foreach (GameObject itemGO in itemButtons.Values)
        {
            Destroy(itemGO);
        }
        itemButtons.Clear();

        // 重新添加所有物品
        RPGInventorySystem inventorySystem = FindObjectOfType<RPGInventorySystem>();
        if (inventorySystem != null)
        {
            List<Item> allItems = inventorySystem.GetAllItems();
            foreach (Item item in allItems)
            {
                AddItemToUI(item);
            }

            // 更新金币和背包信息
            UpdateGoldDisplay(RPGGameManager.Instance.player.gold);
            UpdateInventoryInfo(inventorySystem.GetInventoryUsage(), inventorySystem.inventorySize);
        }
    }

    // 物品点击事件
    private void OnItemClick(Item item)
    {
        selectedItem = item;

        // 显示物品详细信息
        if (itemIcon != null && item.icon != null)
        {
            itemIcon.sprite = item.icon;
        }

        if (itemNameText != null)
        {
            itemNameText.text = item.itemName;
        }

        if (itemDescriptionText != null)
        {
            itemDescriptionText.text = item.description;
        }

        if (itemStatsText != null)
        {
            string stats = "";
            if (item.strength > 0) stats += $"\n+{item.strength} Strength";
            if (item.dexterity > 0) stats += $"\n+{item.dexterity} Dexterity";
            if (item.intelligence > 0) stats += $"\n+{item.intelligence} Intelligence";
            if (item.healthBonus > 0) stats += $"\n+{item.healthBonus} Max HP";
            if (item.armorBonus > 0) stats += $"\n+{item.armorBonus} Armor";
            if (item.damageBonus > 0) stats += $"\n+{item.damageBonus} Attack";
            if (item.healthRestore > 0) stats += $"\nRestores {item.healthRestore} HP";

            itemStatsText.text = stats;
        }
    }

    // 装备槽点击事件
    private void OnEquipmentSlotClick(EquipmentSlot slot)
    {
        if (selectedItem != null)
        {
            // 尝试装备选中的物品
            RPGInventorySystem inventorySystem = FindObjectOfType<RPGInventorySystem>();
            if (inventorySystem != null)
            {
                inventorySystem.EquipItem(selectedItem.itemName);
            }
        }
    }
}

// RPG商店UI
public class RPGShopUI : MonoBehaviour
{
    [Header("商店面板")]
    public GameObject shopPanel;
    public Transform shopItemsGrid;
    public Transform playerInventoryGrid;

    [Header("商店信息")]
    public Text shopNameText;
    public Text playerGoldText;

    [Header("物品按钮预制件")]
    public GameObject shopItemButtonPrefab;
    public GameObject inventoryItemButtonPrefab;

    private List<Item> shopInventory = new List<Item>();
    private NPC currentNPC;

    // 设置商店
    public void SetShop(NPC npc)
    {
        currentNPC = npc;
        shopInventory.Clear();

        if (shopNameText != null)
        {
            shopNameText.text = $"{npc.npcName}'s Shop";
        }

        // 添加NPC的商店物品
        foreach (string itemName in npc.shopItems)
        {
            Item item = RPGGameManager.Instance.GetItem(itemName);
            if (item != null)
            {
                shopInventory.Add(item);
            }
        }

        DisplayShopItems();
    }

    // 显示商店物品
    private void DisplayShopItems()
    {
        // 清除现有物品
        foreach (Transform child in shopItemsGrid)
        {
            Destroy(child.gameObject);
        }

        // 添加商店物品
        foreach (Item item in shopInventory)
        {
            if (shopItemButtonPrefab != null)
            {
                GameObject itemGO = Instantiate(shopItemButtonPrefab, shopItemsGrid);
                SetupShopItemButton(itemGO, item);
            }
        }

        // 显示玩家背包物品
        DisplayPlayerInventory();
    }

    // 设置商店物品按钮
    private void SetupShopItemButton(GameObject buttonGO, Item item)
    {
        // 设置图标
        Image iconImage = buttonGO.GetComponent<Image>();
        if (iconImage != null && item.icon != null)
        {
            iconImage.sprite = item.icon;
        }

        // 设置文本(物品名和价格)
        Text[] texts = buttonGO.GetComponentsInChildren<Text>();
        if (texts.Length >= 2)
        {
            texts[0].text = item.itemName;
            texts[1].text = $"${item.buyPrice}";
        }

        // 设置点击事件
        Button button = buttonGO.GetComponent<Button>();
        button.onClick.AddListener(() => OnShopItemBuy(item));
    }

    // 显示玩家背包物品
    private void DisplayPlayerInventory()
    {
        // 清除现有物品
        foreach (Transform child in playerInventoryGrid)
        {
            Destroy(child.gameObject);
        }

        // 获取玩家背包物品
        RPGInventorySystem inventorySystem = FindObjectOfType<RPGInventorySystem>();
        if (inventorySystem != null)
        {
            List<Item> playerItems = inventorySystem.GetAllItems();
            
            foreach (Item item in playerItems)
            {
                if (inventoryItemButtonPrefab != null)
                {
                    GameObject itemGO = Instantiate(inventoryItemButtonPrefab, playerInventoryGrid);
                    SetupInventoryItemButton(itemGO, item);
                }
            }
        }
    }

    // 设置背包物品按钮
    private void SetupInventoryItemButton(GameObject buttonGO, Item item)
    {
        // 设置图标
        Image iconImage = buttonGO.GetComponent<Image>();
        if (iconImage != null && item.icon != null)
        {
            iconImage.sprite = item.icon;
        }

        // 设置文本(物品名和售价)
        Text[] texts = buttonGO.GetComponentsInChildren<Text>();
        if (texts.Length >= 2)
        {
            texts[0].text = item.itemName;
            texts[1].text = $"Sell: ${item.sellPrice}";
        }

        // 设置点击事件
        Button button = buttonGO.GetComponent<Button>();
        button.onClick.AddListener(() => OnInventoryItemSell(item));
    }

    // 购买物品
    private void OnShopItemBuy(Item item)
    {
        RPGInventorySystem inventorySystem = FindObjectOfType<RPGInventorySystem>();
        if (inventorySystem != null)
        {
            if (inventorySystem.BuyItem(item))
            {
                // 购买成功,刷新显示
                DisplayShopItems();
                
                // 播放音效
                if (RPGAudioManager.Instance != null)
                {
                    RPGAudioManager.Instance.PlaySFX("ItemBuy");
                }
            }
            else
            {
                // 购买失败(金币不足或背包满)
                Debug.LogWarning("Cannot buy item: not enough gold or inventory full");
            }
        }
    }

    // 出售物品
    private void OnInventoryItemSell(Item item)
    {
        RPGInventorySystem inventorySystem = FindObjectOfType<RPGInventorySystem>();
        if (inventorySystem != null)
        {
            if (inventorySystem.SellItem(item.itemName))
            {
                // 出售成功,刷新显示
                DisplayShopItems();
                
                // 播放音效
                if (RPGAudioManager.Instance != null)
                {
                    RPGAudioManager.Instance.PlaySFX("ItemSell");
                }
            }
            else
            {
                // 出售失败
                Debug.LogWarning("Cannot sell item");
            }
        }
    }

    // 更新玩家金币显示
    private void UpdatePlayerGold()
    {
        if (playerGoldText != null)
        {
            playerGoldText.text = $"Gold: {RPGGameManager.Instance.player.gold}";
        }
    }

    // 显示/隐藏商店面板
    public void ToggleShopPanel()
    {
        if (shopPanel != null)
        {
            bool isActive = !shopPanel.activeSelf;
            shopPanel.SetActive(isActive);
            
            if (isActive && currentNPC != null)
            {
                SetShop(currentNPC);
                UpdatePlayerGold();
            }
        }
    }
}

游戏发布流程

构建设置

using UnityEngine;
using UnityEditor;
using System.Collections;

// 游戏发布设置
public class GameBuildSettings : MonoBehaviour
{
    [Header("构建设置")]
    public string gameTitle = "My Game";
    public string companyName = "My Company";
    public string productVersion = "1.0.0";
    public string bundleIdentifier = "com.mycompany.mygame";

    [Header("游戏配置")]
    public int targetFrameRate = 60;
    public bool enableVSync = false;
    public Resolution defaultResolution = new Resolution { width = 1920, height = 1080, refreshRate = 60 };
    public bool fullscreenMode = true;

    [Header("优化设置")]
    public bool enableDynamicBatching = true;
    public bool enableStaticBatching = true;
    public bool enableOcclusionCulling = true;
    public bool enableLODs = true;

    [Header("音频设置")]
    public bool enableAudioDucking = true;
    public float masterVolume = 1f;

    [Header("控制设置")]
    public bool enableMouseCursor = true;
    public bool enableTouchInput = true;
    public bool enableGamepadInput = true;

    // 应用构建设置
    [ContextMenu("应用构建设置")]
    public void ApplyBuildSettings()
    {
        #if UNITY_EDITOR
        // 应用基本设置
        PlayerSettings.productName = gameTitle;
        PlayerSettings.companyName = companyName;
        PlayerSettings.bundleVersion = productVersion;
        
        #if UNITY_STANDALONE
        PlayerSettings.applicationIdentifier = bundleIdentifier;
        #elif UNITY_ANDROID
        PlayerSettings.applicationIdentifier = bundleIdentifier;
        #elif UNITY_IOS
        PlayerSettings.applicationIdentifier = bundleIdentifier;
        #endif

        // 应用性能设置
        Application.targetFrameRate = targetFrameRate;
        QualitySettings.vSyncCount = enableVSync ? 1 : 0;

        // 应用图形设置
        QualitySettings.names = new string[] { "Very Low", "Low", "Medium", "High", "Very High", "Ultra" };
        
        // 应用批处理设置
        PlayerSettings.batching = enableDynamicBatching ? 
            PlayerSettings.batching | BatchMode.CombineMeshesStatic : 
            PlayerSettings.batching & ~BatchMode.CombineMeshesStatic;
            
        PlayerSettings.batching = enableStaticBatching ? 
            PlayerSettings.batching | BatchMode.CombineMeshesDynamic : 
            PlayerSettings.batching & ~BatchMode.CombineMeshesDynamic;

        // 应用其他设置
        PlayerSettings.runInBackground = true;
        PlayerSettings.captureSingleScreen = false;
        PlayerSettings.resizableWindow = !fullscreenMode;
        PlayerSettings.fullScreenMode = fullscreenMode ? 
            FullScreenMode.FullScreenWindow : FullScreenMode.Windowed;

        Debug.Log("构建设置已应用");
        #endif
    }

    // 分辨率设置
    [System.Serializable]
    public class Resolution
    {
        public int width = 1920;
        public int height = 1080;
        public int refreshRate = 60;
    }

    // 获取推荐的分辨率
    public static Resolution[] GetRecommendedResolutions()
    {
        return new Resolution[]
        {
            new Resolution { width = 1920, height = 1080, refreshRate = 60 }, // 1080p
            new Resolution { width = 1280, height = 720, refreshRate = 60 },  // 720p
            new Resolution { width = 2560, height = 1440, refreshRate = 60 }, // 1440p
            new Resolution { width = 3840, height = 2160, refreshRate = 60 }  // 4K
        };
    }

    // 检查系统兼容性
    public static SystemCompatibilityInfo GetSystemCompatibility()
    {
        SystemCompatibilityInfo info = new SystemCompatibilityInfo();
        
        info.os = SystemInfo.operatingSystem;
        info.gpu = SystemInfo.graphicsDeviceName;
        info.gpuType = SystemInfo.graphicsDeviceType.ToString();
        info.ram = SystemInfo.systemMemorySize;
        info.cpu = SystemInfo.processorType;
        info.cpuCount = SystemInfo.processorCount;
        info.supportsShadows = SystemInfo.supportsShadows;
        info.supportsRenderTextures = SystemInfo.supportsRenderTextures;
        info.supportsComputeShaders = SystemInfo.supportsComputeShaders;
        
        // 评估兼容性等级
        if (info.ram >= 8192 && info.cpuCount >= 4 && info.supportsShadows)
        {
            info.compatibilityLevel = CompatibilityLevel.High;
        }
        else if (info.ram >= 4096 && info.cpuCount >= 2)
        {
            info.compatibilityLevel = CompatibilityLevel.Medium;
        }
        else
        {
            info.compatibilityLevel = CompatibilityLevel.Low;
        }

        return info;
    }
}

// 系统兼容性信息
[System.Serializable]
public class SystemCompatibilityInfo
{
    public string os;
    public string gpu;
    public string gpuType;
    public int ram; // MB
    public string cpu;
    public int cpuCount;
    public bool supportsShadows;
    public bool supportsRenderTextures;
    public bool supportsComputeShaders;
    public CompatibilityLevel compatibilityLevel;
}

public enum CompatibilityLevel
{
    Low,
    Medium,
    High
}

// 构建工具类
public class BuildTool : MonoBehaviour
{
    [Header("构建配置")]
    public BuildTargetGroup targetPlatform = BuildTargetGroup.Standalone;
    public BuildTarget buildTarget = BuildTarget.StandaloneWindows64;
    public string buildPath = "Builds/";
    public bool developmentBuild = false;
    public bool autoRunPlayer = false;
    public bool enableHeadlessMode = false;

    [Header("场景配置")]
    public string[] scenesToBuild;
    public int mainSceneIndex = 0;

    [ContextMenu("执行构建")]
    public void PerformBuild()
    {
        #if UNITY_EDITOR
        // 设置场景
        EditorBuildSettingsScene[] buildScenes = new EditorBuildSettingsScene[scenesToBuild.Length];
        for (int i = 0; i < scenesToBuild.Length; i++)
        {
            buildScenes[i] = new EditorBuildSettingsScene(scenesToBuild[i], true);
        }
        EditorBuildSettings.scenes = buildScenes;

        // 构建选项
        BuildOptions options = BuildOptions.None;
        if (developmentBuild)
        {
            options |= BuildOptions.Development;
        }
        if (enableHeadlessMode)
        {
            options |= BuildOptions.EnableHeadlessMode;
        }

        // 执行构建
        string buildPathFull = buildPath + GetBuildFileName();
        UnityEditor.Build.Reporting.BuildReport report = 
            UnityEditor.BuildPipeline.BuildPlayer(
                scenesToBuild, 
                buildPathFull, 
                buildTarget, 
                options
            );

        if (report.summary.result == UnityEditor.Build.Reporting.BuildResult.Succeeded)
        {
            Debug.Log($"构建成功: {buildPathFull}");
        }
        else
        {
            Debug.LogError($"构建失败: {report.summary.totalErrors} 个错误");
        }
        #endif
    }

    // 获取构建文件名
    private string GetBuildFileName()
    {
        string fileName = GameBuildSettings.Instance.gameTitle.Replace(" ", "_");
        
        switch (buildTarget)
        {
            case BuildTarget.StandaloneWindows:
            case BuildTarget.StandaloneWindows64:
                return fileName + ".exe";
            case BuildTarget.StandaloneOSX:
                return fileName + ".app";
            case BuildTarget.Android:
                return fileName + ".apk";
            case BuildTarget.iOS:
                return fileName + ".ipa";
            default:
                return fileName + ".exe";
        }
    }

    // 设置目标平台
    public void SetTargetPlatform(BuildTarget newTarget)
    {
        buildTarget = newTarget;
        
        switch (newTarget)
        {
            case BuildTarget.StandaloneWindows:
            case BuildTarget.StandaloneWindows64:
                targetPlatform = BuildTargetGroup.Standalone;
                break;
            case BuildTarget.Android:
                targetPlatform = BuildTargetGroup.Android;
                break;
            case BuildTarget.iOS:
                targetPlatform = BuildTargetGroup.iOS;
                break;
            case BuildTarget.WebGL:
                targetPlatform = BuildTargetGroup.WebGL;
                break;
        }
    }

    // 检查构建先决条件
    public bool CheckBuildPrerequisites()
    {
        #if UNITY_EDITOR
        // 检查是否安装了目标平台的构建支持
        if (!BuildPipeline.IsBuildTargetSupported(buildTarget))
        {
            Debug.LogError($"目标平台 {buildTarget} 不受支持");
            return false;
        }

        // 检查场景文件是否存在
        foreach (string scene in scenesToBuild)
        {
            if (string.IsNullOrEmpty(scene))
            {
                Debug.LogError("场景路径不能为空");
                return false;
            }
        }

        return true;
        #else
        return false;
        #endif
    }
}

// 发布清单
public class ReleaseManifest
{
    public string version;
    public string buildDate;
    public string[] dependencies;
    public string[] assets;
    public string[] scenes;
    public string[] scripts;
    public string[] prefabs;
    public string[] materials;
    public string[] textures;
    public string platform;
    public string architecture;
    public string[] supportedLanguages;
    public string[] requiredPermissions;

    public ReleaseManifest()
    {
        version = Application.version;
        buildDate = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        platform = Application.platform.ToString();
        architecture = System.Environment.Is64BitProcess ? "x64" : "x86";
    }

    // 生成发布清单
    public static ReleaseManifest GenerateManifest()
    {
        ReleaseManifest manifest = new ReleaseManifest();

        // 收集场景
        manifest.scenes = UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings > 0 ?
            new string[UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings] : new string[0];

        // 收集资源(简化版本)
        manifest.assets = new string[] { "Assets/", "Resources/", "StreamingAssets/" };

        // 收集脚本(实际项目中需要更复杂的资源分析)
        manifest.scripts = new string[] { "Scripts/", "Editor/" };

        // 收集预制件
        manifest.prefabs = new string[] { "Prefabs/" };

        // 收集材质
        manifest.materials = new string[] { "Materials/" };

        // 收集纹理
        manifest.textures = new string[] { "Textures/" };

        // 支持的语言
        manifest.supportedLanguages = new string[] { "English", "Chinese" }; // 根据项目需要调整

        // 需要的权限(主要用于移动平台)
        manifest.requiredPermissions = new string[] { 
            "Internet", 
            "Storage", 
            "Microphone" // 如果有音频录制功能
        };

        return manifest;
    }
}

性能优化检查清单

using UnityEngine;
using System.Collections.Generic;

// 性能优化检查器
public class PerformanceChecker : MonoBehaviour
{
    [Header("性能监控")]
    public bool enablePerformanceMonitoring = true;
    public float monitorInterval = 1f;
    public int targetFrameRate = 60;
    public float warningThreshold = 0.8f; // 80%目标帧率的阈值

    [Header("优化建议")]
    public bool suggestOptimizations = true;
    public bool autoApplyOptimizations = false;

    private float lastMonitorTime = 0f;
    private List<float> frameTimes = new List<float>();
    private int frameCount = 0;
    private float totalTime = 0f;

    void Update()
    {
        if (enablePerformanceMonitoring && Time.time - lastMonitorTime >= monitorInterval)
        {
            AnalyzePerformance();
            lastMonitorTime = Time.time;
        }
    }

    // 分析性能
    private void AnalyzePerformance()
    {
        float currentFPS = 1.0f / Time.unscaledDeltaTime;
        float averageFPS = frameCount > 0 ? totalTime / frameCount : currentFPS;

        // 检查帧率
        if (currentFPS < targetFrameRate * warningThreshold)
        {
            Debug.LogWarning($"性能警告: 当前FPS {currentFPS:F1}, 低于阈值 {targetFrameRate * warningThreshold:F1}");
            SuggestFPSOptimizations();
        }

        // 检查内存使用
        long memoryUsage = System.GC.GetTotalMemory(false);
        if (memoryUsage > 500 * 1024 * 1024) // 500MB
        {
            Debug.LogWarning($"内存使用警告: {memoryUsage / 1024 / 1024}MB");
            SuggestMemoryOptimizations();
        }

        // 检查Draw Calls
        if (UnityEngine.Rendering.RenderSettings.renderingLayerMask > 1000)
        {
            Debug.LogWarning($"绘制调用过多: {UnityEngine.Rendering.RenderSettings.renderingLayerMask}");
            SuggestDrawCallOptimizations();
        }

        // 记录帧时间
        frameTimes.Add(Time.unscaledDeltaTime);
        if (frameTimes.Count > 60) // 保留最近60帧的数据
        {
            frameTimes.RemoveAt(0);
        }
    }

    // 建议FPS优化
    private void SuggestFPSOptimizations()
    {
        if (!suggestOptimizations) return;

        Debug.Log("FPS优化建议:");
        Debug.Log("1. 检查是否有过多的Update调用");
        Debug.Log("2. 优化物理计算和碰撞检测");
        Debug.Log("3. 减少不必要的对象创建和销毁");
        Debug.Log("4. 使用对象池模式");
        Debug.Log("5. 优化AI和路径寻找算法");
        Debug.Log("6. 减少UI更新频率");
    }

    // 建议内存优化
    private void SuggestMemoryOptimizations()
    {
        if (!suggestOptimizations) return;

        Debug.Log("内存优化建议:");
        Debug.Log("1. 检查是否有内存泄漏");
        Debug.Log("2. 优化纹理和模型的内存占用");
        Debug.Log("3. 使用AssetBundles进行资源管理");
        Debug.Log("4. 及时释放不需要的资源");
        Debug.Log("5. 使用对象池减少GC压力");
        Debug.Log("6. 检查字符串操作,避免频繁拼接");
    }

    // 建议绘制调用优化
    private void SuggestDrawCallOptimizations()
    {
        if (!suggestOptimizations) return;

        Debug.Log("绘制调用优化建议:");
        Debug.Log("1. 启用动态批处理和静态批处理");
        Debug.Log("2. 使用图集合并小纹理");
        Debug.Log("3. 减少材质数量");
        Debug.Log("4. 使用LOD系统");
        Debug.Log("5. 优化光照计算");
        Debug.Log("6. 使用遮挡剔除");
    }

    // 性能报告
    public PerformanceReport GeneratePerformanceReport()
    {
        PerformanceReport report = new PerformanceReport();
        
        report.timestamp = System.DateTime.Now;
        report.targetFrameRate = targetFrameRate;
        report.currentFrameRate = 1.0f / Time.unscaledDeltaTime;
        
        if (frameTimes.Count > 0)
        {
            float sum = 0f;
            foreach (float time in frameTimes)
            {
                sum += time;
            }
            report.averageFrameRate = 1.0f / (sum / frameTimes.Count);
        }
        
        report.memoryUsage = System.GC.GetTotalMemory(false);
        report.totalObjects = FindObjectsOfType<Object>().Length;
        report.drawCalls = UnityEngine.Rendering.RenderSettings.renderingLayerMask;
        
        return report;
    }

    // 性能报告数据结构
    [System.Serializable]
    public class PerformanceReport
    {
        public System.DateTime timestamp;
        public int targetFrameRate;
        public float currentFrameRate;
        public float averageFrameRate;
        public long memoryUsage; // 字节
        public int totalObjects;
        public int drawCalls;
        public string[] optimizationSuggestions;
        public bool isOptimal;
    }
}

// 资源优化工具
public class ResourceOptimizer : MonoBehaviour
{
    [Header("纹理优化")]
    public bool compressTextures = true;
    public int maxTextureSize = 2048;
    public TextureFormat targetFormat = TextureFormat.RGBA32;

    [Header("模型优化")]
    public bool optimizeMeshes = true;
    public float maxPolygonCount = 10000f;
    public bool useLODs = true;

    [Header("音频优化")]
    public bool compressAudio = true;
    public AudioCompressionFormat compressionFormat = AudioCompressionFormat.PCM;

    // 优化纹理
    public void OptimizeTextures()
    {
        #if UNITY_EDITOR
        // 获取所有纹理资源
        string[] textureGUIDs = UnityEditor.AssetDatabase.FindAssets("t:Texture2D");
        
        foreach (string guid in textureGUIDs)
        {
            string path = UnityEditor.AssetDatabase.GUIDToAssetPath(guid);
            UnityEditor.TextureImporter importer = 
                UnityEditor.AssetImporter.GetAtPath(path) as UnityEditor.TextureImporter;
            
            if (importer != null)
            {
                // 设置压缩
                if (compressTextures)
                {
                    importer.compressionQuality = UnityEditor.TextureImporterCompression.High;
                }
                
                // 设置最大尺寸
                importer.maxTextureSize = Mathf.Min(importer.maxTextureSize, maxTextureSize);
                
                // 应用更改
                importer.SaveAndReimport();
            }
        }
        
        Debug.Log($"纹理优化完成,处理了 {textureGUIDs.Length} 个纹理");
        #endif
    }

    // 优化模型
    public void OptimizeModels()
    {
        #if UNITY_EDITOR
        // 获取所有模型资源
        string[] modelGUIDs = UnityEditor.AssetDatabase.FindAssets("t:Model");
        
        foreach (string guid in modelGUIDs)
        {
            string path = UnityEditor.AssetDatabase.GUIDToAssetPath(guid);
            UnityEditor.ModelImporter importer = 
                UnityEditor.AssetImporter.GetAtPath(path) as UnityEditor.ModelImporter;
            
            if (importer != null)
            {
                // 设置网格优化
                if (optimizeMeshes)
                {
                    importer.optimizeMeshVertices = true;
                    importer.optimizeMeshIndices = true;
                }
                
                // 设置动画压缩
                importer.animationCompression = UnityEditor.ModelImporterAnimationCompression.Optimal;
                
                // 应用更改
                importer.SaveAndReimport();
            }
        }
        
        Debug.Log($"模型优化完成,处理了 {modelGUIDs.Length} 个模型");
        #endif
    }

    // 优化音频
    public void OptimizeAudio()
    {
        #if UNITY_EDITOR
        // 获取所有音频资源
        string[] audioGUIDs = UnityEditor.AssetDatabase.FindAssets("t:AudioClip");
        
        foreach (string guid in audioGUIDs)
        {
            string path = UnityEditor.AssetDatabase.GUIDToAssetPath(guid);
            UnityEditor.AudioImporter importer = 
                UnityEditor.AssetImporter.GetAtPath(path) as UnityEditor.AudioImporter;
            
            if (importer != null)
            {
                // 设置压缩
                if (compressAudio)
                {
                    importer.compressionFormat = compressionFormat;
                    importer.quality = 0.5f; // 中等质量
                }
                
                // 设置3D音效
                importer.forceToMono = false; // 根据需要设置
                
                // 应用更改
                importer.SaveAndReimport();
            }
        }
        
        Debug.Log($"音频优化完成,处理了 {audioGUIDs.Length} 个音频文件");
        #endif
    }

    // 一键优化所有资源
    public void OptimizeAllResources()
    {
        OptimizeTextures();
        OptimizeModels();
        OptimizeAudio();
        
        Debug.Log("所有资源优化完成!");
    }
}

项目总结与扩展

项目总结

// 项目总结和最佳实践
public class ProjectSummary : MonoBehaviour
{
    [Header("项目结构总结")]
    public string projectName = "Game Project";
    public string projectVersion = "1.0.0";
    public string developmentTeam = "Development Team";
    public string projectDuration = "3 months";

    [Header("技术栈总结")]
    public string engineVersion = "Unity 2022.3 LTS";
    public string programmingLanguage = "C#";
    public string targetPlatforms = "Windows, Android, iOS";
    public string thirdPartyAssets = "TextMeshPro, Post Processing, DOTween";

    [Header("功能模块")]
    public List<FeatureModule> implementedModules = new List<FeatureModule>();
    public List<FeatureModule> plannedModules = new List<FeatureModule>();

    [Header("性能指标")]
    public PerformanceMetrics performanceMetrics = new PerformanceMetrics();

    [Header("代码质量")]
    public CodeQualityMetrics codeQuality = new CodeQualityMetrics();

    // 功能模块信息
    [System.Serializable]
    public class FeatureModule
    {
        public string moduleName;
        public string description;
        public string status; // Implemented, In Progress, Planned
        public string implementationDate;
        public string developer;
        public string complexity; // Low, Medium, High
        public string performanceImpact; // Low, Medium, High
    }

    // 性能指标
    [System.Serializable]
    public class PerformanceMetrics
    {
        public float averageFrameRate = 60f;
        public float minimumFrameRate = 30f;
        public long peakMemoryUsage = 500 * 1024 * 1024; // 500MB
        public int drawCallCount = 100;
        public int batchCount = 50;
        public string testScenarios;
    }

    // 代码质量指标
    [System.Serializable]
    public class CodeQualityMetrics
    {
        public int totalLinesOfCode = 10000;
        public int totalClasses = 50;
        public int totalMethods = 200;
        public float codeCoverage = 0.8f; // 80%
        public int codeViolations = 5;
        public string codeStandards = "Unity C# Coding Standards";
        public string documentationCoverage = "70%";
    }

    // 生成项目总结报告
    public ProjectReport GenerateProjectReport()
    {
        ProjectReport report = new ProjectReport();
        
        report.projectName = projectName;
        report.version = projectVersion;
        report.duration = projectDuration;
        report.team = developmentTeam;
        
        report.engineVersion = engineVersion;
        report.language = programmingLanguage;
        report.platforms = targetPlatforms;
        report.assets = thirdPartyAssets;
        
        report.implementedFeatures = implementedModules.Count;
        report.plannedFeatures = plannedModules.Count;
        
        report.performance = performanceMetrics;
        report.codeQuality = codeQuality;
        
        report.completionPercentage = CalculateCompletionPercentage();
        report.riskAssessment = PerformRiskAssessment();
        report.recommendations = GenerateRecommendations();
        
        return report;
    }

    // 计算完成百分比
    private float CalculateCompletionPercentage()
    {
        int totalFeatures = implementedModules.Count + plannedModules.Count;
        return totalFeatures > 0 ? (float)implementedModules.Count / totalFeatures * 100 : 0;
    }

    // 执行风险评估
    private RiskAssessment PerformRiskAssessment()
    {
        RiskAssessment assessment = new RiskAssessment();
        
        // 性能风险
        if (performanceMetrics.averageFrameRate < 30)
        {
            assessment.performanceRisk = RiskLevel.High;
        }
        else if (performanceMetrics.averageFrameRate < 50)
        {
            assessment.performanceRisk = RiskLevel.Medium;
        }
        else
        {
            assessment.performanceRisk = RiskLevel.Low;
        }

        // 内存风险
        if (performanceMetrics.peakMemoryUsage > 1000 * 1024 * 1024) // 1GB
        {
            assessment.memoryRisk = RiskLevel.High;
        }
        else if (performanceMetrics.peakMemoryUsage > 500 * 1024 * 1024) // 500MB
        {
            assessment.memoryRisk = RiskLevel.Medium;
        }
        else
        {
            assessment.memoryRisk = RiskLevel.Low;
        }

        // 代码质量风险
        if (codeQuality.codeCoverage < 0.5f) // 50%
        {
            assessment.codeQualityRisk = RiskLevel.High;
        }
        else if (codeQuality.codeCoverage < 0.7f) // 70%
        {
            assessment.codeQualityRisk = RiskLevel.Medium;
        }
        else
        {
            assessment.codeQualityRisk = RiskLevel.Low;
        }

        return assessment;
    }

    // 生成建议
    private List<string> GenerateRecommendations()
    {
        List<string> recommendations = new List<string>();

        if (performanceMetrics.averageFrameRate < 50)
        {
            recommendations.Add("优化游戏性能,目标平均帧率提升至50以上");
        }

        if (performanceMetrics.peakMemoryUsage > 500 * 1024 * 1024)
        {
            recommendations.Add("优化内存使用,减少峰值内存占用");
        }

        if (codeQuality.codeCoverage < 0.7f)
        {
            recommendations.Add("增加单元测试覆盖,目标覆盖率提升至70%以上");
        }

        if (implementedModules.Count == 0)
        {
            recommendations.Add("开始实施核心功能模块");
        }

        return recommendations;
    }
}

// 项目报告
[System.Serializable]
public class ProjectReport
{
    public string projectName;
    public string version;
    public string duration;
    public string team;
    public string engineVersion;
    public string language;
    public string platforms;
    public string assets;
    
    public int implementedFeatures;
    public int plannedFeatures;
    
    public ProjectSummary.PerformanceMetrics performance;
    public ProjectSummary.CodeQualityMetrics codeQuality;
    
    public float completionPercentage;
    public RiskAssessment riskAssessment;
    public List<string> recommendations = new List<string>();
    public System.DateTime reportGenerated = System.DateTime.Now;
}

// 风险评估
[System.Serializable]
public class RiskAssessment
{
    public RiskLevel performanceRisk = RiskLevel.Unknown;
    public RiskLevel memoryRisk = RiskLevel.Unknown;
    public RiskLevel codeQualityRisk = RiskLevel.Unknown;
    public RiskLevel scheduleRisk = RiskLevel.Unknown;
    public RiskLevel featureRisk = RiskLevel.Unknown;
}

public enum RiskLevel
{
    Unknown,
    Low,
    Medium,
    High
}

扩展建议

// 项目扩展建议
public class ProjectExtensionGuide : MonoBehaviour
{
    [Header("扩展方向")]
    public List<ExtensionArea> extensionAreas = new List<ExtensionArea>();

    [Header("技术升级路径")]
    public List<TechnologyUpgrade> technologyUpgrades = new List<TechnologyUpgrade>();

    [Header("功能扩展")]
    public List<FeatureExtension> featureExtensions = new List<FeatureExtension>();

    // 扩展领域
    [System.Serializable]
    public class ExtensionArea
    {
        public string areaName;
        public string description;
        public Priority priority;
        public Complexity complexity;
        public float estimatedTime; // 周
        public string dependencies;
        public string benefits;
        public string risks;
    }

    // 技术升级
    [System.Serializable]
    public class TechnologyUpgrade
    {
        public string technologyName;
        public string currentVersion;
        public string targetVersion;
        public string benefits;
        public string risks;
        public float estimatedTime;
        public string implementationSteps;
    }

    // 功能扩展
    [System.Serializable]
    public class FeatureExtension
    {
        public string featureName;
        public string description;
        public string implementationPlan;
        public string resourceRequirements;
        public float estimatedDevelopmentTime;
        public float estimatedTestingTime;
        public string successMetrics;
    }

    public enum Priority
    {
        Low,
        Medium,
        High,
        Critical
    }

    public enum Complexity
    {
        Simple,
        Moderate,
        Complex,
        VeryComplex
    }

    // 获取扩展建议
    public ExtensionRecommendation GetExtensionRecommendations()
    {
        ExtensionRecommendation recommendation = new ExtensionRecommendation();

        // 分析当前项目状态
        AnalyzeCurrentState(recommendation);

        // 生成扩展建议
        GenerateExpansionSuggestions(recommendation);

        // 评估实施难度
        EvaluateImplementationDifficulty(recommendation);

        return recommendation;
    }

    // 分析当前状态
    private void AnalyzeCurrentState(ExtensionRecommendation recommendation)
    {
        // 分析性能指标
        PerformanceChecker perfChecker = FindObjectOfType<PerformanceChecker>();
        if (perfChecker != null)
        {
            PerformanceChecker.PerformanceReport report = perfChecker.GeneratePerformanceReport();
            
            if (report.averageFrameRate < 50)
            {
                recommendation.performanceOptimizationNeeded = true;
            }
            
            if (report.memoryUsage > 500 * 1024 * 1024)
            {
                recommendation.memoryOptimizationNeeded = true;
            }
        }

        // 分析代码质量
        // 这里可以集成代码分析工具的输出
    }

    // 生成扩展建议
    private void GenerateExpansionSuggestions(ExtensionRecommendation recommendation)
    {
        // 根据游戏类型生成建议
        if (FindObjectOfType<TowerDefenseManager>() != null)
        {
            // 塔防游戏扩展建议
            recommendation.suggestedExtensions.Add("更多塔类型和升级路径");
            recommendation.suggestedExtensions.Add("更多敌人类型和特殊能力");
            recommendation.suggestedExtensions.Add("多人合作模式");
            recommendation.suggestedExtensions.Add("地图编辑器");
        }
        else if (FindObjectOfType<RPGGameManager>() != null)
        {
            // RPG游戏扩展建议
            recommendation.suggestedExtensions.Add("更多职业和技能树");
            recommendation.suggestedExtensions.Add("宠物/伙伴系统");
            recommendation.suggestedExtensions.Add("公会/社交系统");
            recommendation.suggestedExtensions.Add("更多装备和制作系统");
        }
        else if (FindObjectOfType<PlatformerGameManager>() != null)
        {
            // 平台游戏扩展建议
            recommendation.suggestedExtensions.Add("更多关卡和挑战模式");
            recommendation.suggestedExtensions.Add("角色自定义系统");
            recommendation.suggestedExtensions.Add("关卡分享功能");
            recommendation.suggestedExtensions.Add("成就和排行榜系统");
        }
    }

    // 评估实施难度
    private void EvaluateImplementationDifficulty(ExtensionRecommendation recommendation)
    {
        // 根据项目复杂度和团队能力评估
        int totalFeatures = GetImplementedFeaturesCount();
        float complexityScore = CalculateComplexityScore();
        
        if (complexityScore > 0.8f)
        {
            recommendation.implementationDifficulty = Difficulty.High;
            recommendation.requiresSeniorDevelopers = true;
        }
        else if (complexityScore > 0.5f)
        {
            recommendation.implementationDifficulty = Difficulty.Medium;
        }
        else
        {
            recommendation.implementationDifficulty = Difficulty.Low;
        }
    }

    // 获取已实现功能数量
    private int GetImplementedFeaturesCount()
    {
        int count = 0;
        
        // 计算各种系统实现的数量
        if (FindObjectOfType<RPGBattleSystem>() != null) count++;
        if (FindObjectOfType<RPGQuestSystem>() != null) count++;
        if (FindObjectOfType<RPGInventorySystem>() != null) count++;
        if (FindObjectOfType<RPGBattleSystem>() != null) count++;
        
        return count;
    }

    // 计算复杂度评分
    private float CalculateComplexityScore()
    {
        // 简化的复杂度计算
        int totalSystems = 10; // 假设项目应该有10个主要系统
        int implementedSystems = GetImplementedFeaturesCount();
        
        return (float)implementedSystems / totalSystems;
    }
}

// 扩展建议数据结构
[System.Serializable]
public class ExtensionRecommendation
{
    public List<string> suggestedExtensions = new List<string>();
    public List<string> technologyUpgrades = new List<string>();
    public List<string> featurePriorities = new List<string>();
    
    public bool performanceOptimizationNeeded = false;
    public bool memoryOptimizationNeeded = false;
    public bool codeRefactoringNeeded = false;
    public bool architectureImprovementNeeded = false;
    
    public Difficulty implementationDifficulty = Difficulty.Unknown;
    public bool requiresSeniorDevelopers = false;
    public float estimatedTimeToImplement = 0f; // 月
    
    public string implementationPlan;
    public string resourceRequirements;
    public string riskAssessment;
}

public enum Difficulty
{
    Unknown,
    Low,
    Medium,
    High
}

// 项目维护指南
public class ProjectMaintenanceGuide : MonoBehaviour
{
    [Header("维护计划")]
    public List<MaintenanceTask> maintenanceTasks = new List<MaintenanceTask>();
    public float maintenanceInterval = 30f; // 天
    public bool autoMaintenance = false;

    [System.Serializable]
    public class MaintenanceTask
    {
        public string taskName;
        public string description;
        public MaintenanceType type;
        public float interval; // 天
        public System.DateTime lastRun;
        public bool isEnabled = true;
    }

    public enum MaintenanceType
    {
        PerformanceOptimization,
        CodeRefactoring,
        BugFixing,
        FeatureUpdate,
        SecurityUpdate,
        CompatibilityCheck
    }

    // 执行维护任务
    public void PerformMaintenance()
    {
        foreach (MaintenanceTask task in maintenanceTasks)
        {
            if (task.isEnabled && 
                (task.lastRun == System.DateTime.MinValue || 
                 System.DateTime.Now.Subtract(task.lastRun).TotalDays >= task.interval))
            {
                ExecuteMaintenanceTask(task);
                task.lastRun = System.DateTime.Now;
            }
        }
    }

    // 执行特定维护任务
    private void ExecuteMaintenanceTask(MaintenanceTask task)
    {
        switch (task.type)
        {
            case MaintenanceType.PerformanceOptimization:
                OptimizePerformance();
                break;
            case MaintenanceType.CodeRefactoring:
                RefactorCode();
                break;
            case MaintenanceType.BugFixing:
                FixBugs();
                break;
            case MaintenanceType.FeatureUpdate:
                UpdateFeatures();
                break;
            case MaintenanceType.SecurityUpdate:
                UpdateSecurity();
                break;
            case MaintenanceType.CompatibilityCheck:
                CheckCompatibility();
                break;
        }
    }

    // 各种维护操作
    private void OptimizePerformance()
    {
        // 性能优化操作
        System.GC.Collect();
        // 这里可以集成性能分析工具
    }

    private void RefactorCode()
    {
        // 代码重构操作
        // 这里可以集成代码分析和重构工具
    }

    private void FixBugs()
    {
        // Bug修复操作
        // 收集和修复已知问题
    }

    private void UpdateFeatures()
    {
        // 功能更新操作
        // 根据用户反馈更新功能
    }

    private void UpdateSecurity()
    {
        // 安全更新操作
        // 更新依赖库和修复安全漏洞
    }

    private void CheckCompatibility()
    {
        // 兼容性检查操作
        // 检查在新平台或新版本下的兼容性
    }
}

实践练习

练习1: 完整的RPG角色创建系统

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

// RPG角色创建系统
public class RPGCharacterCreator : MonoBehaviour
{
    [Header("角色创建UI")]
    public GameObject characterCreationPanel;
    public InputField characterNameInput;
    public Dropdown characterClassDropdown;
    public Slider[] attributeSliders = new Slider[5]; // 力量、敏捷、智力、体质、运气
    public Text[] attributeTexts = new Text[5];
    public Text totalPointsText;
    public Button createCharacterButton;
    public Button resetButton;

    [Header("预设角色")]
    public List<PresetCharacter> presetCharacters = new List<PresetCharacter>();

    [Header("角色预览")]
    public GameObject characterPreview;
    public Image characterPortrait;

    private int totalAttributePoints = 25;
    private int remainingPoints = 25;
    private int[] attributeValues = new int[5]; // 力量、敏捷、智力、体质、运气

    void Start()
    {
        InitializeCharacterCreator();
    }

    private void InitializeCharacterCreator()
    {
        // 设置职业下拉菜单
        if (characterClassDropdown != null)
        {
            characterClassDropdown.ClearOptions();
            List<string> classOptions = new List<string>();
            
            foreach (CharacterClassType classType in System.Enum.GetValues(typeof(CharacterClassType)))
            {
                classOptions.Add(classType.ToString());
            }
            
            characterClassDropdown.AddOptions(classOptions);
        }

        // 初始化属性滑块
        for (int i = 0; i < attributeSliders.Length; i++)
        {
            int index = i; // 用于闭包
            attributeSliders[i].minValue = 1;
            attributeSliders[i].maxValue = 10;
            attributeSliders[i].value = 5;
            attributeValues[i] = 5;
            
            attributeSliders[i].onValueChanged.AddListener(delegate { OnAttributeChanged(index); });
        }

        UpdateUI();
    }

    // 属性改变事件
    private void OnAttributeChanged(int attributeIndex)
    {
        int oldValue = attributeValues[attributeIndex];
        int newValue = Mathf.RoundToInt(attributeSliders[attributeIndex].value);
        
        int difference = newValue - oldValue;
        remainingPoints -= difference;
        attributeValues[attributeIndex] = newValue;

        // 确保不会超出点数限制
        if (remainingPoints < 0)
        {
            // 撤销更改
            attributeSliders[attributeIndex].value = oldValue;
            attributeValues[attributeIndex] = oldValue;
            remainingPoints += difference;
        }
        else
        {
            UpdateUI();
        }
    }

    // 更新UI显示
    private void UpdateUI()
    {
        // 更新属性文本
        string[] attributeNames = { "Strength", "Dexterity", "Intelligence", "Constitution", "Luck" };
        
        for (int i = 0; i < attributeTexts.Length && i < attributeNames.Length; i++)
        {
            if (attributeTexts[i] != null)
            {
                attributeTexts[i].text = $"{attributeNames[i]}: {attributeValues[i]}";
            }
        }

        // 更新剩余点数显示
        if (totalPointsText != null)
        {
            totalPointsText.text = $"Remaining Points: {remainingPoints}";
        }

        // 更新创建按钮状态
        if (createCharacterButton != null)
        {
            createCharacterButton.interactable = remainingPoints >= 0 && 
                                               !string.IsNullOrEmpty(characterNameInput.text) &&
                                               characterNameInput.text.Length >= 3;
        }
    }

    // 重置属性点数
    public void ResetAttributes()
    {
        for (int i = 0; i < attributeSliders.Length; i++)
        {
            attributeSliders[i].value = 5;
            attributeValues[i] = 5;
        }
        
        remainingPoints = totalAttributePoints - (5 * attributeSliders.Length);
        UpdateUI();
    }

    // 应用预设角色
    public void ApplyPresetCharacter(int presetIndex)
    {
        if (presetIndex >= 0 && presetIndex < presetCharacters.Count)
        {
            PresetCharacter preset = presetCharacters[presetIndex];
            
            // 设置职业
            if (characterClassDropdown != null)
            {
                int classIndex = (int)preset.characterClass;
                characterClassDropdown.value = classIndex;
            }

            // 设置属性
            for (int i = 0; i < attributeSliders.Length && i < preset.attributeValues.Length; i++)
            {
                attributeSliders[i].value = preset.attributeValues[i];
                attributeValues[i] = preset.attributeValues[i];
            }

            // 计算剩余点数
            int usedPoints = 0;
            foreach (int value in preset.attributeValues)
            {
                usedPoints += value;
            }
            remainingPoints = totalAttributePoints - usedPoints;

            UpdateUI();
        }
    }

    // 创建角色
    public void CreateCharacter()
    {
        if (remainingPoints < 0)
        {
            Debug.LogWarning("Not enough attribute points!");
            return;
        }

        string characterName = characterNameInput.text;
        CharacterClassType selectedClass = (CharacterClassType)characterClassDropdown.value;

        // 创建角色数据
        PlayerCharacter newCharacter = new PlayerCharacter();
        newCharacter.Initialize(characterName, selectedClass);

        // 设置属性
        newCharacter.strength = attributeValues[0];
        newCharacter.dexterity = attributeValues[1];
        newCharacter.intelligence = attributeValues[2];
        newCharacter.constitution = attributeValues[3];
        newCharacter.luck = attributeValues[4];

        // 应用职业修正
        CharacterClass charClass = RPGGameManager.Instance.GetCharacterClass(selectedClass);
        if (charClass != null)
        {
            newCharacter.strength = Mathf.RoundToInt(newCharacter.strength * charClass.strengthGrowth);
            newCharacter.dexterity = Mathf.RoundToInt(newCharacter.dexterity * charClass.dexterityGrowth);
            newCharacter.intelligence = Mathf.RoundToInt(newCharacter.intelligence * charClass.intelligenceGrowth);
            newCharacter.constitution = Mathf.RoundToInt(newCharacter.constitution * charClass.constitutionGrowth);
            newCharacter.luck = Mathf.RoundToInt(newCharacter.luck * charClass.luckGrowth);

            // 设置生命值和法力值
            newCharacter.maxHealth = Mathf.RoundToInt(100 * charClass.healthMultiplier) + 
                                   (newCharacter.constitution - 10) * 10;
            newCharacter.currentHealth = newCharacter.maxHealth;
            newCharacter.maxMana = Mathf.RoundToInt(50 * charClass.manaMultiplier) + 
                                 (newCharacter.intelligence - 10) * 5;
            newCharacter.currentMana = newCharacter.maxMana;
        }

        // 设置为当前玩家角色
        RPGGameManager.Instance.player = newCharacter;

        // 隐藏创建面板
        if (characterCreationPanel != null)
        {
            characterCreationPanel.SetActive(false);
        }

        // 触发角色创建完成事件
        OnCharacterCreated(newCharacter);
    }

    // 角色创建完成事件
    private void OnCharacterCreated(PlayerCharacter character)
    {
        Debug.Log($"Character '{character.characterName}' created successfully!");
        
        // 播放创建成功音效
        if (RPGAudioManager.Instance != null)
        {
            RPGAudioManager.Instance.PlaySFX("CharacterCreate");
        }

        // 可以在这里添加角色进入游戏世界的逻辑
    }

    // 预设角色数据
    [System.Serializable]
    public class PresetCharacter
    {
        public string presetName;
        public CharacterClassType characterClass;
        public int[] attributeValues = new int[5]; // 力量、敏捷、智力、体质、运气
    }
}

练习2: 动态关卡生成系统

using UnityEngine;
using System.Collections.Generic;

// 动态关卡生成系统
public class DynamicLevelGenerator : MonoBehaviour
{
    [Header("关卡设置")]
    public int levelWidth = 50;
    public int levelHeight = 50;
    public int seed = 0;
    public bool useRandomSeed = true;

    [Header("地形生成")]
    public float terrainScale = 20f;
    public float waterLevel = 0.3f;
    public float mountainLevel = 0.7f;

    [Header("房间设置")]
    public int minRooms = 5;
    public int maxRooms = 10;
    public int minRoomSize = 4;
    public int maxRoomSize = 10;

    [Header("走廊设置")]
    public bool generateCorridors = true;
    public float corridorWidth = 1f;

    [Header("敌人生成")]
    public List<EnemySpawnData> enemySpawns = new List<EnemySpawnData>();
    public float enemySpawnRate = 0.3f;

    [Header("物品生成")]
    public List<ItemSpawnData> itemSpawns = new List<ItemSpawnData>();
    public float itemSpawnRate = 0.2f;

    [Header("预制件")]
    public GameObject floorPrefab;
    public GameObject wallPrefab;
    public GameObject waterPrefab;
    public GameObject doorPrefab;
    public List<GameObject> enemyPrefabs = new List<GameObject>();
    public List<GameObject> itemPrefabs = new List<GameObject>();

    private System.Random random;
    private List<Room> rooms = new List<Room>();
    private List<Corridor> corridors = new List<Corridor>();
    private bool[,] levelMap;

    [System.Serializable]
    public class EnemySpawnData
    {
        public string enemyType;
        public float spawnChance = 1f;
        public int minLevel = 1;
        public int maxLevel = 10;
    }

    [System.Serializable]
    public class ItemSpawnData
    {
        public string itemType;
        public float spawnChance = 1f;
        public int minLevel = 1;
        public int maxLevel = 10;
    }

    [System.Serializable]
    public class Room
    {
        public int x, y, width, height;
        public int centerX, centerY;
    }

    [System.Serializable]
    public class Corridor
    {
        public int startX, startY, endX, endY;
    }

    void Start()
    {
        GenerateLevel();
    }

    // 生成关卡
    public void GenerateLevel()
    {
        // 设置随机种子
        if (useRandomSeed)
        {
            seed = System.DateTime.Now.Millisecond;
        }
        random = new System.Random(seed);

        // 初始化地图
        levelMap = new bool[levelWidth, levelHeight];

        // 生成房间
        GenerateRooms();

        // 连接房间
        if (generateCorridors)
        {
            GenerateCorridors();
        }

        // 生成地形
        GenerateTerrain();

        // 生成敌人
        SpawnEnemies();

        // 生成物品
        SpawnItems();

        // 在编辑器中可视化地图
        VisualizeLevel();
    }

    // 生成房间
    private void GenerateRooms()
    {
        rooms.Clear();
        int numRooms = random.Next(minRooms, maxRooms + 1);

        for (int i = 0; i < numRooms; i++)
        {
            int width = random.Next(minRoomSize, maxRoomSize + 1);
            int height = random.Next(minRoomSize, maxRoomSize + 1);
            int x = random.Next(1, levelWidth - width - 1);
            int y = random.Next(1, levelHeight - height - 1);

            Room newRoom = new Room
            {
                x = x,
                y = y,
                width = width,
                height = height,
                centerX = x + width / 2,
                centerY = y + height / 2
            };

            // 检查是否与现有房间重叠
            bool overlaps = false;
            foreach (Room otherRoom in rooms)
            {
                if (RectanglesIntersect(newRoom, otherRoom))
                {
                    overlaps = true;
                    break;
                }
            }

            if (!overlaps)
            {
                rooms.Add(newRoom);

                // 标记房间区域
                for (int xi = newRoom.x; xi < newRoom.x + newRoom.width; xi++)
                {
                    for (int yi = newRoom.y; yi < newRoom.y + newRoom.height; yi++)
                    {
                        if (xi >= 0 && xi < levelWidth && yi >= 0 && yi < levelHeight)
                        {
                            levelMap[xi, yi] = true;
                        }
                    }
                }
            }
        }
    }

    // 生成走廊
    private void GenerateCorridors()
    {
        corridors.Clear();

        for (int i = 0; i < rooms.Count - 1; i++)
        {
            Room currentRoom = rooms[i];
            Room nextRoom = rooms[i + 1];

            // H型走廊
            int x1 = currentRoom.centerX;
            int y1 = currentRoom.centerY;
            int x2 = nextRoom.centerX;
            int y2 = nextRoom.centerY;

            // 水平走廊
            int minX = Mathf.Min(x1, x2);
            int maxX = Mathf.Max(x1, x2);
            for (int x = minX; x <= maxX; x++)
            {
                if (x >= 0 && x < levelWidth && y1 >= 0 && y1 < levelHeight)
                {
                    levelMap[x, y1] = true;
                }
            }

            // 垂直走廊
            int minY = Mathf.Min(y1, y2);
            int maxY = Mathf.Max(y1, y2);
            for (int y = minY; y <= maxY; y++)
            {
                if (x2 >= 0 && x2 < levelWidth && y >= 0 && y < levelHeight)
                {
                    levelMap[x2, y] = true;
                }
            }

            corridors.Add(new Corridor { startX = x1, startY = y1, endX = x2, endY = y2 });
        }
    }

    // 生成地形
    private void GenerateTerrain()
    {
        for (int x = 0; x < levelWidth; x++)
        {
            for (int y = 0; y < levelHeight; y++)
            {
                if (!levelMap[x, y])
                {
                    // 使用噪声生成自然地形
                    float noise = Mathf.PerlinNoise(
                        (float)x / terrainScale + seed, 
                        (float)y / terrainScale + seed
                    );

                    if (noise < waterLevel)
                    {
                        // 水域
                        levelMap[x, y] = false; // 保持为false,表示不可通行
                    }
                    else if (noise > mountainLevel)
                    {
                        // 山地,不可通行
                        levelMap[x, y] = false;
                    }
                    else
                    {
                        // 普通地面,可通行
                        levelMap[x, y] = true;
                    }
                }
            }
        }
    }

    // 生成敌人
    private void SpawnEnemies()
    {
        for (int x = 0; x < levelWidth; x++)
        {
            for (int y = 0; y < levelHeight; y++)
            {
                if (levelMap[x, y] && random.NextDouble() < enemySpawnRate)
                {
                    // 选择敌人类型
                    if (enemyPrefabs.Count > 0)
                    {
                        int enemyIndex = random.Next(enemyPrefabs.Count);
                        GameObject enemyPrefab = enemyPrefabs[enemyIndex];

                        Vector3 spawnPos = new Vector3(x, 0, y);
                        GameObject enemy = Instantiate(enemyPrefab, spawnPos, Quaternion.identity);
                        
                        // 设置敌人属性(等级等)
                        Enemy enemyScript = enemy.GetComponent<Enemy>();
                        if (enemyScript != null)
                        {
                            // 根据关卡调整敌人属性
                            enemyScript.level = Random.Range(1, 5);
                        }
                    }
                }
            }
        }
    }

    // 生成物品
    private void SpawnItems()
    {
        for (int x = 0; x < levelWidth; x++)
        {
            for (int y = 0; y < levelHeight; y++)
            {
                if (levelMap[x, y] && random.NextDouble() < itemSpawnRate)
                {
                    // 选择物品类型
                    if (itemPrefabs.Count > 0)
                    {
                        int itemIndex = random.Next(itemPrefabs.Count);
                        GameObject itemPrefab = itemPrefabs[itemIndex];

                        Vector3 spawnPos = new Vector3(x, 0, y);
                        Instantiate(itemPrefab, spawnPos, Quaternion.identity);
                    }
                }
            }
        }
    }

    // 检查矩形是否相交
    private bool RectanglesIntersect(Room a, Room b)
    {
        return a.x < b.x + b.width &&
               a.x + a.width > b.x &&
               a.y < b.y + b.height &&
               a.y + a.height > b.y;
    }

    // 可视化关卡(仅在编辑器中)
    private void VisualizeLevel()
    {
        #if UNITY_EDITOR
        // 清除旧的可视化对象
        foreach (Transform child in transform)
        {
            DestroyImmediate(child.gameObject);
        }

        // 创建可视化对象
        for (int x = 0; x < levelWidth; x++)
        {
            for (int y = 0; y < levelHeight; y++)
            {
                GameObject tile;
                if (levelMap[x, y])
                {
                    // 可通行区域
                    tile = Instantiate(floorPrefab, new Vector3(x, 0, y), Quaternion.identity);
                    tile.name = $"Floor_{x}_{y}";
                }
                else
                {
                    // 不可通行区域
                    tile = Instantiate(wallPrefab, new Vector3(x, 0, y), Quaternion.identity);
                    tile.name = $"Wall_{x}_{y}";
                }
                
                tile.transform.SetParent(transform);
            }
        }
        #endif
    }

    // 获取随机可通行位置
    public Vector3 GetRandomPassablePosition()
    {
        List<Vector3> passablePositions = new List<Vector3>();

        for (int x = 0; x < levelWidth; x++)
        {
            for (int y = 0; y < levelHeight; y++)
            {
                if (levelMap[x, y])
                {
                    passablePositions.Add(new Vector3(x, 0, y));
                }
            }
        }

        if (passablePositions.Count > 0)
        {
            int randomIndex = random.Next(passablePositions.Count);
            return passablePositions[randomIndex];
        }

        return Vector3.zero; // 如果没有可通行位置,返回原点
    }

    // 检查位置是否可通行
    public bool IsPassable(int x, int y)
    {
        if (x < 0 || x >= levelWidth || y < 0 || y >= levelHeight)
        {
            return false;
        }
        return levelMap[x, y];
    }

    // 生成新关卡
    public void GenerateNewLevel()
    {
        if (useRandomSeed)
        {
            seed = System.DateTime.Now.Millisecond;
        }
        else
        {
            seed = random.Next();
        }
        
        GenerateLevel();
    }

    // 在场景视图中可视化
    void OnDrawGizmos()
    {
        if (levelMap != null)
        {
            for (int x = 0; x < levelWidth; x++)
            {
                for (int y = 0; y < levelHeight; y++)
                {
                    Gizmos.color = levelMap[x, y] ? Color.green : Color.red;
                    Gizmos.DrawCube(new Vector3(x, 0, y), Vector3.one * 0.8f);
                }
            }

            // 绘制房间边界
            Gizmos.color = Color.blue;
            foreach (Room room in rooms)
            {
                Vector3 center = new Vector3(room.x + room.width / 2f, 0, room.y + room.height / 2f);
                Vector3 size = new Vector3(room.width, 0.1f, room.height);
                Gizmos.DrawWireCube(center, size);
            }

            // 绘制走廊
            Gizmos.color = Color.yellow;
            foreach (Corridor corridor in corridors)
            {
                Gizmos.DrawLine(
                    new Vector3(corridor.startX, 0.1f, corridor.startY),
                    new Vector3(corridor.endX, 0.1f, corridor.endY)
                );
            }
        }
    }
}

常见错误和最佳实践

1. 性能优化最佳实践

using UnityEngine;
using System.Collections.Generic;

// 性能优化最佳实践示例
public class PerformanceBestPractices : MonoBehaviour
{
    // ❌ 错误:在Update中进行昂贵操作
    /*
    void Update()
    {
        // 每帧都查找对象 - 很慢!
        GameObject player = GameObject.Find("Player");
        
        // 每帧都获取组件 - 很慢!
        Transform playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
        
        // 每帧都进行复杂计算 - 很慢!
        List<GameObject> enemies = new List<GameObject>();
        enemies.AddRange(GameObject.FindGameObjectsWithTag("Enemy"));
    }
    */

    // ✅ 正确:缓存引用
    private Transform playerTransform;
    private List<Transform> enemyTransforms = new List<Transform>();
    private CharacterController playerController;
    private Renderer playerRenderer;

    void Start()
    {
        // 一次性获取并缓存引用
        GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
        if (playerObj != null)
        {
            playerTransform = playerObj.transform;
            playerController = playerObj.GetComponent<CharacterController>();
            playerRenderer = playerObj.GetComponent<Renderer>();
        }

        // 一次性获取所有敌人引用
        GameObject[] enemyObjs = GameObject.FindGameObjectsWithTag("Enemy");
        foreach (GameObject enemyObj in enemyObjs)
        {
            enemyTransforms.Add(enemyObj.transform);
        }
    }

    void Update()
    {
        // 使用缓存的引用 - 快!
        if (playerTransform != null)
        {
            // 对playerTransform进行操作
        }

        // 使用缓存的组件 - 快!
        if (playerController != null)
        {
            // 对playerController进行操作
        }
    }

    // ❌ 错误:频繁创建和销毁对象
    /*
    void Update()
    {
        GameObject effect = new GameObject(); // 每帧创建新对象
        Destroy(effect, 1f); // 1秒后销毁 - 造成GC压力
    }
    */

    // ✅ 正确:使用对象池
    private Queue<GameObject> effectPool = new Queue<GameObject>();
    private GameObject effectPrefab;

    private GameObject GetEffectFromPool()
    {
        if (effectPool.Count > 0)
        {
            GameObject effect = effectPool.Dequeue();
            effect.SetActive(true);
            return effect;
        }
        else
        {
            return Instantiate(effectPrefab);
        }
    }

    private void ReturnEffectToPool(GameObject effect)
    {
        effect.SetActive(false);
        effect.transform.SetParent(transform); // 归属到池对象下
        effectPool.Enqueue(effect);
    }

    // ❌ 错误:在循环中进行昂贵操作
    /*
    void Update()
    {
        for (int i = 0; i < transform.childCount; i++)
        {
            // 每次循环都调用GetComponent - 很慢!
            var script = transform.GetChild(i).GetComponent<SomeComponent>();
        }
    }
    */

    // ✅ 正确:预先获取引用
    private List<SomeComponent> childComponents = new List<SomeComponent>();

    void CacheChildComponents()
    {
        childComponents.Clear();
        for (int i = 0; i < transform.childCount; i++)
        {
            SomeComponent component = transform.GetChild(i).GetComponent<SomeComponent>();
            if (component != null)
            {
                childComponents.Add(component);
            }
        }
    }

    // 使用预分配的列表而不是每次都创建新列表
    private List<Collider> tempColliders = new List<Collider>(50); // 预分配容量

    void OptimizedOverlapSphere(Vector3 center, float radius)
    {
        tempColliders.Clear(); // 清空但不重新分配内存
        int count = Physics.OverlapSphereNonAlloc(center, radius, 
            tempColliders.Capacity > 0 ? 
            tempColliders.GetRange(0, tempColliders.Capacity).ToArray() : 
            new Collider[0]);
        
        // 处理碰撞体...
    }

    // 使用对象池的完整示例
    public class ObjectPool<T> where T : Component
    {
        private Queue<T> pool = new Queue<T>();
        private T prefab;
        private Transform parent;

        public ObjectPool(T prefab, int initialSize, Transform parent = null)
        {
            this.prefab = prefab;
            this.parent = parent;

            for (int i = 0; i < initialSize; i++)
            {
                T obj = CreateNewObject();
                ReturnToPool(obj);
            }
        }

        public T Get()
        {
            T obj;
            if (pool.Count > 0)
            {
                obj = pool.Dequeue();
                obj.gameObject.SetActive(true);
            }
            else
            {
                obj = CreateNewObject();
            }
            return obj;
        }

        public void ReturnToPool(T obj)
        {
            obj.gameObject.SetActive(false);
            obj.transform.SetParent(parent);
            pool.Enqueue(obj);
        }

        private T CreateNewObject()
        {
            T obj = GameObject.Instantiate(prefab);
            obj.transform.SetParent(parent);
            obj.gameObject.SetActive(false);
            return obj;
        }
    }

    // 使用对象池
    private ObjectPool<GameObject> bulletPool;

    void InitializeBulletPool()
    {
        GameObject bulletPrefab = Resources.Load<GameObject>("Prefabs/Bullet");
        bulletPool = new ObjectPool<GameObject>(bulletPrefab, 20, transform);
    }

    GameObject SpawnBullet()
    {
        return bulletPool.Get();
    }

    void ReturnBullet(GameObject bullet)
    {
        bulletPool.ReturnToPool(bullet);
    }

    // 优化的字符串操作
    private System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();

    string BuildStatusString(int health, int mana, int level)
    {
        stringBuilder.Length = 0; // 清空但不重新分配内存
        stringBuilder.Append("Health: ");
        stringBuilder.Append(health);
        stringBuilder.Append(", Mana: ");
        stringBuilder.Append(mana);
        stringBuilder.Append(", Level: ");
        stringBuilder.Append(level);
        return stringBuilder.ToString();
    }

    // 优化的协程管理
    private List<Coroutine> activeCoroutines = new List<Coroutine>();

    Coroutine StartManagedCoroutine(System.Collections.IEnumerator routine)
    {
        Coroutine coroutine = StartCoroutine(routine);
        activeCoroutines.Add(coroutine);
        return coroutine;
    }

    void StopManagedCoroutine(Coroutine coroutine)
    {
        if (activeCoroutines.Contains(coroutine))
        {
            StopCoroutine(coroutine);
            activeCoroutines.Remove(coroutine);
        }
    }

    void StopAllManagedCoroutines()
    {
        foreach (Coroutine coroutine in activeCoroutines.ToArray())
        {
            if (coroutine != null)
            {
                StopCoroutine(coroutine);
            }
        }
        activeCoroutines.Clear();
    }

    void OnDestroy()
    {
        StopAllManagedCoroutines();
    }
}

// 占位符组件
public class SomeComponent : MonoBehaviour { }

2. 内存管理最佳实践

using UnityEngine;
using System.Collections.Generic;

// 内存管理最佳实践
public class MemoryManagementBestPractices : MonoBehaviour
{
    // ✅ 使用结构体而不是类(适用于小对象)
    [System.Serializable]
    public struct PositionData
    {
        public Vector3 position;
        public Quaternion rotation;
        public int id;

        public PositionData(Vector3 pos, Quaternion rot, int id)
        {
            position = pos;
            rotation = rot;
            this.id = id;
        }
    }

    // ✅ 预分配列表大小
    private List<GameObject> enemies = new List<GameObject>(100); // 预分配容量
    private Dictionary<int, PositionData> entityData = new Dictionary<int, PositionData>(50); // 预分配容量

    // ✅ 使用Span<T>进行高性能数组操作(C# 7.2+)
    void ProcessArrayWithSpan(int[] array)
    {
        System.Span<int> span = array.AsSpan();
        for (int i = 0; i < span.Length; i++)
        {
            span[i] *= 2; // 直接在栈上操作,无GC
        }
    }

    // ✅ 避免装箱/拆箱
    void AvoidBoxing()
    {
        // ❌ 错误:装箱
        // object boxedInt = 42; // int装箱为object
        // List<object> mixedList = new List<object> { 1, 2, 3, "string" }; // 发生装箱

        // ✅ 正确:使用泛型
        List<int> intList = new List<int> { 1, 2, 3, 4, 5 };
        List<string> stringList = new List<string> { "a", "b", "c" };
    }

    // ✅ 事件系统内存管理
    private System.Action<int> scoreChangedCallback;

    void SubscribeToEvents()
    {
        // 使用具体方法而不是Lambda来避免闭包
        scoreChangedCallback = OnScoreChanged;
        GameEvents.OnScoreChanged += scoreChangedCallback;
    }

    void UnsubscribeFromEvents()
    {
        // 记得取消订阅以避免内存泄漏
        GameEvents.OnScoreChanged -= scoreChangedCallback;
    }

    private void OnScoreChanged(int newScore)
    {
        // 处理分数改变
    }

    // ✅ 资源管理
    private List<Object> loadedAssets = new List<Object>();

    void LoadAssetSafely<T>(string path) where T : Object
    {
        T asset = Resources.Load<T>(path);
        if (asset != null)
        {
            loadedAssets.Add(asset);
        }
    }

    void UnloadAllAssets()
    {
        foreach (Object asset in loadedAssets)
        {
            if (asset != null)
            {
                Resources.UnloadAsset(asset);
            }
        }
        loadedAssets.Clear();
    }

    // ✅ 组件访问优化
    private Transform cachedTransform;
    private Rigidbody cachedRigidbody;
    private Renderer cachedRenderer;
    private Collider cachedCollider;

    void CacheComponents()
    {
        cachedTransform = transform;
        cachedRigidbody = GetComponent<Rigidbody>();
        cachedRenderer = GetComponent<Renderer>();
        cachedCollider = GetComponent<Collider>();
    }

    void UseCachedComponents()
    {
        // 使用缓存的引用而不是每次都获取
        if (cachedTransform != null)
        {
            cachedTransform.Translate(Vector3.forward * Time.deltaTime);
        }

        if (cachedRigidbody != null)
        {
            cachedRigidbody.velocity = new Vector3(1, 0, 0);
        }
    }

    // ✅ 对象生命周期管理
    private List<System.IDisposable> disposableObjects = new List<System.IDisposable>();

    void RegisterDisposable(System.IDisposable disposable)
    {
        disposableObjects.Add(disposable);
    }

    void Cleanup()
    {
        // 清理所有可释放对象
        foreach (System.IDisposable disposable in disposableObjects)
        {
            disposable?.Dispose();
        }
        disposableObjects.Clear();
    }

    // ✅ 使用引用而不是值传递大数据结构
    void ProcessLargeData(ref PositionData data)
    {
        // 通过引用传递,避免复制大数据结构
        data.position += Vector3.one;
    }

    void OnDestroy()
    {
        Cleanup();
        UnsubscribeFromEvents();
        UnloadAllAssets();
    }
}

总结

本章我们学习了Unity中完整的项目开发实践:

2D平台跳跃游戏: 角色控制、敌人AI、关卡设计、收集系统
塔防游戏: 路径系统、防御塔、敌人波次、经济系统
RPG游戏系统: 角色成长、战斗系统、任务对话、背包商店
游戏发布流程: 构建设置、性能优化、发布清单
项目总结扩展: 项目总结、扩展建议、维护指南

这些完整的项目示例涵盖了游戏开发的各个方面,从基础的机制实现到完整的系统设计,为实际项目开发提供了全面的参考。


下一步

继续学习 09. 最佳实践