【Unity知识扫盲】最常用高级进阶概念

高级进阶知识体系架构介绍

1. 对象池 (Object Pool)

避免频繁创建/销毁对象,提升性能。

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 = Object.Instantiate(prefab, parent);
            obj.gameObject.SetActive(false);
            pool.Enqueue(obj);
        }
    }
    public T Get() {
        if (pool.Count > 0) {
            T obj = pool.Dequeue();
            obj.gameObject.SetActive(true);
            return obj;
        }
        return Object.Instantiate(prefab, parent);
    }    
    public void Return(T obj) {
        obj.gameObject.SetActive(false);
        pool.Enqueue(obj);
    }
}
// 使用
ObjectPool<Bullet> bulletPool = new ObjectPool<Bullet>(bulletPrefab, 50);
Bullet bullet = bulletPool.Get();
bulletPool.Return(bullet);
2. ScriptableObject - 数据驱动设计
// 定义数据资源
[CreateAssetMenu(fileName = "WeaponData", menuName = "Game/Weapon")]
public class WeaponData : ScriptableObject {
    public string weaponName;
    public int damage;
    public float fireRate;
    public Sprite icon;    
    [TextArea(3, 10)]
    public string description;   
    // 可以包含方法
    public void Fire() {
        Debug.Log($"{weaponName} 开火!伤害: {damage}");
    }
}
// 使用
public class WeaponController : MonoBehaviour {
    public WeaponData weaponData;    
    void Fire() {
        weaponData.Fire();
    }
}

优势:
📦 数据与逻辑分离
🔄 运行时共享数据,节省内存
✏️ 可在Inspector直接编辑
💾 可作为资源持久化

