在创建微信小程序源码及h5小游戏源码过程中,我们将创建我们的游戏应用程序(使用 Unity 3d),我们将连接到我们的WebSocket服务器。议使用 Unity Hub 来管理您的 Unity 下载,因为它允许您拥有多个版本的 Unity,如果您愿意的话。在撰写本文时,我使用的是 Unity 版本2020.3.23f1。在大多数情况下,我们今天将介绍的内容应该适用于所有 2018、2019、2020 版本的 Unity。我建议使用 Unity 的 LTS(长期支持版本)版本之一,您可以从LTS Releases Unity Page下载它们。在我们构建游戏应用程序时,使用其中一个版本可确保更高的稳定性和支持。

仓库源码:y.wxlbyx.icu
  所以,现在我们已经在我们的机器上安装了 Unity3D 引擎,让我们创建我们的 Unity 项目。
  创建我们的 Unity 项目
  首先,让我们打开 Unity Hub 并确保我们在应用程序的项目部分如下图所示:

  进入 Unity Hub 后,选择“新建”按钮旁边的向下插入符号,然后选择您想要创建应用程序的 Unity 版本。
  您现在应该看到一个标题为“创建新项目...”的对话框,并确保您在“模板”部分中选择了“3D”。在“设置”部分,选择项目名称(我将使用“有史以来最好的游戏 - 多人游戏”)并选择您希望创建项目的位置。准备就绪后,选择“创建”按钮,如下图所示:

  选择“创建”后,您将看到 Unity 开始工作,因为它创建了我们将基于“3D”项目模板使用的基础项目。
  创建我们的玩家移动脚本
  创建玩家角色 player 后,让我们通过创建移动脚本来为其添加在场景中移动的能力。为了让事情井井有条,让我们快速创建一个“Scripts”文件夹来保存我们所有的脚本,并在该文件夹中创建一个名为“Player”的文件夹来保存播放器特定的文件夹。
  因此,在“Project”窗口的 Assets 文件夹中,让我们创建一个名为“Scripts”的文件夹。创建后,让我们进入该文件夹并创建一个名为“Player”的文件夹。创建文件夹后,让我们创建一个名为“Movement”的新 C# 脚本。
  注意:当我们创建脚本时,请确保在取消选择文件之前更改文件的名称。否则你将不得不做额外的工作来确保你的脚本被正确命名。我不会详细说明这意味着什么,因为需要一些时间来解释,但请注意这一点。
  在我们的 Player 文件夹中,右键单击空白区域并选择“创建 > C# 脚本”。一旦出现脚本图标,我们将命名我们的脚本运动,如下所示:
  现在我们的“运动”脚本已经创建,让我们打开它和我们的代码。所以继续双击该文件并在您首选的编辑器中打开我们的脚本(默认情况下,Unity 使用 Visual Studio)并删除所有默认代码,直到您的文件如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Movement : MonoBehaviour
{}

  现在我们的文件已经很清楚了,让我们在文件中的 Movement 公共类中添加这行代码:

  float movementSpeed = 5.0f;

这个浮点变量将用于确定我们播放器的速度。从理论上讲,您可以将此值设置为您想要的任何值,但在这种情况下,我们将其设置为 5.0f。
  添加第一个变量后,让我们添加实际移动玩家角色的功能。在我们的新变量下面,让我们添加以下代码:

