当前位置: 首页 > news >正文

深入解析:Unity笔记——Unity 封装方法指南

深入解析:Unity笔记——Unity 封装方法指南

在 Unity 开发中,良好的封装可以提高代码的可维护性、可读性和复用性。以下是几种常见的封装方法:

1. 方法封装

// 基础方法封装
public class PlayerController : MonoBehaviour
{
private float speed = 5f;
// 封装移动逻辑
private void MovePlayer()
{
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(horizontal, 0, vertical) * speed * Time.deltaTime;
transform.Translate(movement);
}
void Update()
{
MovePlayer();
}
}

2. 属性封装

// 使用属性进行封装
public class PlayerStats : MonoBehaviour
{
private int _health = 100;
// 封装健康值属性
public int Health
{
get => _health;
set
{
_health = Mathf.Clamp(value, 0, 100);
Debug.Log($"Health changed to: {_health}");
}
}
public void TakeDamage(int damage)
{
Health -= damage;
}
}

3. 组件封装

// 封装常用组件访问
public class PlayerMovement : MonoBehaviour
{
private Rigidbody _rb;
private Animator _animator;
private void Awake()
{
_rb = GetComponent();
_animator = GetComponent();
}
public void Move(Vector3 direction, float speed)
{
_rb.velocity = direction * speed;
_animator.SetBool("IsMoving", direction. Magnitude > 0);
}
}

4. 单例模式封装

// 单例模式封装
public class GameManager : MonoBehaviour
{
private static GameManager _instance;
public static GameManager Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType();
if (_instance == null)
{
GameObject obj = new GameObject();
obj.name = typeof(GameManager).Name;
_instance = obj.AddComponent();
DontDestroyOnLoad(obj);
}
}
return _instance;
}
}
private void Awake()
{
if (_instance == null)
{
_instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
// 其他游戏管理方法...
}

单例模式其实是很常见的模式,写法有很多种,这里更好的封装应该是将单例抽出来,做成基类,把让需要使用单例的类继承这个基类。

// 利用泛型给不同的子类创建单例模式
public class Singleton : MonoBehaviour where T : Singleton
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
instance = FindObjectOfType();
if (instance == null)
{
GameObject obj = new GameObject(typeof(T).Name);
instance = obj.AddComponent();
DontDestroyOnLoad(obj); // 按需持久化
}
}
return instance;
}
}
protected virtual void Awake()
{
if (instance != null)
{
GameObject.Destroy(gameObject);
}
else
{
instance = this as T;
// 按需持久化,不要在场景切换时销毁
DontDestroyOnLoad(gameObject);
}
}
}
// 在其他需要使用单例的情况下就可以继承该基类,而不用重写一个新的单例模式
public class GameManager : SingletonMono
{
protected override void Awake()
{
base. Awake();
}
}

5. 事件系统封装

// 事件系统封装
public class EventManager : MonoBehaviour
{
public delegate void PlayerDeathHandler();
public static event PlayerDeathHandler OnPlayerDeath;
public static void TriggerPlayerDeath()
{
OnPlayerDeath?.Invoke();
}
}
// 使用示例
public class Player : MonoBehaviour
{
private void Die()
{
// 玩家死亡逻辑...
EventManager.TriggerPlayerDeath();
}
}
public class UIManager : MonoBehaviour
{
private void OnEnable()
{
EventManager.OnPlayerDeath += ShowGameOverScreen;
}
private void OnDisable()
{
EventManager.OnPlayerDeath -= ShowGameOverScreen;
}
private void ShowGameOverScreen()
{
// 显示游戏结束UI
}
}

6. 脚本间通信封装(接口)

// 使用接口进行封装
public interface IDamageable
{
void TakeDamage(int amount);
}
public class Enemy : MonoBehaviour, IDamageable
{
public void TakeDamage(int amount)
{
// 敌人受伤逻辑
}
}
public class PlayerCombat : MonoBehaviour
{
private void Attack(IDamageable target)
{
target.TakeDamage(10);
}
}

7. 协程封装

// 协程方法封装
public class CoroutineUtils : MonoBehaviour
{
public static IEnumerator FadeOut(Renderer renderer, float duration)
{
Color originalColor = renderer.material.color;
float elapsed = 0f;
while (elapsed (), 2f));

实践建议

1. 单一职责原则:每个方法/类只做一件事
2. 适当的访问修饰符:使用 private/protected/public 控制访问级别
3. 参数验证:在公共方法中添加参数检查
4. 添加注释:使用 /// <summary>注释 或者 // 注释说明方法用途和参数
5. 避免过度封装:保持简单,只在必要时封装,当同一方法或者类似逻辑的实现出现第二次时就可以考虑封装该方法、将其抽象为抽象类方法 或者 考虑接口实现

良好的封装可以使你的 Unity 项目更易于维护和扩展,特别是在团队协作中。

http://www.sczhlp.com/news/2547/

相关文章:

  • ABC 415(A - E)
  • 专题:2025医疗AI落地与高端医疗险增长报告|附135份行业PDF、原始数据下载
  • [FZYZOJ6441][2024国庆集训Day1D]D
  • 专题:2025情绪经济研究报告|附29份报告PDF汇总下载
  • 专题:2025银发经济消费新势力报告|附29份PDF报告及数据下载
  • 常用的Linux命令和Docker命令以及其含义
  • java第三十一天
  • 人工智能和机器学习发展史的核心脉络
  • P9020 [USACO23JAN] Mana Collection P 题解
  • 【Google Gemini】asp.net core使用httpclient的最佳方式
  • mac+PhpWebStudy+xdebug
  • C-Stack_2025牛客暑期多校训练营6
  • wqs 二分
  • 第3章,完善MBR
  • Ubuntu 安装 Docker 的方法(基于24.04 LTS)
  • 使用CONCAT函数将查询结果组合起来
  • 我的精神状态
  • 如何安装一只QT
  • Exceptionless docker部署 仪表盘不显示日志问题
  • Detectify如何助力企业实现NIS 2和DORA合规要求
  • P8990 [北大集训 2021] 小明的树
  • 在Docker中,镜像层级压缩如何实现?
  • 在Docker中,docker commit生成的镜像和dockerfile生成镜像有什么区别?
  • 如何优化Docker镜像大小?
  • 在Docker中,本地的镜像文件都存放在哪里?
  • 我给自己请了个“AI抬杠师”,吵了半小时,爽了
  • 在Docker中,Docker容器有几种状态?
  • 在Docker中,Docker可以用来做什么?
  • 在Docker中,stage和step有什么区别?
  • 在Docker中,如何查看镜像支持的环境变量?