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

第三篇:Unity进阶阶段(商业项目能力)

目标:可参与团队商业项目开发


第12章:脚本架构设计

12.1 SOLID 设计原则

原则含义Unity示例
S - 单一职责一个类只做一件事PlayerMovement只管移动
O - 开闭原则对扩展开放,对修改关闭用interface定义IWeapon
L - 里式替换子类可替换父类Enemy继承Character
I - 接口隔离接口小而专IDamageable/IHealable分离
D - 依赖反转依赖抽象不依赖具体依赖IDataService接口

12.2 常用设计模式

// ═══ 单例模式 Singleton ═══publicclassGameManager:MonoBehaviour{publicstaticGameManagerInstance{get;privateset;}voidAwake(){if(Instance==null){Instance=this;DontDestroyOnLoad(gameObject);}elseDestroy(gameObject);}}// ═══ 观察者模式 Observer ═══publicclassHealthSystem:MonoBehaviour{publiceventAction<float>OnHealthChanged;publiceventActionOnDeath;privatefloathealth;publicvoidTakeDamage(floatdmg){health-=dmg;OnHealthChanged?.Invoke(health);if(health<=0)OnDeath?.Invoke();}}// ═══ 命令模式 Command ═══publicinterfaceICommand{voidExecute();voidUndo();}publicclassMoveCommand:ICommand{Transformtarget;Vector3from,to;publicMoveCommand(Transformt,Vector3dest){target=t;from=t.position;to=dest;}publicvoidExecute()=>target.position=to;publicvoidUndo()=>target.position=from;}// 用途:技能释放、操作撤销、录像回放// ═══ 状态机模式 State ═══publicinterfaceIState{voidEnter();voidUpdate();voidExit();}publicclassStateMachine{privateIStatecurrent;publicvoidChangeState(IStatenewState){current?.Exit();current=newState;current.Enter();}publicvoidUpdate()=>current?.Update();}// ═══ 工厂模式 Factory ═══publicstaticclassEnemyFactory{publicstaticEnemyCreate(EnemyTypetype)=>typeswitch{EnemyType.Goblin=>newGoblin(),EnemyType.Dragon=>newDragon(),_=>thrownewArgumentException()};}// ═══ 策略模式 Strategy ═══publicinterfaceIAttackStrategy{voidAttack(Transformattacker,Transformtarget);}publicclassMeleeAttack:IAttackStrategy{publicvoidAttack(...){/* 近战 */}}publicclassRangedAttack:IAttackStrategy{publicvoidAttack(...){/* 远程 */}}

12.3 Unity 常用架构

Manager模式(最常用): ├── GameManager ← 游戏流程控制 ├── UIManager ← UI管理 ├── AudioManager ← 音频管理 ├── PoolManager ← 对象池管理 ├── SaveManager ← 存档管理 └── EventManager ← 事件管理 推荐框架: ├── QFramework ← 国内主流,轻量级 ├── Zenject ← 依赖注入框架 ├── UniTask ← 异步方案(替代协程) └── UniRx ← 响应式编程

第13章:事件系统与消息通信

13.1 三种事件实现方式

// ═══ 方式1:C# event(性能最好)═══publicclassPlayer:MonoBehaviour{publiceventAction<int>OnHPChanged;publiceventActionOnDeath;publicvoidTakeDamage(intdmg){hp-=dmg;OnHPChanged?.Invoke(hp);}}// 订阅:player.OnHPChanged += UpdateHPBar;// 取消:player.OnHPChanged -= UpdateHPBar;// ═══ 方式2:UnityEvent(Inspector可视化绑定)═══[SerializeField]UnityEventonDeath;[SerializeField]UnityEvent<int>onScoreChanged;// 代码触发:onDeath.Invoke();// ═══ 方式3:EventBus(全局解耦通信)═══publicstaticclassEventBus{staticDictionary<Type,List<object>>handlers=new();publicstaticvoidSubscribe<T>(Action<T>handler){...}publicstaticvoidUnsubscribe<T>(Action<T>handler){...}publicstaticvoidPublish<T>(TeventData){...}}// 发布:EventBus.Publish(new EnemyDeadEvent { enemy = this });// 订阅:EventBus.Subscribe<EnemyDeadEvent>(OnEnemyDead);// 对比:// C# event:耦合度中,性能最好,适合组件间通信// UnityEvent:可视化配置,适合UI交互// EventBus:完全解耦,适合跨系统通信

