Unity游戏开发 基于多线程的Http网络框架完整篇

Unity游戏开发 基于多线程的Http网络框架基础篇 基本思路: HttpClient: HttpManager: 阅读详情

这篇主要是提供完整的代码。。。注释较少请见谅,如果对流程有疑惑可以参考**《Unity游戏开发 基于多线程的Http网络框架基础篇》

完整篇除了基础篇讲到的内容之外,出于对性能和安全性的考虑还覆盖了如下内容:

单例:(BaseController)

       **关于单例请参考《Unity游戏开发 单例基类》

对象池: (Poolable、PoolManager)

加密:(Encry)

这些内容后续有时间写的话会把链接放上来,目前把所有代码贴出来主要是方便直接拷贝就可以使用了。

在更完整的版本里还有一个事件分发的处理,后续如果有时间写UI框架的话会把这块关联起来。

目录

使用示例

HttpManager(http管理器)

HttpClient(http核心逻辑)

HttpPack(http数据包)

BlockQueue(多线程队列)

Encry(加密)

BaseController(单例)

Poolable(对象池之可缓存对象)

PoolManager(对象池管理器)



使用示例

void Start()
{
    // 发起请求
    HttpManager.instance.HttpPost(1, "http://es.dota2.uuu9.com/players", false);
}

int id = 0; int code = 0; string data = "";
void Update()
{
    // 从接受队列取得消息(此处本来是和lua的http模块以及ui框架结合做错误码处理以及网络事件分发的)
    if(HttpManager.instance.TryGetResPonse(ref id, ref code, ref data))
    {
        UnityEngine.Debug.LogError(data);
    }
}

这里加密传了false,如果传入true的话会将返回的消息用Encry模块去解密。

这个需要服务器的配合,两边约定好加密的密钥。

目前只是对接收到的数据进行了解密处理,如果有需要的话也可以和服务器做协商,在发送的json参数中用某个字段将实际游戏中用到的参数通过Encry加密后保存起来发送给服务器,服务器解密后再做处理。

HttpManager(http管理器)

using System.Text;

public enum HttpType
{
    Get,
    Post,
}

public class HttpManager : BaseController<HttpManager>
{
    private HttpClient _httpClient = new HttpClient();
    private StringBuilder _getBuilder = new StringBuilder();

    public void HttpGet(int key, string url, bool encry, string param = null)
    {
        _getBuilder.Clear();
        _getBuilder.Append(url);
        if (param != null)
        {
            _getBuilder.Append("?");
            _getBuilder.Append(param);
        }
        _httpClient.AddHttpReq(key, HttpType.Get, _getBuilder.ToString(), encry);
    }

    public void HttpPost(int key, string url, bool encry, string param = null)
    {
        _getBuilder.Clear();
        _getBuilder.Append(url);
        _httpClient.AddHttpReq(key, HttpType.Post, _getBuilder.ToString(), encry, param);
    }

    public bool TryGetResPonse(ref int key, ref int code, ref string data)
    {
        HttpPack pack;
        if (_httpClient.TryGetResponse(out pack))
        {
            key = pack.key;
            code = pack.code;
            data = pack.response;
            pack.Dispose();
            return true;
        }
        return false;
    }
}

HttpClient(http核心逻辑)

using System.Net;
using System.Text;
using System.IO;
using System.Threading;
using System;

public class HttpClient
{
    private Encry _encry = new Encry("testkey");
    private Thread _sendTask;

    private BlockQueue<HttpPack> _sendList = new BlockQueue<HttpPack>(10);
    private BlockQueue<HttpPack> _receiveList = new BlockQueue<HttpPack>(10);

    #region 外部接口
    public bool TryGetResponse(out HttpPack pack)
    {
        if (_receiveList.count > 0)
        {
            pack = _receiveList.Dequeue();
            return true;
        }
        else
        {
            pack = null;
            return false;
        }
    }

    public void AddHttpReq(int key, HttpType type, string url, bool encry, string param = null)
    {
        HttpPack pack = HttpPack.GetPooled();
        pack.key = key;
        pack.type = type;
        pack.url = url;
        pack.param = param;
        pack.encry = encry;
        pack.tryNum = 3;
        _sendList.Enqueue(pack);
    }
    #endregion

    public HttpClient()
    {
        _sendTask = StartDaemonThread(StartSend);
    }

    private static Thread StartDaemonThread(ThreadStart threadMethod)
    {
        Thread thread = new Thread(threadMethod);
        thread.IsBackground = true;
        thread.Start();
        return thread;
    }

