网站模板怎么修改/故事式软文范例500字

网站模板怎么修改,故事式软文范例500字,西安关键词排名推广,wordpress 修改 page文章目录 【Unity网络同步框架 - Nakama研究(三)】准备工作前言Unity部分连接服务器创建并进入房间创建人物人物移动和同步 【Unity网络同步框架 - Nakama研究(三)】 以下部分需要有一定的Unity基础,在官方的案例Pirate Panic基础上进行修改而成。如果没有下载并熟悉…

文章目录

  • 【Unity网络同步框架 - Nakama研究(三)】
    • 准备工作
    • 前言
    • Unity部分
      • 连接服务器
      • 创建并进入房间
      • 创建人物
      • 人物移动和同步

【Unity网络同步框架 - Nakama研究(三)】

以下部分需要有一定的Unity基础,在官方的案例Pirate Panic基础上进行修改而成。如果没有下载并熟悉过官方案例,最好先下载对应的工程查看。工程地址为:https://github.com/heroiclabs/unity-sampleproject,对应的案例文档为:https://heroiclabs.com/docs/zh/nakama/tutorials/unity/pirate-panic/,以下运行的Unity版本为2022LTS,一般关系不大

准备工作

  • Unity2022或者随便一个LTS版本
  • VS2022
  • Nakama Unity SDK(官网或者Unity商店都有,实在找不到把上面的案例的程序集偷出来)

前言

  • Nakama是一个网络同步库,兼容很多游戏引擎,名字取自于日语伙伴,底层由Go开发,所以性能上有保证(可以对比其他流行的网络框架)。并且拥有大量已经开发好而且经过检验的功能(聊天,排行榜,群组,房间,身份验证,存储,好友等等),但是之前在网络上,甚至官网上找到的博客或者文章要么是性质雷同,要么就是空谈。
  • 以下的改变主要是用于网上找不到,AI提供不准确,论坛全英文,翻找资料麻烦的基础上提供的。

Unity部分

连接服务器

  • 我喜欢尽量把逻辑精简,让程序能跑起来,再去研究里面的细节,就像钢铁侠里面的台词“有时候你得先跑起来,再学会走路”
	[SerializeField] private GameConnection _connection;public static string DeviceIdKey => "nakama.deviceId" + UserData.Id;public static string AuthTokenKey => "nakama.authToken" + UserData.Id;public static string RefreshTokenKey => "nakama.refreshToken" + UserData.Id;private Client client;private ISocket socket;private const string ServerIp = "xxx.xxx.xx.xx"; // 你的ip地址public async void RequireEnterRoom(){if (_connection.Session == null){string deviceId = GetDeviceId();if (!string.IsNullOrEmpty(deviceId)){PlayerPrefs.SetString(DeviceIdKey, deviceId);}await InitializeGame(deviceId);}}private async Task InitializeGame(string deviceId){client = new Client("http", ServerIp, 7350, "defaultkey", UnityWebRequestAdapter.Instance);client.Timeout = 5;socket = client.NewSocket(useMainThread: true);string authToken = PlayerPrefs.GetString(AuthTokenKey, null);bool isAuthToken = !string.IsNullOrEmpty(authToken);string refreshToken = PlayerPrefs.GetString(RefreshTokenKey, null);ISession session = null;// refresh token can be null/empty for initial migration of client to using refresh tokens.if (isAuthToken){session = Session.Restore(authToken, refreshToken);// Check whether a session is close to expiry.if (session.HasExpired(DateTime.UtcNow.AddDays(1))){try{// get a new access tokensession = await client.SessionRefreshAsync(session);}catch (ApiResponseException){// get a new refresh tokensession = await client.AuthenticateDeviceAsync(deviceId);PlayerPrefs.SetString(RefreshTokenKey, session.RefreshToken);}PlayerPrefs.SetString(AuthTokenKey, session.AuthToken);}}else{session = await client.AuthenticateDeviceAsync(deviceId);PlayerPrefs.SetString(AuthTokenKey, session.AuthToken);PlayerPrefs.SetString(RefreshTokenKey, session.RefreshToken);}Connect(socket, session);IApiAccount account = null;try{account = await client.GetAccountAsync(session);}catch (ApiResponseException e){Debug.LogError("Error getting user account: " + e.Message);}_connection.Init(client, socket, account, session);}private async void Connect(ISocket socket, ISession session){try{if (!socket.IsConnected){await socket.ConnectAsync(session);}}catch (Exception e){Debug.LogWarning("Error connecting socket: " + e.Message);}}private string GetDeviceId(){string deviceId = "";deviceId = PlayerPrefs.GetString(DeviceIdKey);if (string.IsNullOrWhiteSpace(deviceId)){deviceId = Guid.NewGuid().ToString();}return deviceId;}