第14章:对象池系统

14.1 为什么需要对象池

Instantiate/Destroy 的问题: 1. 每次创建都分配内存 → GC频繁 → 卡顿 2. 内存碎片化 → 内存效率下降 3. 创建/销毁开销 → 帧率下降 对象池方案: 预先创建 → 用时激活 → 用完回收 → 循环复用

14.2 Unity 内置 ObjectPool

usingUnityEngine.Pool;// Unity 2021+ 内置对象池ObjectPool<GameObject>bulletPool=newObjectPool<GameObject>(createFunc:()=>Instantiate(bulletPrefab),// 创建actionOnGet:obj=>obj.SetActive(true),// 取出时actionOnRelease:obj=>obj.SetActive(false),// 归还时actionOnDestroy:obj=>Destroy(obj),// 销毁时collectionCheck:true,// 防重复归还defaultCapacity:20,// 默认容量maxSize:50// 最大容量);// 使用GameObjectbullet=bulletPool.Get();// 取出bulletPool.Release(bullet);// 归还

14.3 自定义通用对象池

publicclassPoolManager:MonoBehaviour{publicstaticPoolManagerInstance;privateDictionary<string,Queue<GameObject>>pools=new();privateDictionary<string,GameObject>prefabs=new();publicvoidRegisterPool(stringkey,GameObjectprefab,intinitSize){prefabs[key]=prefab;pools[key]=newQueue<GameObject>();for(inti=0;i<initSize;i++){varobj=Instantiate(prefab);obj.SetActive(false);pools[key].Enqueue(obj);}}publicGameObjectSpawn(stringkey,Vector3pos,Quaternionrot){GameObjectobj;if(pools[key].Count>0)obj=pools[key].Dequeue();elseobj=Instantiate(prefabs[key]);obj.transform.SetPositionAndRotation(pos,rot);obj.SetActive(true);returnobj;}publicvoidRecycle(stringkey,GameObjectobj){obj.SetActive(false);pools[key].Enqueue(obj);}}

第15章:存档与数据持久化

15.1 PlayerPrefs(简单存储)

// 存储(只支持 int/float/string)PlayerPrefs.SetInt("HighScore",9999);PlayerPrefs.SetFloat("MusicVolume",0.8f);PlayerPrefs.SetString("PlayerName","Alice");PlayerPrefs.Save();// 确保写入磁盘// 读取(带默认值)intscore=PlayerPrefs.GetInt("HighScore",0);// 删除PlayerPrefs.DeleteKey("HighScore");PlayerPrefs.DeleteAll();// ⚠️ 缺点:无加密、容量小、不适合复杂数据

15.2 JSON 存档

[System.Serializable]publicclassSaveData{publicstringplayerName;publicintlevel;publicfloathp;publicList<string>inventory;publicVector3Serializableposition;}// Vector3不能直接序列化,需要包装[System.Serializable]publicstructVector3Serializable{publicfloatx,y,z;publicVector3Serializable(Vector3v){x=v.x;y=v.y;z=v.z;}publicVector3ToVector3()=>newVector3(x,y,z);}// 保存publicstaticvoidSave(SaveDatadata){stringjson=JsonUtility.ToJson(data,true);// true=格式化stringpath=Path.Combine(Application.persistentDataPath,"save.json");File.WriteAllText(path,json);}// 加载publicstaticSaveDataLoad(){stringpath=Path.Combine(Application.persistentDataPath,"save.json");if(!File.Exists(path))returnnewSaveData();stringjson=File.ReadAllText(path);returnJsonUtility.FromJson<SaveData>(json);}