    private void StartSend()
    {
        while (true)
        {
            HandleSend();
        }
    }

    private void HandleSend()
    {
        if (_sendList.count > 0)
        {
            HttpPack pack = _sendList.Dequeue();
            switch (pack.type)
            {
                case HttpType.Get:
                    {
                        Get(ref pack, pack.url, pack.encry);
                        HandleRecive(ref pack);
                        return;
                    }
                case HttpType.Post:
                    {
                        Post(ref pack, pack.url, pack.param, pack.encry);
                        HandleRecive(ref pack);
                        return;
                    }
            }
        }
    }

    // 处理接收
    private void HandleRecive(ref HttpPack pack)
    {
        // 异常时重试
        if (pack.code != 200 && pack.tryNum > 0)
        {
            pack.tryNum--;
            _sendList.Enqueue(pack);
        }
        else
        {
            _receiveList.Enqueue(pack);
        }
    }

    private void Get(ref HttpPack pack, string url, bool encry, int timeout = 2000, Encoding encode = null)
    {
        HttpWebRequest req = null;
        HttpWebResponse res = null;
        req = (HttpWebRequest)WebRequest.Create(url);
        req.AllowAutoRedirect = false;
        req.Timeout = timeout;

        try
        {
            res = (HttpWebResponse)req.GetResponse();
        }
        catch (WebException ex)
        {
            res = (HttpWebResponse)ex.Response;
        }

        pack.code = ((int)res.StatusCode);
        using (Stream stream = res.GetResponseStream())
        {
            pack.response = GetStrResponse(stream, encry, encode);
        }

        res.Close();
        req.Abort();
    }

    private void Post(ref HttpPack pack, string url, string postdata, bool encry, int timeout = 2000, Encoding encode = null)
    {
        HttpWebRequest req;
        HttpWebResponse res;
        encode = encode ?? Encoding.UTF8;
        req = (HttpWebRequest)WebRequest.Create(new Uri(url));
        req.Method = "POST";
        req.Timeout = timeout;

        if (postdata != null)
        {
            byte[] byteArray = encode.GetBytes(postdata);
            Stream stream = req.GetRequestStream();
            stream.Write(byteArray, 0, byteArray.Length);
            stream.Close();
        }

        try
        {
            res = (HttpWebResponse)req.GetResponse();
            pack.code = (int)res.StatusCode;
            using (Stream resStream = res.GetResponseStream())
            {
                pack.response = GetStrResponse(resStream, encry, encode);
            }
            res.Close();
        }
        catch (WebException ex)
        {
            pack.code = (int)ex.Status;
        }

        req.Abort();
    }

    // 处理加密
    private string GetStrResponse(Stream stream, bool encry, Encoding encode)
    {
        using (StreamReader reader = new StreamReader(stream))
        {
            string str = reader.ReadToEnd();
            if (encry)
            {
                byte[] unEncryBytes = encode.GetBytes(str);
                _encry.DoEncry(unEncryBytes);
                return encode.GetString(unEncryBytes);
            }
            else
            {
                return str;
            }
        }
    }
}

HttpPack(http数据包)

public class HttpPack : Poolable<HttpPack>
{
    public HttpType type;
    public int code;
    public bool encry;
    public int tryNum;
    public int key;
    public string url;
    public string param;
    public string response;
}

BlockQueue(多线程队列)

using System;
using System.Collections.Generic;
using System.Threading;

public class BlockQueue<T>
{
    private readonly Queue<T> _queue;
    private readonly int _capacity;
    private bool _closing;

    public int count
    {
        get { return _queue.Count; }
    }

    public BlockQueue(int capacity)
    {
        this._capacity = capacity;
        this._queue = new Queue<T>(capacity);
    }

    public void Enqueue(T item)
    {
        lock (_queue)
        {
            while (_queue.Count >= _capacity)
            {
                Monitor.Wait(_queue);
            }
            _queue.Enqueue(item);
            if (_queue.Count == 1)
            {
                Monitor.PulseAll(_queue);
            }
        }
    }

    public T Dequeue()
    {
        lock (_queue)
        {
            while (_queue.Count == 0)
            {
                Monitor.Wait(_queue);
            }
            T item = _queue.Dequeue();
            if (_queue.Count == _capacity - 1)
            {
                Monitor.PulseAll(_queue);
            }
            return item;
        }
    }


    public void Close()
    {
        lock (_queue)
        {
            _closing = true;
            Monitor.PulseAll(_queue);
        }
    }