void Update(){Vector3 moveDir = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));Vector3 newMoveDir = moveDir * movementSpeed;transform.position += newMoveDir * Time.deltaTime;}

  此代码利用 Unity 引擎每帧调用的 Update 函数,并根据播放器的移动输入(WASD 和箭头键)更改播放器位置。moveDir变量创建一个 Vector3 对象,该对象使用 Input.GetAxis 方法存储玩家的输入。GetAxis根据按下的方向输出一个从 -1 到 1 的值,传入Input.GetAxis方法的 Horizo ​​ntal和Vertical参数对应于键输入:
  水平:A/D/左箭头/右箭头
  垂直:W/S/向上箭头/向下箭头
  一旦这个 Vector3 对象被创建,它就会被添加到玩家的对象变换位置,它决定了玩家在世界中的位置。
  现在我们已经创建了脚本,我们需要将它添加到我们的玩家对象中,以便我们的玩家角色移动。让我们导航回 Unity 编辑器,然后选择我们的 Cube。
  在 Inspector 窗口中,导航到底部并单击“添加组件”按钮,如下所示:
  创建多人游戏套接字连接
  在花了一些时间构建我们非常简单的游戏之后,是时候将我们的游戏连接到我们之前制作的多人游戏服务器了。为此,我们需要在项目中添加两个新脚本:PlayerData和SocketManager。
  这两个脚本对于使我们的游戏与我们的 WebSocket 服务器有效通信至关重要。
  因此,让我们从 PlayerData 脚本开始。
  在我们项目的 Scripts 文件夹中,让我们创建一个名为“Multiplayer”的新文件夹。这个文件夹将包含我们游戏的多人游戏方面的所有代码。打开我们新建的“Multiplayer”文件夹并创建一个新脚本(右键单击> Create > C# Script)并命名为“PlayerData”。在我们的 PlayerData 脚本文件中,将其全部内容替换为以下代码:

using System;[Serializable]
public struct PlayerData
{public string id;public float xPos;public float yPos;public float zPos;public double timestamp;
}

  这个脚本本质上是为我们将传递给我们的服务器的数据设置结构,其中将包含有关我们玩家角色当前位置的信息。我们创建这个脚本的原因是因为它可以让我们轻松地将我们的玩家数据转换为我们可以轻松发送到我们的服务器的 JSON 对象/字符串。
  如果您查看代码,您可能会注意到[Serializable]行。这实质上使我们创建的这个数据结构成为可序列化的,这意味着我们可以使用一些基本的 Unity 实用程序轻松地将这些数据转换为其他形式。
  您可能还注意到这个 PlayerData 对象是一个struct。这允许我们将此 PlayerData 对象用作“结构”,作为我们的数据对象将遵循的形式,并与说一个类相比保持该数据非常轻量级。所以这可能是描述这一点的最糟糕的方式,但如果您有兴趣进一步了解这一点,我鼓励您查看“结构和类之间的差异”。我保证你会学到很多东西。
  当我们继续我们的 SocketManager 脚本时,您将看到我们使用 PlayerData 结构来快速存储我们的数据并将其转换为 JSON,然后再将其发送到服务器。
  现在我们已经创建了 PlayerData 脚本(或者更好地描述为 PlayerData 结构),让我们创建 SocketManager 脚本,我们将使用它来管理我们的连接、向游戏服务器发送数据和从游戏服务器接收数据。
  在 Unity 编辑器的 Project 区域的 Script 文件夹中,让我们在“Multiplayer”文件夹中添加一个名为“SocketManager”的新脚本。我们现在应该在 Multiplayer 文件夹中看到两个脚本 PlayerData 和 SocketManager,如下所示:
  16-Multiplayer-scripts-in-folder
  创建该文件后,让我们打开该文件。进入文件后,删除为您预先制作的所有代码并添加以下代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using WebSocketSharp;
using Newtonsoft.Json.Linq;public class SocketManager : MonoBehaviour
{WebSocket socket;public GameObject player;public PlayerData playerData;// Start is called before the first frame updatevoid Start(){socket = new WebSocket("ws://localhost:8080");//socket = new WebSocket("ws://websocket-starter-code-multiplayer-websocket-app.bsh-serverconnect-b3c-4x1-162e406f043e20da9b0ef0731954a894-0000.us-south.containers.appdomain.cloud/");socket.Connect();//WebSocket onMessage functionsocket.OnMessage += (sender, e) =>{//If received data is type text...if (e.IsText){//Debug.Log("IsText");//Debug.Log(e.Data);JObject jsonObj = JObject.Parse(e.Data);//Get Initial Data server ID data (From intial serverhandshakeif (jsonObj["id"] != null){//Convert Intial player data Json (from server) to Player data objectPlayerData tempPlayerData = JsonUtility.FromJson<PlayerData>(e.Data);playerData = tempPlayerData;Debug.Log("player ID is " + playerData.id);return;}}};//If server connection closes (not client originated)socket.OnClose += (sender, e) =>{Debug.Log(e.Code);Debug.Log(e.Reason);Debug.Log("Connection Closed!");};}// Update is called once per framevoid Update(){//Debug.Log(player.transform.position);if (socket == null){return;}//If player is correctly configured, begin sending player data to serverif (player != null && playerData.id != ""){//Grab player current position and rotation dataplayerData.xPos = player.transform.position.x;playerData.yPos = player.transform.position.y;playerData.zPos = player.transform.position.z;System.DateTime epochStart =  new System.DateTime(1970, 1, 1, 8, 0, 0, System.DateTimeKind.Utc);double timestamp = (System.DateTime.UtcNow - epochStart).TotalSeconds;//Debug.Log(timestamp);playerData.timestamp = timestamp;string playerDataJSON = JsonUtility.ToJson(playerData);socket.Send(playerDataJSON);}if (Input.GetKeyDown(KeyCode.M)){string messageJSON = "{\"message\": \"Some Message From Client\"}";socket.Send(messageJSON);}}private void OnDestroy(){//Close socket when exiting applicationsocket.Close();}}

  现在这是一大段代码。所以我要做的就是把它分成 6 个部分并总结每个部分发生的事情。一旦我们理解了这段代码,我们就可以设置我们的 Unity 场景来使用它并连接到我们之前创建的服务器。但在我们继续之前,您需要做一些非常重要的事情来使 SocketManager 脚本工作
  现在所有必要的文件都准备好了,让我们继续。正如我所提到的,我现在将套接字管理器分解为单独的部分。

1. 进口

  using System.Collections;using System.Collections.Generic;using UnityEngine;using WebSocketSharp;using Newtonsoft.Json.Linq;

  本节非常简单,因为我们只是导入了运行代码所需的所有必要框架。需要注意的最重要的事情是我们正在导入WebSocketSharp(从我们的 .dll 文件)和Newtonsoft.Json.Linq。注意:在 Unity 2020 之前,您需要手动将 Newtonsoft 添加到您的项目中。因此,如果您使用的是 2020 年之前的版本,您可以访问 [此页面] 以了解有关将 Newtonsoft 添加到您的项目的更多信息。
  2.变量

  WebSocket socket;public GameObject player;public PlayerData playerData;

  这部分代码声明了我们将在整个脚本中使用的变量,以使我们的 SocketManager 工作。socket变量是我们将用来连接、发送和接收来自服务器的消息的变量。player游戏对象只是代表我们游戏中的玩家,而playerData对象是我们将发送到套接字服务器的数据。这些将是我们的经理工作所需的唯一变量。
  3. 创建我们的 WebSocket 连接
  因此,在我们的 Start 函数(启动此脚本时触发的函数)中,您将首先看到以下代码行:

  socket = new WebSocket("ws://localhost:8080");socket.Connect();

  第一行代码指定了我们的 websocket 游戏服务器的位置以及连接的位置。这可以在我们的本地机器上或 Red Hat OpenShift 上的远程服务器上。唯一需要注意的是,由于我们使用的是 WebSocket 协议,所以我们的网址需要以ws://开头
  第二行代码实际上会将我们连接到前行指定的游戏服务器。这应该会启动客户端(Unity 游戏)和服务器之间的“握手”。
  4. 接收消息

  //WebSocket onMessage functionsocket.OnMessage += (sender, e) =>{//If received data is type text...if (e.IsText){//Debug.Log("IsText");//Debug.Log(e.Data);JObject jsonObj = JObject.Parse(e.Data);//Get Initial Data server ID data (From intial serverhandshakeif (jsonObj["id"] != null){//Convert Intial player data Json (from server) to Player data objectPlayerData tempPlayerData = JsonUtility.FromJson<PlayerData>(e.Data);playerData = tempPlayerData;Debug.Log("player ID is " + playerData.id);return;}}};//If server connection closes (not client originated)socket.OnClose += (sender, e) =>{Debug.Log(e.Code);Debug.Log(e.Reason);Debug.Log("Connection Closed!");};

  所以这部分代码应该看起来与我们在服务器上创建的代码非常相似。本质上,这段代码中有两个监听器在运行;一个 OnMessage 侦听器和一个 OnClose 侦听器。与我们的服务器类似,这两个侦听器正在侦听传入消息以及何时从服务器触发关闭方法(也就是服务器出于某种原因关闭它与我们的游戏的连接)。
  在我们的 OnMessage 代码部分中,您将看到:
  if (e.IsText)...
  这只是一个健全性检查,因为我们的服务器理论上可以向我们发送二进制或文本数据。在我们的例子中,我们只想处理文本数据。

  JObject jsonObj = JObject.Parse(e.Data);//Get Initial Data server ID data (From initial server handshakeif (jsonObj["id"] != null){//Convert Initial player data Json (from server) to Player data objectPlayerData tempPlayerData = JsonUtility.FromJson<PlayerData>(e.Data);playerData = tempPlayerData;Debug.Log("player ID is " + playerData.id);return;}

  此代码解析从服务器发送的 JSON 字符串数据,然后检查 JSON 字符串是否采用我们希望使用的格式。在这种情况下,它专门查看 JSON 数据是否具有id字段。这样做是因为我们将服务器设计为向客户端发送一组特定的数据,其中包含玩家 ID 以供以后存储。您可以使用这样的逻辑来发送具有特定字段的数据,并根据数据可能具有的字段对数据执行不同的操作。
  一旦我们确认了该字段,我们就会将我们收到的 JSON 数据转换为一个 PlayerData 对象,然后我们可以在我们的代码中使用该对象。这非常方便,因为它通过自动将 JSON 字段链接到 PlayerData 对象中的数据字段来为我们节省大量时间,然后我们可以在 Unity 代码中使用这些字段。它不会包含 PlayerData 对象所期望的所有数据,但 Unity 能够实现这一点,并且只是根据属性类型将不存在的字段设置为默认值。
  5. 向游戏服务器发送数据

  //Debug.Log(player.transform.position);if (socket == null){return;}//If player is correctly configured, begin sending player data to serverif (player != null && playerData.id != ""){//Grab player current position and rotation dataplayerData.xPos = player.transform.position.x;playerData.yPos = player.transform.position.y;playerData.zPos = player.transform.position.z;System.DateTime epochStart = new System.DateTime(1970, 1, 1, 8, 0, 0, System.DateTimeKind.Utc);double timestamp = (System.DateTime.UtcNow - epochStart).TotalSeconds;//Debug.Log(timestamp);playerData.timestamp = timestamp;string playerDataJSON = JsonUtility.ToJson(playerData);socket.Send(playerDataJSON);}

  在我们的更新函数中,我们做了很多事情。我们要做的第一件事就是检查我们的套接字变量是否有效。如果不是,我们只是短路/停止我们的代码,因为它下面的所有代码都需要套接字对象有效。
  如果套接字对象有效,我们有一个“IF 语句”来检查我们的玩家游戏对象是否有效,以及我们的 playerData id 字段是否有一个非空的字符串值。这个检查做了两件重要的事情:
  它确保我们有一个与该脚本关联的有效播放器。这很重要,因为我们的 IF 语句中的所有代码都需要有效的玩家数据(例如位置)才能发送到服务器。
  它确保玩家有一个ID。这很重要,因为在我们向服务器发送数据之前,我们需要一个标识符让服务器知道哪个客户端发送了数据。这只是确保我们的游戏在我们正确配置与服务器的连接之前不会发送数据。
  在我们确保我们的玩家和玩家 ID 是有效的之后,剩下的代码就是获取关于玩家当前位置的信息,并设置一个时间戳,在这个时间戳上我们捕获了关于玩家的这些信息。这些都存储在我们的 PlayerData 对象中,然后由 Unity 的 JSONUtility 转换为 JSON 字符串并发送到我们的服务器以供其检索。
  就像我们的游戏正在向我们的服务器发送关于我们的玩家以及玩家在任何特定时刻的位置的数据一样。
  5.关闭游戏服务器连接

private void OnDestroy(){//Close socket when exiting applicationsocket.Close();}

  最后,我们有一小部分代码在脚本本身被销毁(也就是游戏应用程序因任何原因关闭时)被触发。此代码只是向我们的服务器发送一条“关闭”消息,这将触发服务器上的 OnClose 侦听器。这是一组重要的代码,因为服务器必须知道玩家何时离开游戏,这样它才能将该玩家从服务器中移除并通知所有其他玩家。
  服务器启动并运行后,返回 Unity 编辑器并按下播放按钮运行我们的游戏。游戏开始后,返回终端窗口,您现在应该会看到终端窗口打印有关我们的播放器的信息,如下所示:

  Client 50c7f039-1d1a-45d5-a695-a8656c6a4ba8 Connected!Player Message{id: '50c7f039-1d1a-45d5-a695-a8656c6a4ba8',xPos: -0.7148541808128357,yPos: 0.5,zPos: 0.6946321129798889,timestamp: 1638454171.455932}Player Message{id: '50c7f039-1d1a-45d5-a695-a8656c6a4ba8',xPos: -0.7148541808128357,yPos: 0.5,zPos: 0.6946321129798889,timestamp: 1638454171.488816}

微信小程序源码及H5小游戏源码内核构建方法相关推荐

  1. 【微信小程序控制硬件②】 开始微信小程序之旅,导入小程序Mqtt客户端源码,实现简单的验证和通讯于服务器.(附带源码)

    文章目录 一.前言: 二.注册微信小程序: 三.本博文连接和微信物联有何区别: 四.微信小程序`MQTT`客户端源码导入注意事项: 五.下载: 微信物联网生态主要分在微信硬件开发平台与腾讯物联开发平台 ...

  2. 小狐狸ChatGPT付费创作系统1.92独立版 + H5端 + 小程序前端+新增AI绘画功能 系统源码体验安装教程

    小狐狸GPT付费体验系统最新版系统是一款基于ThinkPHP框架开发的AI问答小程序,是基于国外很火的ChatGPT进行开发的Ai智能问答小程序.播播资源网针对源码整体测试下来非常完美,可以说小狐狸G ...

  3. 微信小程序:云开发表情包制作源码

    该款小程序是一个表情包制作 内容毕竟丰富,另外自定义制作方面也是特别的自由 支持自主上传图片,自定义文章,另外拥有多种素材模板以供选择 这是一款云开发的小程序,但是安装还是挺简单的 搭建教程: 首先使 ...

  4. 跳一跳改分java源码_解密微信小程序漏洞:可下载任意小游戏源代码,“跳一跳”可改分...

    原标题:解密微信小程序漏洞:可下载任意小游戏源代码,"跳一跳"可改分 雷锋网消息,据 IT 之家 1 月 2 日消息称,"跳一跳"居然可以利用漏洞自己改分数,甚 ...

  5. python 自动化微信小程序_干货 | 微信小程序自动化测试最佳实践(附 Python 源码)...

    原标题:干货 | 微信小程序自动化测试最佳实践(附 Python 源码) 本文为霍格沃兹测试学院测试大咖公开课<微信小程序自动化测试>图文整理精华版. 随着微信小程序的功能和生态日益完善, ...

  6. 基于微信小程序云开发的投票小程序源码,图文投票微信小程序源码

    功能介绍 投票活动十分火,商家,企业,机构偶尔都会来一场投票活动评选,本小程序支持图文投票,简单方便.随时随地完成投票,可以方便设定投票模式(按天按全程,投票数限定). 本代码前后端完整代码包投票列表 ...

  7. 计算机毕业设计Python+uniapp基于微信小程序某企业考勤系统(小程序+源码+LW)

    计算机毕业设计Python+uniapp基于微信小程序某企业考勤系统(小程序+源码+LW) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行 环境配置: Pychram社区版+ ...

  8. 基于微信小程序的springboot客运汽车票购票系统源码和论文

    在客运公司工作 7 年之余,对客运管理的难度深有感触.特别是在春运期 间购票难依旧是长途汽车订票的一大难题.长途汽车和火车的订票管理虽然有 差异,但大体上是相同的.长途汽车在售票的过程中需要对旅客的起 ...

  9. 微信小程序自带地图_小程序丨教你:如何打开小程序如何打开微信自带的地图(附源码)...

    教你小程序系列教程:教你小程序系列教程: 1.教你:微信小程序如何实现scroll-view隐藏滚动条 2.教你:如何使用scroll-view组件实现视图垂直滚动(附源码) 3.教你:小程序如何使用 ...

  10. 微信小程序:笑话与趣图框架源码下载

    这是一款以笑话和趣味图为主的一款微信小程序源码 或者也可以说是一个框架吧 里面的内容是内置在小程序里面的,所以说是一款框架也可以 因为内置的内容,所以内容数量有限! 大家可以用来养账号,或者有能力的二 ...

最新文章

  1. Third Week :Linux下的C语言
  2. hadoop程序实例
  3. 优先队列/单调队列 - 滑动窗口最大值
  4. 矩形并的面积(51Nod-2488)
  5. make、make clean、make uninstall的使用
  6. Oracle分页小谈
  7. Unity加载机制及内存管理
  8. [计算机网络] - HTTP、HTTPS
  9. canvas绘图数学知识总结
  10. 微型计算机应用领域思维导图,思维导图作用和应用领域有哪些
  11. 【Python数据分析实战】豆瓣读书分析(含代码和数据集)
  12. 转载-SAP HCM系统和OA系统接口方案讨论
  13. Android 10.0 强制app横屏显示
  14. saltstack的NETAPI接口详讲
  15. 万年历农历法定节假日数据查询工具
  16. Webview相关属性和事件处理
  17. Beanstalkd源码分析—bury和kick命令的实现
  18. NLP-生成模型-2016:CopyNet【Copy机制赋予seq2seq模型从源文本中复制词汇的能力,解决Decoder的OOV问题】
  19. 计算机各个接口PCB-Layout 规则要求
  20. Python语言_理論與習題

热门文章

  1. vue实现调用摄像头扫描二维码功能
  2. 查看tomcat版本信息
  3. 读完本文你就了解什么是文本分析
  4. eviews7.2pojie版-eviews7.2附使用教程
  5. Eviews6 7 软件安装包
  6. ENVI5.3软件资源与安装教程(64bit)
  7. 专为存储设计的LRC编码
  8. 哨兵2号L1C数据下载及预处理
  9. Java获取网络视频封面图片
  10. 手机麦克风结构原理图_一文看懂咪头的工作原理及结构(驻极体话筒) - 全文...