15.3 AES 加密存档

usingSystem.Security.Cryptography;usingSystem.IO;usingSystem.Text;publicstaticclassEncryptedSave{privatestaticreadonlystringkey="1234567890ABCDEF";// 16字节密钥privatestaticreadonlystringiv="ABCDEF1234567890";// 16字节IVpublicstaticvoidSaveEncrypted(SaveDatadata){stringjson=JsonUtility.ToJson(data);byte[]encrypted=Encrypt(Encoding.UTF8.GetBytes(json));stringpath=Path.Combine(Application.persistentDataPath,"save.dat");File.WriteAllBytes(path,encrypted);}staticbyte[]Encrypt(byte[]data){usingvaraes=Aes.Create();aes.Key=Encoding.UTF8.GetBytes(key);aes.IV=Encoding.UTF8.GetBytes(iv);usingvarenc=aes.CreateEncryptor();returnenc.TransformFinalBlock(data,0,data.Length);}}

第16章:AI 与寻路系统

16.1 NavMesh 导航

usingUnityEngine.AI;// NavMeshAgent 组件NavMeshAgentagent=GetComponent<NavMeshAgent>();agent.speed=5f;agent.stoppingDistance=1f;// 停止距离agent.destination=targetPos;// 设置目标位置// 检查是否到达if(!agent.pathPending&&agent.remainingDistance<agent.stoppingDistance)Debug.Log("到达目标!");// 烘焙NavMesh:Window → AI → Navigation → Bake

16.2 有限状态机 FSM

publicclassEnemyAI:MonoBehaviour{enumAIState{Patrol,Chase,Attack,Flee}AIStatestate=AIState.Patrol;voidUpdate(){floatdistToPlayer=Vector3.Distance(transform.position,player.position);switch(state){caseAIState.Patrol:PatrolBehavior();if(distToPlayer<detectRange)state=AIState.Chase;break;caseAIState.Chase:agent.destination=player.position;if(distToPlayer<attackRange)state=AIState.Attack;if(distToPlayer>loseRange)state=AIState.Patrol;break;caseAIState.Attack:AttackBehavior();if(distToPlayer>attackRange)state=AIState.Chase;if(hp<maxHP*0.2f)state=AIState.Flee;break;caseAIState.Flee:Vector3fleeDir=(transform.position-player.position).normalized;agent.destination=transform.position+fleeDir*10f;break;}}}

16.3 行为树概念

行为树节点类型: ├── Composite(组合节点) │ ├── Sequence:顺序执行,全成功才成功(AND) │ ├── Selector:选择执行,一个成功就成功(OR) │ └── Parallel:并行执行 ├── Decorator(装饰节点) │ ├── Inverter:结果取反 │ └── Repeater:重复执行 └── Leaf(叶节点) ├── Action:执行动作(移动/攻击/拾取) └── Condition:判断条件(是否看到敌人/HP是否低)

第17章:Editor 扩展开发

17.1 Custom Inspector

usingUnityEditor;[CustomEditor(typeof(EnemyConfig))]publicclassEnemyConfigEditor:Editor{publicoverridevoidOnInspectorGUI(){EnemyConfigconfig=(EnemyConfig)target;EditorGUILayout.LabelField("敌人配置",EditorStyles.boldLabel);config.enemyName=EditorGUILayout.TextField("名称",config.enemyName);config.hp=EditorGUILayout.IntSlider("HP",config.hp,1,1000);if(config.hp<100)EditorGUILayout.HelpBox("HP过低!",MessageType.Warning);if(GUILayout.Button("重置默认值"))config.ResetDefaults();if(GUI.changed)EditorUtility.SetDirty(config);}}

17.2 Editor Window

publicclassMyToolWindow:EditorWindow{[MenuItem("Tools/My Tool Window")]publicstaticvoidShowWindow(){GetWindow<MyToolWindow>("我的工具");}voidOnGUI(){GUILayout.Label("自定义工具窗口",EditorStyles.boldLabel);if(GUILayout.Button("执行操作"))Debug.Log("按钮被点击");}}

17.3 Gizmos

// 在Scene视图中绘制调试信息voidOnDrawGizmosSelected(){Gizmos.color=Color.red;Gizmos.DrawWireSphere(transform.position,attackRange);// 攻击范围Gizmos.color=Color.yellow;Gizmos.DrawWireSphere(transform.position,detectRange);// 检测范围}

http://www.jsqmd.com/news/696456/

相关文章:

  • AI查看文档001
  • 2026年Q2西南水晶标优质服务商排行榜:四川PVC工作牌公司、四川PVC工作证公司、四川UV水晶标公司、四川工作牌公司选择指南 - 优质品牌商家
  • 杀戮尖塔2 MOD与修改器介绍
  • 遇到新问题怎么办?AI 的“抄作业“大法
  • 弄懂这56个Python使用技巧(轻松掌握Python高效开发)
  • 2026Q2正宗牛华麻辣烫品牌推荐指南:乐山麻辣烫加盟、乐山麻辣烫哪家好吃、乐山麻辣烫哪家正宗、乐山麻辣烫店、乐山麻辣烫推荐店铺选择指南 - 优质品牌商家
  • 2026年评价高的全程扶持养生馆加盟/零经验养生馆加盟榜单优选公司 - 品牌宣传支持者
  • Agent 编排从“提示词地狱”到“图结构确定性”:五大模式突破多代理生产瓶颈的实战路径
  • 别再死记硬背圣维南方程了!用MIKE11水动力模块的视角,重新理解河道模拟的底层逻辑
  • Qwen3-4B-Instruct基础教程:torch29环境激活、pip扩展依赖安装详解
  • Windows无法完成安装。若要在此计算机上安装Windows,请重新启动安装
  • 2026年水泥电杆优质推荐榜:水泥电线杆底盘/水泥电线杆拉盘/水泥电线杆配件/电力工程水泥电线杆/线路改造水泥电线杆/选择指南 - 优质品牌商家
  • 2026硅PU施工优质服务商TOP5推荐:全塑型塑胶跑道/塑胶跑道施工/塑胶跑道材料/复合型塑胶跑道/学校塑胶跑道/选择指南 - 优质品牌商家
  • 如何隐藏phpMyAdmin的真实访问路径_修改Alias或重命名目录以防止暴力破解
  • WeDLM-7B-Base媒体落地:短视频脚本初稿生成与多平台风格适配案例
  • 用通达信时间函数打造你的‘盘面时钟’:实时监控开盘时长与交易时段
  • 跨境企业破局通信难题:国际物联网卡+定制物联网方案,赋能全球业务落地
  • B站会员购抢票神器:新手也能快速上手的终极购票指南
  • Fairseq-Dense-13B-Janeway作品集:基于经典IP语感模仿的英文续写成果(非侵权学习用途)
  • Windows 11任务栏拖放功能终极修复指南:开源解决方案完全解析
  • 2026年知名的高利润养生馆加盟/一站式养生馆加盟/养生馆加盟/零经验养生馆加盟热门公司推荐 - 行业平台推荐
  • econgnition精度评价四种统计方法
  • AGENTS.md 文件的真实效能差距:为什么 80% 的写法反而拖累 AI 编码 Agent?Augment 内部基准拆解路径
  • 天下苦Token久矣,DeepSeekV4终于来了!
  • 鲸采云 SaaS版:企业数字化转型最优解,不限行业、即开即用
  • 【论文阅读】World-Value-Action Model: Implicit Planning for Vision-Language-Action Systems
  • C++面向对象编程:从封装到实战
  • 机器学习算法迷你课程:从原理到实战
  • 选择数学高中问题
  • DOC/DOCX转TXT工具:功能详解与使用指南