    public bool TryDequeue(out T value)
    {
        lock (_queue)
        {
            while (_queue.Count == 0)
            {
                if (_closing)
                {
                    value = default(T);
                    return false;
                }
                Monitor.Wait(_queue);
            }
            value = _queue.Dequeue();
            if (_queue.Count == _capacity - 1)
            {
                Monitor.PulseAll(_queue);
            }
            return true;
        }
    }
}

Encry(加密)

public class Encry
{
    private string _encryKey;

    public Encry(string encryKey)
    {
        _encryKey = encryKey;
    }

    public void DoEncry(byte[] data)
    {
        int keyId = 0;
        for (int i = 0; i < data.Length; i++)
        {
            data[i] ^= (byte)_encryKey[keyId];
            keyId++;
            if (keyId >= _encryKey.Length)
            {
                keyId = 0;
            }
        }
    }
}

BaseController(单例)

using UnityEngine;

public abstract class BaseController<T> : MonoBehaviour 
    where T : BaseController<T>
{
    private const string ROOT_NAME = "SingleRoot";
    private static T _instance = null;

    private static GameObject root
    {
        get
        {
            GameObject singleRoot = GameObject.Find(ROOT_NAME);
            if (singleRoot == null)
            {
                singleRoot = new GameObject(ROOT_NAME);
                DontDestroyOnLoad(singleRoot);
            }
            return singleRoot;
        }
    }

    public static T instance
    {
        get
        {
            if (_instance == null)
            {
                GameObject gameObject = new GameObject(typeof(T).Name);
                gameObject.transform.SetParent(root.transform);
                _instance = gameObject.AddComponent<T>();
            }
            return _instance;
        }
    }

    public virtual void Init()
    {
        
    }

    public virtual void Remove()
    {
        if (_instance == this)
            _instance = null;

        GameObject.Destroy(gameObject);
    }
}

Poolable(对象池之可缓存对象)

using System;
using System.Collections.Generic;

public class Poolable<T> where T : Poolable<T>
{
    private static Queue<T> _pool;
    private static Queue<T> Pool
    {
        get
        {
            if (_pool == null)
            {
                _pool = new Queue<T>();
                PoolManager.instance.RegisterPool(ClearPool);
            }
            return _pool;
        }
    }

    public static T GetPooled()
    {
        T output;
        if (Pool.Count == 0)
        {
            output = Activator.CreateInstance<T>();
        }
        else
        {
            output = _pool.Dequeue();
        }
        return output;
    }

    public static void ClearPool()
    {
        _pool.Clear();
    }

    public void Dispose()
    {
        OnDispose();
        Pool.Enqueue((T)this);
    }

    protected virtual void OnDispose()
    {

    }
}

PoolManager(对象池管理器)

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

class PoolManager : BaseController<PoolManager>
{
    public delegate void PoolClearHandler();
    private event PoolClearHandler _onFlush;

    public PoolManager()
    {

    }

    public void RegisterPool(PoolClearHandler clearHandler)
    {
        _onFlush += clearHandler;
    }

    public void Flush()
    {
        _onFlush?.Invoke();
    }
}

Unity 如何设计网络框架 注意好这些点,就可以设计出一个很好的网络框架。为了收数据的时候能完整正确的收到应用层的数据包,我们必须要把两个应用层的数据报之间做好分隔标记,当我们收到数据以后就可以根据分隔标记来决定哪些数据是哪个包的。二进制序列化/反序列化:基于二进制的bit,通过用户商量的协议来把数据对象变成二进制bit数据流,反序列化的时候根据用户协议,来把bit数据流变成数据对象。底层有可能把两个应用层的数据包分到一个”TCP数据包”发过去,接收到后,一部分是属于上一个应用层的数据包,一部分属于下一个应用层的数据包,这个叫做。 阅读详情

相关推荐

Unity模块化游戏开发框架:从架构设计到核心模块实现

在Unity游戏开发中,模块化架构是一种通过高内聚、低耦合的设计原则来组织代码的核心方法。其原理是将复杂系统拆分为独立、可复用的功能模块,每个模块通过定义良好的接口进行通信,从而提升代码的可维护性和可测试性。这种架构的技术价值在于支持并行开发、便于功能替换与扩展,并能有效管理资源生命周期,防止内存泄漏。其应用场景广泛,尤其适用于需要长期迭代的中大型游戏项目,能显著降低团队协作成本。本文以实战为导向,深入解析了如何构建一个包含资源管理、UI框架、事件通信等核心模块的Unity开发框架,其中资源管理模块通过引用