3. 委托、事件、UnityEvent - 解耦系统
// 1. C# 委托和事件(性能最好)
public class EventManager {
    public delegate void GameEvent(int value);
    public static event GameEvent OnScoreChanged;
    public static event Action OnGameOver;
    public static event Action<GameObject, int> OnDamage;    
    public static void TriggerScoreChanged(int score) {
        OnScoreChanged?.Invoke(score);
    }
}
// 订阅
void OnEnable() {
    EventManager.OnScoreChanged += HandleScoreChanged;
}
void OnDisable() {
    EventManager.OnScoreChanged -= HandleScoreChanged;  // ⚠️ 必须取消订阅!
}
void HandleScoreChanged(int score) {
    Debug.Log($"分数: {score}");
}
// 2. UnityEvent(可在Inspector配置)
[System.Serializable]
public class CustomEvent : UnityEvent<int, string> { }
public class UIController : MonoBehaviour {
    public UnityEvent onStart;
    public UnityEvent<int> onScoreChanged;
    public CustomEvent onCustomEvent;    
    void Start() {
        onStart?.Invoke();
        onScoreChanged?.Invoke(100);
    }
}
// 3. 高级事件总线
public class EventBus {
    private static Dictionary<Type, List<Delegate>> eventDict = new Dictionary<Type, List<Delegate>>();    
    public static void Subscribe<T>(Action<T> listener) where T : struct {
        Type eventType = typeof(T);
        if (!eventDict.ContainsKey(eventType)) {
            eventDict[eventType] = new List<Delegate>();
        }
        eventDict[eventType].Add(listener);
    }
    public static void Publish<T>(T eventData) where T : struct {
        Type eventType = typeof(T);
        if (eventDict.ContainsKey(eventType)) {
            foreach (var listener in eventDict[eventType]) {
                (listener as Action<T>)?.Invoke(eventData);
            }
        }
    }
}
// 使用
public struct PlayerDiedEvent {
    public int playerId;
    public Vector3 position;
}
EventBus.Subscribe<PlayerDiedEvent>(OnPlayerDied);
EventBus.Publish(new PlayerDiedEvent { playerId = 1, position = transform.position });
4. Jobs System + Burst Compiler - 多线程优化
using Unity.Jobs;
using Unity.Collections;
using Unity.Burst;
// 定义Job
[BurstCompile]
public struct VelocityJob : IJobParallelFor {
    public NativeArray<Vector3> positions;
    public NativeArray<Vector3> velocities;
    public float deltaTime;    
    public void Execute(int index) {
        positions[index] += velocities[index] * deltaTime;
    }
}
// 使用
void Update() {
    NativeArray<Vector3> positions = new NativeArray<Vector3>(1000, Allocator.TempJob);
    NativeArray<Vector3> velocities = new NativeArray<Vector3>(1000, Allocator.TempJob);    
    // 初始化数据...    
    VelocityJob job = new VelocityJob {
        positions = positions,
        velocities = velocities,
        deltaTime = Time.deltaTime
    };    
    JobHandle handle = job.Schedule(positions.Length, 64);
    handle.Complete();    
    // 使用结果...    
    positions.Dispose();
    velocities.Dispose();
}
5. ECS (Entity Component System) - DOTS
using Unity.Entities;
using Unity.Transforms;
using Unity.Mathematics;
// 组件(纯数据)
public struct MovementSpeed : IComponentData {
    public float Value;
}
// 系统(纯逻辑)
public partial class MovementSystem : SystemBase {
    protected override void OnUpdate() {
        float deltaTime = Time.DeltaTime;        
        Entities.ForEach((ref Translation translation, in MovementSpeed speed) => {
            translation.Value.y += speed.Value * deltaTime;
        }).ScheduleParallel();
    }
}
// 创建Entity
EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
Entity entity = entityManager.CreateEntity(typeof(Translation), typeof(MovementSpeed));
entityManager.SetComponentData(entity, new MovementSpeed { Value = 5f });
6. Addressables - 资源管理系统
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class ResourceLoader : MonoBehaviour {
    // 通过地址加载
    async void LoadAsset() {
        var handle = Addressables.LoadAssetAsync<GameObject>("Assets/Prefabs/Enemy.prefab");
        await handle.Task;        
        if (handle.Status == AsyncOperationStatus.Succeeded) {
            GameObject prefab = handle.Result;
            Instantiate(prefab);
        }
    }    
    // 通过引用加载(可在Inspector配置)
    public AssetReference assetReference;    
    async void LoadReference() {
        var handle = assetReference.LoadAssetAsync<GameObject>();
        await handle.Task;
        GameObject obj = handle.Result;        
        // 实例化
        await Addressables.InstantiateAsync(assetReference);        
        // 释放
        Addressables.Release(handle);
    }    
    // 加载场景
    async void LoadScene() {
        await Addressables.LoadSceneAsync("GameScene").Task;
    }
}
7. Compute Shader - GPU计算
// ComputeShader代码(.compute文件)
#pragma kernel CSMain

RWStructuredBuffer<float3> positions;
float deltaTime;
	