上面的这部分就是连接的函数部分,其中的结构GameConnection如下:

using Nakama;
using UnityEngine;public class GameConnection : ScriptableObject
{private IClient _client;public IClient Client => _client;public ISession Session { get; set; }public IApiAccount Account { get; set; }private ISocket _socket;public ISocket Socket => _socket;private IChannel _channel;public IChannel Channel => _channel;public string MatchID { get; set; }public void Init(IClient client, ISocket socket, IApiAccount account, ISession session){_client = client;_socket = socket;Account = account;Session = session;}
}

上面大部分的代码都能在案例中找到,有些小修改。需要注意的是,如果要在电脑上实现多开(非编辑器模式下,处于打完包的exe状态),需要修改DeviceIdKey等参数,不然服务器接收到的时候,这俩会识别成同一个帐号(因为传入的参数deviceId一致),会给后续操作带来麻烦。

创建并进入房间

  • 这一步开始就跟案例中的不一样了,案例使用的是AddMatchmakerAsync,这个方法在文档中说明是不会创建房间的,只是简单的匹配机制,所以如果这个时候你写了如下代码:
	private async void ListMatchesAndJoin(){var minPlayers = 0;var maxPlayers = 10;var limit = 10;var authoritative = true;var label = "";var query = "*";try{var result = await client.ListMatchesAsync(_connection.Session, minPlayers, maxPlayers, limit, authoritative, null, null);// 添加新的列表项foreach (var match in result.Matches){Debug.LogFormat("{0}: {1}/{2} players", match.MatchId, match.Size, maxPlayers);JoinMatch(match.MatchId);break;}}catch (System.Exception e){Debug.LogError("Error listing matches: " + e.Message);}}

到时候你就会发现怎么都拿不到房间信息,一直返回空,这里根据需求分为两步,一是你自己创建的房间(如果人数为0,会被销毁,而且走的是官方设定好的逻辑,叫非权威比赛),二是服务器创建的权威比赛,这个比赛即使房间内人数为0也不会解散(关服务器还是会解散的)

// 这是非权威比赛(权威比赛会在上述代码中直接返回对应的matchid)
var matchid = await _connection.Socket.CreateMatchAsync();// 通过返回的matchid加入
var match = await socket.JoinMatchAsync(matchId);

至于如何创建服务器的权威比赛,留到下次讲服务器扩展再说。

  • 走到这一步,其实我们已经在房间里了,看服务器的日志,日志
    第一条是连接socket,第二条是加入房间。

创建人物

  • 进入了房间,接下去做的一般是创建你所加入房间的那个摆设,或者新的场景,然后给服务器发送创建人物的信息,涉及到操作信息在房间内的传递。
  • 创建新的场景这一点,Unity自己就能做到
  • 发送操作信息要分开,因为Nakama有很多种渠道可以发送消息,这里采用正规一点的房间消息,需要注意的是,如果这个房间是非权威房间,那么房间信息Nakama给你写好了,如果是服务器自己创建的非权威房间,那么需要你自己写。
	public static async Task SpawnPlayer(){var matchMessagePlayerCreate = new MatchMessagePlayerCreate(BattleSceneController.Instance.Connection.Session.Username,BattleSceneController.Instance.Connection.Session.UserId,randomPos.x,randomPos.y,randomPos.z,0, 0, 0,selectCharacterId,selectCharacterData);BattleSceneController.Instance.StateManager.SendMatchStateMessage(MatchMessageType.UnitSpawned, matchMessagePlayerCreate);BattleSceneController.Instance.StateManager.SendMatchStateMessageSelf(MatchMessageType.UnitSpawned, matchMessagePlayerCreate);}

创建人物信息的方式跟案例里面的差不多,注意一下时序问题即可。然后在监听对应事件的地方GameStateManager处理服务器发送过来的消息即可。

private GameConnection _connection;_connection.Socket.ReceivedMatchState += ReceiveMatchStateMessage;private void ReceiveMatchStateMessage(IMatchState matchState){string messageJson = System.Text.Encoding.UTF8.GetString(matchState.State);if (string.IsNullOrEmpty(messageJson))return;ReceiveMatchStateHandle(matchState.OpCode, messageJson);}public void SendMatchStateMessageSelf<T>(MatchMessageType opCode, T message)where T : MatchMessage<T>{switch (opCode){case MatchMessageType.UnitSpawned:OnPlayerCreate?.Invoke(message as MatchMessagePlayerCreate);break;default:break;}}
public void ReceiveMatchStateHandle(long opCode, string messageJson){switch ((MatchMessageType)opCode){case MatchMessageType.UnitSpawned:MatchMessagePlayerCreate matchMessagePlayerCreate = MatchMessagePlayerCreate.Parse(messageJson);OnPlayerCreate?.Invoke(matchMessagePlayerCreate);break;default:break;}}

有一点需要注意的是,Nakama传递的消息结构字段是json,而且是Base64转义之后的,如果你在服务器的日志中看到错误信息,记得先转回正常的字符串。

  • 然后你的人物就能出现在场景中了。人物

人物移动和同步

  • 再往后面就是正常的人物之间的同步信息,比如人物的旋转,移动,动画等等,都可以在上面ReceiveMatchStateHandle方法里面进行监听和执行,涉及到CinemachineTimeline,动画状态机等等,就不在这里详细展开了。

下一章讲讲服务器的扩展相关和一些可能遇到的问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/72278.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【AD】6-1 PCB常用规则

间距规则&#xff1a; 可自行修改线宽与间距&#xff08;默认10mil&#xff09; 线宽规则&#xff1a;电源线宽加粗 布线过程中更改线宽&#xff1a;走线状态下&#xff0c;shiftw更改线宽&#xff0c;线宽要在规则范围之内过孔规则&#xff1a; 阻焊规则&#xff1a;

【零基础入门unity游戏开发——unity3D篇】3D物理系统之 —— 3D刚体组件Rigidbody

考虑到每个人基础可能不一样,且并不是所有人都有同时做2D、3D开发的需求,所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】:主要讲解C#的基础语法,包括变量、数据类型、运算符、流程控制、面向对象等,适合没有编程基础的…

C# net deepseek RAG AI开发 全流程 介绍

deepseek本地部署教程及net开发对接 步骤详解&#xff1a;安装教程及net开发对接全流程介绍 DeepSeekRAG 中的 RAG&#xff0c;全称是 Retrieval-Augmented Generation&#xff08;检索增强生成&#xff09;&#xff0c;是一种结合外部知识库检索与大模型生成能力的技术架构。其…

b站视频下载工具软件怎么下载

自行配置FFMPEG环境 请优先选择批量下载&#xff0c;会自处理视频和音频文件。 如果要下载更高质量请登陆。 没有配置FFMPEG下载后会有报错提示&#xff0c;视频音频文件无法合并生成mp4文件 更新批量下载标题&#xff0c;只取视频原标题&#xff0c;B站反爬机制登陆后下载多了…

Java 大视界 -- Java 大数据分布式计算中的资源调度与优化策略(131)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

时序数据库 TDengine 到 MySQL 数据迁移同步

简述 TDengine 是一款开源、高性能、云原生的时序数据库&#xff0c;专为物联网、车联网、工业互联网、金融、IT 运维等场景优化设计。在工业自动化的时代&#xff0c;时序数据库在电力、轨道交通、智能制造等领域有着广泛的应用。 MySQL 是全球广泛使用的开源关系型数据库&a…

基于YOLO11深度学习的舌苔舌象检测识别与诊断系统【python源码+Pyqt5界面+数据集+训练代码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

正新鸡排:在变革浪潮中领航,打造连锁餐饮新生态

在当下风云变幻的餐饮市场中&#xff0c;连锁品牌犹如逆水行舟&#xff0c;不进则退。作为国内坐拥万店的知名连锁餐饮品牌&#xff0c;正新鸡排2023年卖出了7.2亿片鸡排&#xff0c;集团营收同比增长28%。在《2024年中国鸡排连锁品牌10强榜单》中&#xff0c;正新鸡排以高达95…

软件性能测试与功能测试联系和区别

随着软件开发技术的迅猛发展&#xff0c;软件性能测试和功能测试成为了确保软件质量的两个重要环节。那么只有一字之差的性能测试和功能测试分别是什么?又有哪些联系和区别呢? 一、软件性能测试是什么?   软件性能测试是为了评估软件系统在特定条件下的表现&#xff0c;包…

Vue 框架使用难点与易错点剖析:避开陷阱,提升开发效率

Vue.js 作为当下最流行的前端框架之一&#xff0c;以其轻量、易用和灵活的特性深受开发者喜爱。然而&#xff0c;即使是经验丰富的开发者&#xff0c;在使用 Vue 的过程中也难免会遇到一些难点和易错点。本文将深入分析 Vue 开发中常见的“坑”&#xff0c;并提供解决方案和代码…

Odoo Http鉴权+调用后端接口

最近在调研Odoo18&#xff0c;包括它的前后端原理、源码等。发现官方的开发文档并不十分实用&#xff0c;比如标题这种简单的实用需求&#xff0c;竟然浪费了一点时间&#xff0c;特此记录。 官方文档&#xff1a;External API — Odoo 18.0 documentation 前提&#xff1a;首…

Linux常见问题与分析

操作系统进行线程切换时进行的动作 1. 保存当前线程的上下文 寄存器状态&#xff1a;保存 CPU 寄存器&#xff08;如通用寄存器、程序计数器 PC、栈指针 SP 等&#xff09;到当前线程的 线程控制块&#xff08;TCB&#xff09; 中。内核栈信息&#xff1a;如果线程在内核态运…

VSTO(C#)Excel开发6:与窗体交互

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

Node.js与VUE安装

目录 Win下载安装 Mac下载安装 Win与Mac配置检查是否安装成功切换淘宝NPM库检查镜像配置是否生效设置 npm 全局环境目录&#xff08;避免权限问题&#xff09;WinMac VUE CLI安装安装验证打开vue面板 Vue脚手架npm init vuelatest、npm create vuelatestvue create、vue ui Win…

解决 MySQL 迁移到达梦报错 “无效的列名” 的问题

在数据库迁移的过程中&#xff0c;常常会遇到各种各样的问题。本文将聚焦于从源库 MySQL&#xff08;大小写不敏感&#xff09;迁移到目标库达梦&#xff08;大小写敏感&#xff09;时&#xff0c;出现的创建索引报错 “无效的列名” 这一问题&#xff0c;使用SQLark工具如何避…

C/C++都有哪些开源的Web框架?

CppCMS CppCMS是一个采用C语言开发的高性能Web框架&#xff0c;通过模版元编程方式实现了在编译期检查RESTful路由系统&#xff0c;支持传统的MVC模式和多种语言混合开发模式。 CppCMS最厉害的功能是WebSocket&#xff0c;10万连接在内存中长期保存占用的大小不超过600MB&…

大数据学习(59)-DataX执行机制

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91…

USB数据采集卡 Labview采集卡 32路AD模拟量采集 DAQ卡

今天给大家介绍阿尔泰科技的一款多功能数据采集卡USB3150/1/2/5/6 。 该板卡提供 32RSE / NRSE 通道或 16 通道 DIFF 模 拟量输入&#xff1b;4 通道模拟量同步输出&#xff1b;16 路可编程 I/O&#xff1b;2 路计数器。 USB3150/1/2/5/6 的主要应用场合为&#xff1a;电子产品…

基于DeepSeek的智能数据分析和自动化处理系统:引领BI行业新变革

近期&#xff0c;一款基于DeepSeek API的智能数据分析和自动化处理系统横空出世&#xff0c;以其强大的功能和灵活的可扩展性&#xff0c;为BI行业带来了颠覆性的变革。 该系统支持多类型数据分析&#xff0c;包括文本 、指标和日志等。在文本分析方面&#xff0c;它能够提取关…

【CentOS】搭建Radius服务器

目录 背景简介&#xff1a;Radius是什么&#xff1f;Radius服务器验证原理搭建Radius服务器环境信息yum在线安装配置FreeRADIUS相关文件clients.conf文件users文件重启服务 验证 参考链接 背景 在项目中需要用到Radius服务器作为数据库代理用户的外部验证服务器&#xff0c;做…