Unity 代理模式(实例详解)

文章目录

      • 实例1:资源加载代理(Asset Loading Proxy)
      • 实例2:网络请求代理(Network Request Proxy)
      • 实例3:性能优化代理(Performance Optimization Proxy)
      • 实例4:权限控制代理(Authorization Control Proxy)
      • 实例5:热更新代理(Hot Reload Proxy)

在Unity游戏开发中,代理模式(Proxy Design Pattern)用于为另一个对象提供一个代理以控制对这个对象的访问。以下是在Unity环境下实现代理模式的5个不同代码实例说明:

实例1:资源加载代理(Asset Loading Proxy)

// 原始资源加载接口
public interface IResourceLoader
{
    Texture2D LoadTexture(string path);
}

// 真实资源加载器
public class RealResourceLoader : IResourceLoader
{
    public Texture2D LoadTexture(string path)
    {
        return Resources.Load<Texture2D>(path);
    }
}

// 资源加载代理,负责异步加载并缓存资源
public class AssetLoadingProxy : IResourceLoader
{
    private Dictionary<string, IEnumerator> _loadingTasks;
    private RealResourceLoader _realLoader;

    public AssetLoadingProxy()
    {
        _loadingTasks = new Dictionary<string, IEnumerator>();
        _realLoader = new RealResourceLoader();
    }

    public IEnumerator LoadTextureAsync(string path, Action<Texture2D> onLoaded)
    {
        if (!_loadingTasks.ContainsKey(path))
        {
            var www = UnityWebRequestTexture.GetTexture(path);
            yield return www.SendWebRequest();

            if (www.result == UnityWebRequest.Result.Success)
            {
                var texture = DownloadHandlerTexture.GetContent(www);
                _loadingTasks[path] = null; // 移除任务记录,避免重复加载
                onLoaded?.Invoke(texture);
            }
            else
            {
                Debug.LogError($"Failed to load texture: {www.error}");
            }
        }
        else
        {
            while (_loadingTasks[path] != null)
            {
                yield return null; // 等待资源完成加载
            }
            onLoaded?.Invoke(_realLoader.LoadTexture(path)); // 加载完成后调用回调
        }
    }
}

实例2:网络请求代理(Network Request Proxy)

// 网络请求接口
public interface INetworkService
{
    void SendRequest(string url, Action<string> onResponse);
}

// 真实网络服务类
public class RealNetworkService : INetworkService
{
    public void SendRequest(string url, Action<string> onResponse)
    {
        StartCoroutine(SendRequestCoroutine(url, onResponse));
    }

    private IEnumerator SendRequestCoroutine(string url, Action<string> onResponse)
    {
        using (var request = UnityWebRequest.Get(url))
        {
            yield return request.SendWebRequest();

            if (request.result == UnityWebRequest.Result.Success)
            {
                onResponse(request.downloadHandler.text);
            }
            else
            {
                Debug.LogError($"Error sending network request: {request.error}");
            }
        }
    }
}

// 网络请求代理,添加了请求队列和错误重试机制
public class NetworkRequestProxy : INetworkService
{
    private INetworkService _realService;
    private Queue<Action> _requestQueue;
    private int _maxRetryCount;

    public NetworkRequestProxy(INetworkService realService, int maxRetries)
    {
        _realService = realService;
        _requestQueue = new Queue<Action>();
        _maxRetryCount = maxRetries;
    }

    public void SendRequest(string url, Action<string> onResponse)
    {
        _requestQueue.Enqueue(() => _realService.SendRequest(url, response =>
        {
            if (!string.IsNullOrEmpty(response) || --_maxRetryCount < 0)
            {
                onResponse(response);
            }
            else
            {
                SendRequest(url, onResponse); // 重试请求
            }
        }));

        ProcessNextRequest(); // 开始处理队列中的下一个请求
    }

    private void ProcessNextRequest()
    {
        if (_requestQueue.Count > 0)
        {
            var nextAction = _requestQueue.Dequeue();
            StartCoroutine(ProcessRequestCoroutine(nextAction));
        }
    }