[numthreads(256,1,1)]
void CSMain (uint3 id : SV_DispatchThreadID) {
    positions[id.x].y += sin(positions[id.x].x + deltaTime) * 0.1;
}
// C# 调用
public class ComputeController : MonoBehaviour {
    public ComputeShader computeShader;
    private ComputeBuffer buffer;    
    void Start() {
        Vector3[] data = new Vector3[1000];
        buffer = new ComputeBuffer(data.Length, sizeof(float) * 3);
        buffer.SetData(data);        
        int kernel = computeShader.FindKernel("CSMain");
        computeShader.SetBuffer(kernel, "positions", buffer);
    }    
    void Update() {
        int kernel = computeShader.FindKernel("CSMain");
        computeShader.SetFloat("deltaTime", Time.time);
        computeShader.Dispatch(kernel, 1000 / 256, 1, 1);        
        Vector3[] results = new Vector3[1000];
        buffer.GetData(results);
    }   
    void OnDestroy() {
        buffer?.Release();
    }
}
8. 自定义编辑器
#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(WeaponController))]
public class WeaponControllerEditor : Editor {
    public override void OnInspectorGUI() {
        WeaponController weapon = (WeaponController)target;        
        // 自定义布局
        EditorGUILayout.LabelField("武器配置", EditorStyles.boldLabel);
        weapon.damage = EditorGUILayout.IntSlider("伤害", weapon.damage, 0, 100);        
        // 自定义按钮
        if (GUILayout.Button("测试开火")) {
            weapon.Fire();
        }        
        // 显示默认Inspector
        DrawDefaultInspector();        
        // 标记脏数据(保存修改)
        if (GUI.changed) {
            EditorUtility.SetDirty(target);
        }
    }
}
// 自定义属性绘制器
[CustomPropertyDrawer(typeof(RangeInt))]
public class RangeIntDrawer : PropertyDrawer {
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
        // 自定义绘制逻辑
    }
}
#endif
9. Shader编程
Shader "Custom/ToonShader" {
    Properties {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _RampTex ("Ramp Texture", 2D) = "white" {}
    }    
    SubShader {
        Tags { "RenderType"="Opaque" }        
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"            
            struct appdata {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };            
            struct v2f {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 worldNormal : TEXCOORD1;
            };
            
            sampler2D _MainTex;
            sampler2D _RampTex;
            float4 _Color;            
            v2f vert (appdata v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                return o;
            }            
            fixed4 frag (v2f i) : SV_Target {
                float3 lightDir = _WorldSpaceLightPos0.xyz;
                float NdotL = dot(normalize(i.worldNormal), lightDir);
                float lightIntensity = smoothstep(0, 0.01, NdotL);                
                fixed4 col = tex2D(_MainTex, i.uv) * _Color;
                col.rgb *= lightIntensity;
                return col;
            }
            ENDCG
        }
    }
}
10. 反射与特性 (Attributes)
// 自定义特性
[AttributeUsage(AttributeTargets.Field)]
public class ReadOnlyAttribute : PropertyAttribute { }
// 使用特性
public class GameManager : MonoBehaviour {
    [SerializeField] private int score;
    [HideInInspector] public int hiddenValue;
    [ReadOnly] public float readOnlyValue;
    [Range(0, 100)] public int health = 100;
    [Header("武器设置")]
    [Tooltip("武器伤害值")]
    public int damage;    
    [ContextMenu("重置分数")]
    void ResetScore() {
        score = 0;
    }
}
// 反射使用
public class ReflectionExample {
    void GetAllComponents(GameObject obj) {
        Component[] components = obj.GetComponents<Component>();        
        foreach (var comp in components) {
            Type type = comp.GetType();
            Debug.Log($"组件: {type.Name}");            
            // 获取所有字段
            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            foreach (var field in fields) {
                object value = field.GetValue(comp);
                Debug.Log($"  {field.Name} = {value}");
            }            
            // 调用方法
            MethodInfo method = type.GetMethod("Start", BindingFlags.NonPublic | BindingFlags.Instance);
            method?.Invoke(comp, null);
        }
    }
}
11. 异步编程 (async/await)
using System.Threading.Tasks;
using UnityEngine.Networking;
public class AsyncExample : MonoBehaviour {
    // 异步加载
    async Task<Texture2D> LoadImageAsync(string url) {
        using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(url)) {
            var operation = request.SendWebRequest();            
            while (!operation.isDone) {
                await Task.Yield();  // 等待下一帧
            }            
            if (request.result == UnityWebRequest.Result.Success) {
                return DownloadHandlerTexture.GetContent(request);
            }
            return null;
        }
    }    
    // 延迟执行
    async Task DelayedAction(float seconds) {
        await Task.Delay((int)(seconds * 1000));
        Debug.Log("延迟完成");
    }    
    // 并发执行
    async Task LoadMultipleResources() {
        Task<Texture2D> task1 = LoadImageAsync("url1");
        Task<Texture2D> task2 = LoadImageAsync("url2");
        Task<Texture2D> task3 = LoadImageAsync("url3");        
        await Task.WhenAll(task1, task2, task3);        
        Debug.Log("所有资源加载完成");
    }    
    // UniTask(更好的Unity异步方案)
    // using Cysharp.Threading.Tasks;
    
    // async UniTask LoadWithUniTask() {
    //     await UniTask.Delay(1000);
    //     var texture = await Resources.LoadAsync<Texture2D>("icon").ToUniTask();
    // }
}
12. 性能优化技巧
public class OptimizationTips : MonoBehaviour {
    // 避免在Update中频繁查找
    void Update_Bad() {
        GameObject.Find("Player").transform.position = Vector3.zero;
        GetComponent<Rigidbody>().velocity = Vector3.up;
    }    
    // 缓存引用
    private Transform playerTransform;
    private Rigidbody rb;    
    void Start() {
        playerTransform = GameObject.Find("Player").transform;
        rb = GetComponent<Rigidbody>();
    }    
    void Update_Good() {
        playerTransform.position = Vector3.zero;
        rb.velocity = Vector3.up;
    }    
    // 使用CompareTag而不是字符串比较
    void OnTriggerEnter(Collider other) {
        if (other.CompareTag("Player")) { }  // 快
        // if (other.tag == "Player") { }    // 慢
    }    
    // 避免空引用检查的GC
    void NullCheck() {
        // if (obj != null) { }  // 会调用Unity的==重载,有GC
        if (obj) { }             // 更快
        if (!(obj is null)) { }  // C# 7.0+
    }    
    // 使用StringBuilder
    void StringOperations() {
        // string result = "";
        // for (int i = 0; i < 100; i++) {
        //     result += i.ToString();  // 产生大量GC
        // }        
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        for (int i = 0; i < 100; i++) {
            sb.Append(i);  // 无GC
        }
        string result = sb.ToString();
    }
}
13. 设计模式在Unity中的应用
// 单例模式
public class GameManager : MonoBehaviour {
    private static GameManager _instance;
    public static GameManager Instance {
        get {
            if (_instance == null) {
                _instance = FindObjectOfType<GameManager>();
                if (_instance == null) {
                    GameObject obj = new GameObject("GameManager");
                    _instance = obj.AddComponent<GameManager>();
                }
            }
            return _instance;
        }
    }    
    void Awake() {
        if (_instance != null && _instance != this) {
            Destroy(gameObject);
            return;
        }
        _instance = this;
        DontDestroyOnLoad(gameObject);
    }
}
// 命令模式
public interface ICommand {
    void Execute();
    void Undo();
}
public class MoveCommand : ICommand {
    private Transform transform;
    private Vector3 displacement;
    private Vector3 previousPosition;    
    public MoveCommand(Transform transform, Vector3 displacement) {
        this.transform = transform;
        this.displacement = displacement;
    }    
    public void Execute() {
        previousPosition = transform.position;
        transform.position += displacement;
    }    
    public void Undo() {
        transform.position = previousPosition;
    }
}
// 状态机模式
public interface IState {
    void Enter();
    void Update();
    void Exit();
}
public class StateMachine {
    private IState currentState;    
    public void ChangeState(IState newState) {
        currentState?.Exit();
        currentState = newState;
        currentState?.Enter();
    }   
    public void Update() {
        currentState?.Update();
    }
}
// 工厂模式
public class EnemyFactory {
    public Enemy CreateEnemy(EnemyType type) {
        return type switch {
            EnemyType.Zombie => new Zombie(),
            EnemyType.Skeleton => new Skeleton(),
            _ => null
        };
    }
}

高级进阶知识总结

Unity高级进阶架构
├─ 🔥 对象池 (必须掌握)
├─ 🔥 ScriptableObject (数据驱动)
├─ 🔥 事件系统 (解耦架构)
├─ ⚡ Jobs System (多线程)
├─ ⚡ ECS/DOTS (未来架构)
├─ 📦 Addressables (资源管理)
├─ 💻 Compute Shader (GPU计算)
├─ 🎨 自定义Editor (工具开发)
├─ 🎭 Shader编程 (图形渲染)
├─ 🪞 反射与特性 (元编程)
├─ ⏱️ 异步编程 (async/await)
├─ 🚀 性能优化 (profiling)
└─ 🏗️ 设计模式 (架构设计)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值