weixin_30247781的博客 370

Unity网络通信之HTTP

**超文本传输协议HTTP**(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。那么,我们怎样使用和访问HTTP呢? 首先,我们需要通过VS建立一个服务器 步骤:选择模板栏下的Web,创建ASP.NET MVC 4 Web应用程序,选择项目

qq_40258199的博客 965

Unity游戏开发框架GameFramework核心模块解析与实战应用指南

在Unity游戏开发中,模块化架构与资源管理是构建可维护、高性能项目的基石。其核心原理在于通过清晰的职责分离和标准化接口,降低代码耦合度,提升团队协作效率。这一设计带来的技术价值在于能够系统化地解决资源加载、内存管理、UI流程等工程难题,尤其适用于中大型商业项目的开发。在实际应用场景中,开发者常借助成熟框架来落地这些最佳实践,例如GameFramework(GF)。该框架通过模块化设计,将资源管理、对象池、UI系统、事件通信等核心功能封装为独立服务,并内置了对AssetBundle与热更新的完善支持。本文以

weixin_33857679的博客 476

Unity简单HTTP服务

using LitJson; using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Text; using System.Threading.Tasks; using UnityEngine; /// <summary> /// 用于接收启动器发送的设备ID,根据设备ID进行资源更新(启动轮询一次) /// </summary> public

weixin_41155760的博客 1782

Unity安卓局域网文件传输方案:HTTP协议实现与优化指南

在游戏开发与移动应用开发中,局域网文件传输是一项基础且关键的技术,它基于客户端-服务器(C/S)架构模型,通过本地网络协议实现设备间高效数据交换。其核心原理是利用设备在同一网络下的IP可达性,构建点对点通信链路,避免了对外部互联网和云服务的依赖。这项技术的核心价值在于保障数据传输的私密性、提升传输速度与稳定性,尤其适用于开发测试、资源热更新、日志收集等对安全与效率要求高的内网场景。本文聚焦于Unity引擎与安卓平台的集成实践,深入探讨如何利用HTTP协议这一通用、易上手的方案,结合UnityWebReque

weixin_34331102的博客 662

基于MediaPipe与Unity的实时体感游戏开发实战

计算机视觉驱动的实时交互正从实验室走向教育、康复与无障碍应用等高价值场景。其核心在于将人体姿态等物理世界信号,通过轻量高效算法(如MediaPipe姿态估计)转化为结构化数据,并以毫秒级低延迟(<20ms)稳定传输至游戏引擎(如Unity)。关键技术挑战涵盖光照鲁棒性、多人区分、UDP实时通信、零拷贝数据桥接及跨平台部署。本文聚焦CV与游戏引擎协同开发范式,提供从OpenCV预处理、MediaPipe关键点提取到Unity骨骼映射的端到端工程化路径,兼顾初学者可上手性与工业级稳定性要求。

weixin_34116482的博客 239

Unity封装的Http请求工具(Get、Post、Put、Delete)

Dictionary<string, int> hash = new Dictionary<string, int>(); hash.Add("currentPage", 1); hash.Add("pageSize", 10); string str = LitJson.JsonMapper.ToJson(hash); print(str); string url = "http://192.168.0.103:8084/api/model/selectAll"; UnityWeb

vip的博客 3256

Unity Editor HTTP MCP Server:跨线程请求封送与主线程调度架构

在软件架构中,跨线程通信与数据封送是解决并发编程核心挑战的关键技术,尤其在单线程UI框架与多线程服务端集成的场景下。其原理在于通过同步上下文(SynchronizationContext)和任务(Task)模型,安全地将工作单元从一个线程调度到另一个特定线程执行,并异步地传递结果。这项技术的工程价值在于能够打破‘工具链孤岛’,实现外部系统对单线程应用内部能力的标准化、无侵入式调用,从而极大提升自动化流程的效率和可集成性。典型的应用场景包括CI/CD流水线集成、自动化测试框架驱动以及AI辅助编程工具对接。本文

weixin_31240035的博客 262

Unity前端游戏框架完整解决方案:提升游戏开发效率的利器

Unity前端游戏框架完整解决方案:提升游戏开发效率的利器 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 Unity前端游戏框架完整解决方案,是一款专为Unity游戏开发者设计的全功能开发套件。它集成了UI、网络、资源、数据、脚本、时间、线程和日志等多个模块,旨在通过模块化设计和高度整合,为开发者提供一站式的游戏开发解决方案。 项目技术分析 Unity前端游戏框架完整...

gitblog_06706的博客 1224

Unity中Http框架

最近做了ASP.NET Web应用程序(.Net Framework)的Http服务,所以想也把之前我的Http框架也整理一下发布出来供大家参考。

类人_猿的博客 802

DOTween Pro v1.0.380 unity 插件 最新版

DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTween Pro v1.0.380 unity 插件 最新版DOTwe

Unity游戏开发-客户端Http下载

本篇主要分享基于.Net实现一个客户端Http下载模块。 Http下载这块和服务器也有一定的联系,关于服务器Http下载模块的实现可以参考这里《基于C#的服务器Http通信》

FlyToCloud的博客 719

DeepSeek跨会话协作指南:让AI成为你的「第二大脑」

通过DeepSeek的跨会话协作系统,用户实测工作效率提升63%。

紫夜若涵的博客 1474

[Unity]AssetBundle资源更新以及多线程下载

前言 此文章适合不太了解资源加载的萌新,有了入门基础之后再去github上搜大牛写的专业的资源加载方案才能得心应手,不然的话会看的很吃力或者说一脸懵逼。Unity里面关于资源加载我们都知道是下载更新AssetBundle,关于AssetBundle我之前的文章已经详细介绍过,没看过的朋友可以在看一下。下面介绍的资源加载的Demo有以下几点: 1.WWW下载图片资源 2.HTTP下载apk文件,并且...

Su_Ruyu的博客 754

车辆贷款违约预测挑战赛

2021科大讯飞-车辆贷款违约预测挑战赛--方案简介车贷违约预测问题,目的是建立风险识别模型来预测可能违约的借款人。预测结果为借款人是否可能违约,属于二分类问题。偏数据挖掘的比赛,关键点是如何基于对数据的理解抽象归纳出有用的特征。站在大佬的视角,尝试学习总结,站在巨人的肩膀上,也许看得会更远一些。直接进入主题,开始学习套路,芜湖~特征工程1、常用库、数据导入import pandas as pd import numpy as np import lightgbm as lgb import xgboost

平平淡淡,戒急用忍,一生学闭嘴。 3341

Ubuntu 上 1Panel 的安装与高效运维实践

本文详细介绍了在Ubuntu系统上安装和高效运维1Panel面板的完整实践指南。内容涵盖了一键安装、Docker容器可视化部署、计划任务自动化以及网站数据库管理等核心功能,并提供了安全加固、资源监控与数据备份等进阶技巧,旨在帮助用户快速搭建并管理一个强大易用的服务器环境。

weixin_29210759的博客 143

Unity网络编程实战:C# Socket通信框架与TCP粘包处理

网络编程是构建实时交互应用的核心基础,其本质在于实现不同设备或进程间的数据交换。Socket作为操作系统提供的底层网络通信接口,扮演着网络进程间“电话插座”的角色,通过IP地址和端口号建立连接通道。在技术实现上,TCP协议提供可靠、有序的数据流传输,适用于游戏状态同步等场景,而UDP协议则侧重于低延迟的实时数据传输。对于Unity开发者而言,掌握C# Socket编程不仅能解决与自定义服务端或外部硬件的通信需求,还能深入理解网络通信原理,有效应对TCP粘包拆包、异步处理和线程安全等工程挑战。本文以Unity

weixin_33696822的博客 462

基于C#的跨平台上位机开发:一次编写,多平台运行

摘要: 本文探讨了如何利用C#进行跨平台上位机开发,以适配Windows、Linux、macOS等多平台需求。通过分析传统单平台开发的局限性(如API差异、硬件接口兼容性),提出基于.NET 5/6/7的解决方案,重点推荐Avalonia(类WPF的跨平台UI框架)和GtkSharp(基于GTK+)实现图形界面。同时,针对硬件通信需求,介绍了System.IO.Ports串口通信和LibUsbDotNet的跨平台支持,并强调多平台调试(VS Code、Docker)的重要性,最终实现一次编码、多端部署的高效

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1407

Unity-MCP:面向游戏开发的AI通信协议基建

在游戏开发中,将大模型能力集成到Unity引擎面临主线程阻塞、跨平台网络兼容性差、上下文丢失和不可审计等核心挑战。MCP协议(Model Communication Protocol)作为一种轻量级JSON-RPC风格的通信规范,聚焦于协议层抽象与跨平台通信基建,通过异步非阻塞设计、强上下文绑定、可中断请求和多传输层适配,解决Unity与AI服务间稳定、可追溯、可中断的双向通信问题。它不绑定具体模型或云厂商,支持本地Ollama、私有API网关乃至规则引擎,已在多个商业项目中验证其在Windows/macO

weixin_33724570的博客 667

18650电池组流体直冷热管理仿真:COMSOL多物理场耦合建模路线与实战策略

在动力电池与储能系统的热管理设计中,多物理场耦合仿真已成为平衡性能与成本的关键工具。液冷方案的换热极限促使行业转向制冷剂直冷技术,而两相流与电池产热的强耦合特性,使得基于COMSOL的数值建模成为评估系统温升与流动分配的重要手段。工程实践中,电化学-热-流场全耦合模型与集总电池-流场简化模型各有适用场景,前者揭示电池内部微观机理,后者则以高计算效率支撑包级方案迭代。通过合理简化几何、标定内阻与熵热系数、设置等效换热边界,仿真能够准确预测直冷系统在快充或大倍率放电下的温度均匀性与压降特性,从而指导流道优化与制

weixin_33585822的博客 314

基于GELAN模块的YOLOv8改进-C2f结构替换与轻量化与高效涨点优化研究

本文详细探讨了在YOLOv8架构中利用YOLOv9的GELAN模块替换C2f结构的改进方法。轻量化版本在资源受限的场景中具有显著的推理效率提升,适用于边缘设备和移动端应用。高效涨点版本则在检测精度上实现了大幅突破,特别适合高精度要求的任务。实验结果显示,GELAN模块相比原C2f模块,在参数量与计算量间取得了更好的平衡,同时提升了检测性能。此外,本文还展示了结构图、训练代码和部署优化方案,为研究者和开发者提供了实践参考。

博客 1436

最新Unity游戏主程进阶学习大纲(2个月)

e: 游戏开发中常用的管理模块:日志模块,事件订阅与发布模块, 声音管理模块,UI管理模块,Timer模块,TCP/UDP/HTTP网络模块,序列化与反序列化模块,节点池管理模块,状态机逻辑控制模块,行为树逻辑控制模块;”的学习大纲,帮助大家做好面试准备。c: 项目渲染管线的选取与配置: 内置渲染管线,URP渲染管线,HDRP渲染管线等,它们的优缺点,如何给项目选择合适的渲染管线;d: 游戏关卡编辑器工具的制作: 扩展编辑器支持关卡类游戏的编辑与数据导出,如《跑酷游戏》的关卡编辑器;

voidinit的专栏 1571

YOLOv13改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Backbone、SPPF、Neck、检测头等全方位改进

1️⃣ 已更新种不同的改进方案,专栏内的每篇文章皆,均可顺利运行。2️⃣ 订阅专栏即可进群获取以及从的各种答疑内容。3️⃣ 全新的YOLOv13改进专栏,,只为更好的满足论文发表的要求。专栏内容,专栏实时评分,全网最高,质量保证。🎫。。

Limiiiing的博客 9151

Unity游戏开发:基于MagicOnion与gRPC构建高性能实时通信客户端

在实时游戏与物联网应用开发中,高性能网络通信是核心技术挑战。gRPC作为一种基于HTTP/2的现代RPC框架,通过二进制协议、头部压缩和双向流等特性,为低延迟、高吞吐量的数据传输提供了底层支持。其技术价值在于能够显著优化传统HTTP REST API在实时场景下的性能瓶颈,特别适用于游戏状态同步、数字孪生和物联网数据交换等场景。MagicOnion作为构建在gRPC之上的C#友好层,进一步降低了开发门槛,允许开发者使用熟悉的接口定义方式实现远程调用。本文聚焦于如何在Unity中集成MagicOnion客户端

385

国科大人工智能原理与算法-2024-第一次作业-雷震老师

1. 反射行动(比如从热炉子上缩回你的手)是理性的吗?它们是智能的吗? 2. 以下的计算机系统在何种程度上是人工智能的实例: - 超市条码扫描器 - 网络搜索引擎 - 语音激活的电话菜单 - 对网络状态动态响应的网络路由算法 3. 为什么进化会倾向于导致行为合理的系统?设计这样的系统想达到的目标是什么?

MatsumotoChrikk 2928

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

上一篇: Unity游戏开发 基于多线程的Http网络框架基础篇
下一篇: Unity游戏开发 单例基类
古月三齐
博客等级 码龄10年 67粉丝 22原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值