    private IEnumerator ProcessRequestCoroutine(Action action)
    {
        yield return new WaitForSeconds(0.1f); // 假设这里有防止频繁请求的间隔
        action();
    }
}

实例3:性能优化代理(Performance Optimization Proxy)

// 高级图形渲染组件接口
public interface IAdvancedRenderer
{
    void RenderHighQualityMesh(Mesh mesh);
}

// 真实高级渲染组件
public class RealAdvancedRenderer : IAdvancedRenderer
{
    public void RenderHighQualityMesh(Mesh mesh)
    {
        // 执行高质量、高消耗的渲染操作
        // ...
    }
}

// 性能优化代理,根据设备性能动态调整渲染质量
public class PerformanceProxyRenderer : IAdvancedRenderer
{
    private IAdvancedRenderer _realRenderer;
    private bool _isLowEndDevice;

    public PerformanceProxyRenderer(IAdvancedRenderer realRenderer, SystemInfo systemInfo)
    {
        _realRenderer = realRenderer;
        _isLowEndDevice = systemInfo.graphicsMemorySize < 1024; // 假设低于1GB显存的设备是低端设备
    }

    public void RenderHighQualityMesh(Mesh mesh)
    {
        if (!_isLowEndDevice)
        {
            _realRenderer.RenderHighQualityMesh(mesh);
        }
        else
        {
            // 执行低质量、低消耗的替代渲染操作
            RenderLowQualityMesh(mesh);
        }
    }

    private void RenderLowQualityMesh(Mesh mesh)
    {
        // ...
    }
}

实例4:权限控制代理(Authorization Control Proxy)

// 数据库访问接口
public interface IDataAccess
{
    void SaveData(UserData data);
}

// 真实数据库访问类
public class RealDataAccess : IDataAccess
{
    public void SaveData(UserData data)
    {
        // 存储用户数据到数据库
        // ...
    }
}

// 权限控制代理,确保只有管理员可以写入数据
public class AuthorizationProxy : IDataAccess
{
    private IDataAccess _realAccess;
    private IUserService _userService;

    public AuthorizationProxy(IDataAccess realAccess, IUserService userService)
    {
        _realAccess = realAccess;
        _userService = userService;
    }

    public void SaveData(UserData data)
    {
        if (_userService.IsCurrentUserAdmin())
        {
            _realAccess.SaveData(data);
        }
        else
        {
            Debug.LogWarning("Non-admin user attempted to save data.");
        }
    }
}

实例5:热更新代理(Hot Reload Proxy)

// MonoBehavior基类
public abstract class MonoBehaviourBase : UnityEngine.MonoBehaviour
{
    // 公共方法声明...
}

// 热更脚本接口
public interface IHotReloadable
{
    void OnHotReload();
}

// 热更代理MonoBehavior
public class HotReloadProxy : MonoBehaviourBase
{
    private IHotReloadable _hotReloadTarget;

    public void SetHotReloadTarget(IHotReloadable target)
    {
        _hotReloadTarget = target;
    }

    void Update()
    {
        // 如果目标实现了热更接口,则在Update时触发OnHotReload
        if (_hotReloadTarget != null && Application.isEditor && UnityEditor.EditorUtility.IsDirty(targetScript))
        {
            _hotReloadTarget.OnHotReload();
        }
    }
}

// 真实业务逻辑脚本,通过ILRuntime或类似技术热更新
[HotReloading]
public class RealBusinessLogic : IHotReloadable
{
    public void OnHotReload()
    {
        // 重新加载业务逻辑
        // ...
    }

    // 其他业务逻辑...
}

这些例子展示了如何在Unity中使用代理模式来解决资源管理、网络请求、性能优化、权限控制以及热更新等场景下的问题。每个代理类都封装了一个真实对象,并提供了额外的功能或控制层。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

你可能感兴趣的:(unity,C#设计模式详解,unity,代理模式,游戏引擎)