<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Posts on 云笺小筑</title>
    <link>https://imrcao.top/posts/</link>
    <description>Recent content in Posts on 云笺小筑</description>
    <generator>Hugo -- 0.122.0</generator>
    <language>zh-cn</language>
    <lastBuildDate>Thu, 04 Jun 2026 17:34:22 +0800</lastBuildDate>
    <atom:link href="https://imrcao.top/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Github中SSH密钥配置流程</title>
      <link>https://imrcao.top/posts/0.7github%E4%B8%8A%E7%9A%84ssh%E5%AF%86%E9%92%A5%E9%85%8D%E7%BD%AE/</link>
      <pubDate>Thu, 04 Jun 2026 17:34:22 +0800</pubDate>
      <guid>https://imrcao.top/posts/0.7github%E4%B8%8A%E7%9A%84ssh%E5%AF%86%E9%92%A5%E9%85%8D%E7%BD%AE/</guid>
      <description>一、SSH 是什么 SSH（Secure Shell）是一种加密网络协议。在 Git 场景下，SSH 密钥对用来代替密码向 GitHub 证明身份。
核心原理：
私钥留在本地电脑，永远不要分享 公钥上传到 GitHub 推送/拉取代码时，本地用私钥签名，GitHub 用公钥验证 二、配置流程（共 6 步） 步骤 1：检查是否已有 SSH 密钥 1 ls -al ~/.ssh/ 命令拆解：
ls：list，列出目录下的文件 -a：显示所有文件（包括 . 开头的隐藏文件） -l：以长格式显示（权限、大小、日期等） ~：用户主目录，Windows 上即 C:\Users\用户名 .ssh/：SSH 配置目录（隐藏文件夹） 如果看到 id_ed25519 和 id_ed25519.pub，说明已有密钥，可跳过步骤 2。 如果只有 known_hosts 或目录为空，说明没有密钥，继续下一步。
步骤 2：生成新的 SSH 密钥 1 ssh-keygen -t ed25519 -C &amp;#34;你的GitHub邮箱&amp;#34; 命令拆解：
ssh-keygen：SSH 密钥生成工具 -t ed25519：指定算法为 Ed25519（比 RSA 更短更安全更快，目前最推荐） -C &amp;quot;邮箱&amp;quot;：注释，方便日后识别密钥归属 执行后两个交互提示：
保存位置 → 直接回车，使用默认路径 ~/.ssh/id_ed25519 passphrase（口令） → 可留空回车，也可设密码保护私钥 生成结果：.</description>
    </item>
    <item>
      <title>使用UE4原生模块进行简单UDP广播和数据接收</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E4%BD%BF%E7%94%A8ue4%E5%8E%9F%E7%94%9F%E6%A8%A1%E5%9D%97%E8%BF%9B%E8%A1%8C%E7%AE%80%E5%8D%95udp%E5%B9%BF%E6%92%AD%E5%92%8C%E6%95%B0%E6%8D%AE%E6%8E%A5%E6%94%B6/</link>
      <pubDate>Wed, 03 Jun 2026 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E4%BD%BF%E7%94%A8ue4%E5%8E%9F%E7%94%9F%E6%A8%A1%E5%9D%97%E8%BF%9B%E8%A1%8C%E7%AE%80%E5%8D%95udp%E5%B9%BF%E6%92%AD%E5%92%8C%E6%95%B0%E6%8D%AE%E6%8E%A5%E6%94%B6/</guid>
      <description>前言： 最近在学习UE4网络相关知识，尝试学习使用 UDP做一个分布式服务器（后面会出相关文章），这里简单记录一下如何使用 UE4的“Sockets”模块和“Networking”模块进行UDP广播。
操作步骤： 1、首先创建两个空的UE4C++工程（我这里使用的是UE426版本引擎），一个用来广播数据，一个用来接收数据，在两个工程分别创建继承自UObject的类，分别命名为“ UDPSend”和“ UDPRecive”，还需在&amp;quot;.build.cs&amp;quot;文件中添加模块“Sockets&amp;quot;, &amp;ldquo;Networking”，示例如下代码所示。 2、为了清晰可见，直接上代码（部分代码是网上粘贴的，我这里只是想记录的同时再复习一遍，也方便自己后续查阅）。 3、编译后启动引擎，将两个基于C++的蓝图类，分别拖入到场景中（用来广播的工程只用创建UDPSend，用来接收的工程只用创建“UDPRecive”）。拖入场景中后，在UDPSend中调用函数“StartUDPSender()”，传入网络套接字、 IP、端口号即可。UDP开启后，可以TICK执行广播数据（调用函数RamaUDPSender_SendString（））；接收数据的工程也是一样，将对应类拖入场景中，打开蓝图编辑器，先调用函数StartUDPReceiver（），再调用函数DataRecv（）。两个工程要同时运行，这样就能广播和接收数据了。 using UnrealBuildTool;
public class UDPTest426 : ModuleRules { public UDPTest426(ReadOnlyTargetRules Target) : base(Target) { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 PublicDependencyModuleNames.</description>
    </item>
    <item>
      <title>使用Perforce管理Unreal Engine项目</title>
      <link>https://imrcao.top/posts/0.6%E4%BD%BF%E7%94%A8perforce%E7%AE%A1%E7%90%86unreal-engine%E9%A1%B9%E7%9B%AE/</link>
      <pubDate>Fri, 29 May 2026 17:59:15 +0800</pubDate>
      <guid>https://imrcao.top/posts/0.6%E4%BD%BF%E7%94%A8perforce%E7%AE%A1%E7%90%86unreal-engine%E9%A1%B9%E7%9B%AE/</guid>
      <description>前言 在本指南中你将了解如何使用Perforec管理UE项目，包括Perforce部署、安装、使用。我使用了家中电脑和公司电脑作为两个客户端，还有一台腾讯云服务器作用来托管Perforce。
下载 在Perforce官网（https://www.perforce.com/downloads）下载Perforce的服务器（Helix Core(P4D) Server）和客户端（Helix Visual Client(P4V)），直接搜英文名下载即可。
部署Perforce服务器 使用PC自带的远程桌面登录访问腾讯云服务器，将下载好的perforce服务器安装包拷贝到腾讯云上或者直接在腾讯云上下载。双击安装包运行，如图所示；
默认端口号为1666，如果和你本地端口冲突也可以自定义端口。点击“Change”选择一个用来存放资产的目录，如下图所示；
自定义你的User Name，客户端连接的服务器的时候会用到这个User Name。安装完毕后点击“exit”即可。如下图所示；
检测Perforce服务器是否运行成功。在命令行工具中输入“netstat -a&amp;quot;回车，会发现有端口为1666的程序在运行，说明Perforce安装部署成功。如下图所示；
安装Perforce客户端 双击安装包，默认全部勾选，选择安装路径后，点击”Next“。如图所示：
输入你的服务器公网IP地址和端口号（x.x.x.x:1666）以及在服务器中刚刚输入的User Name，最后一栏默认选择即可，点击”Next“。
创建一个”User“和”Workspace“。创建用户时可以不用输入密码。如下图所示。
创建好用户和工作空间后点击OK，会弹出来一个窗口让你上传文件到服务器。你可以指定一个文件夹或者创建一个文件夹，文件夹内需要有资产。如下图所示。
我这里选择”Use a classic depot“，看自己需要。如下图。
简单使用 点击”Get Latest“获取服务器最新资产；点击”Checkout“检出需要操作的资产；点击”Add“添加新的资产；点击”Submit“提交修改的资产； 使用 Unreal Engine 连接 Perforce 服务器 直接在Perforce中打开Unreal项目，在编辑器的右下角找到“Source Control”，点击选择“”，在弹出来的面板中输入服务器IP和端口，以及本地Perforce用户名和工作空间的名称，点击“Accept Settings”即可。
其它 Tips 1、当你不小心添加了很多无用的文件到DefaultList中，可以右键单击某一个Change列表，选择Revert Files，恢复。 </description>
    </item>
    <item>
      <title>Github配合Sourcetree管理UE4工程</title>
      <link>https://imrcao.top/posts/0.5github%E9%85%8D%E5%90%88sourcetree%E7%AE%A1%E7%90%86ue4%E5%B7%A5%E7%A8%8B/</link>
      <pubDate>Fri, 29 May 2026 17:58:30 +0800</pubDate>
      <guid>https://imrcao.top/posts/0.5github%E9%85%8D%E5%90%88sourcetree%E7%AE%A1%E7%90%86ue4%E5%B7%A5%E7%A8%8B/</guid>
      <description>一、创建私有仓库 这一步不详细记录 注意：创建仓库的时候选择添加gitIgnore文件，文件模板选择“UnrealEngine”
二、随便传几个文件 三、创建SSH密钥（核心） 使用SSH密钥克隆仓库，首要需要创建SSH密钥。 创建SSH密钥入口：点击头像选中“Settings” 根据链接中的提示创建 链接：https://docs.github.com/zh/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
安装Git for Windows（它自带 Git Bash） 管理员运行cmd，执行：
1 git-installer.exe /VERYSILENT /NORESTART 安装验证：
1 git --version 首先打开Git Bash（可以从SourceTree中启动） 先执行：
1 ssh-keygen -t ed25519 -C &amp;#34;your_email@example.com&amp;#34; //这里换成自己的邮箱 接着会出来：
1 Enter file in which to save the key (/c/Users/YOU/.ssh/id_ALGORITHM):[Press enter] //直接点回车就行 接着会让你输入两次密码：（19960525）
1 2 Enter passphrase (empty for no passphrase): [Type a passphrase] Enter same passphrase again: [Type passphrase again] 最终命令行如下： 结果会生成两个文件： 将这个key放到刚才在GitHub创建ssH文件的地方：
这样就可以复制ssh链接准备开始克隆了。
四、安装sourceTree（下载），安装过程中可能需要注册一下账号.. 这里打开终端： 输入ssh链接，指定目录克隆即可。 五、指定需要版本控制的文件 一般来说传这几个文件</description>
    </item>
    <item>
      <title>使用Git命令常见问题</title>
      <link>https://imrcao.top/posts/0.3%E4%BD%BF%E7%94%A8git%E5%91%BD%E4%BB%A4%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/</link>
      <pubDate>Fri, 29 May 2026 17:09:29 +0800</pubDate>
      <guid>https://imrcao.top/posts/0.3%E4%BD%BF%E7%94%A8git%E5%91%BD%E4%BB%A4%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/</guid>
      <description>克隆命令
1 git clone GitHub地址 条件：首先需要魔法上网，否则国内是无法连接GitHub的。其次需要设置代理的端口，否则也会提示连接失败。
1 2 3 git clone https://github.com/neilsonnn/image-blaster &amp;#34;F:/00_Imrcao/01_MyProject/ImageBlaster&amp;#34; Cloning into &amp;#39;F:/00_Imrcao/01_MyProject/ImageBlaster&amp;#39;... fatal: unable to access &amp;#39;https://github.com/neilsonnn/image-blaster/&amp;#39;: Failed to connect to github.com p 设置代理端口
1 2 git config --global http.proxy http://127.0.0.1:&amp;lt;端口&amp;gt; git config --global https.proxy http://127.0.0.1:&amp;lt;端口&amp;gt; 清除代理端口：
1 2 git config --global --unset http.proxy git config --global --unset https.proxy 查看代理端口:
1 2 git config --global --get http.proxy git config --global --get https.proxy 常用git命令 初始化与首次提交
1 2 3 git init # 在当前目录初始化 Git 仓库 git add .</description>
    </item>
    <item>
      <title>从零搭建全自动化极客博客 (Obsidian &#43; Hugo &#43; Vercel)</title>
      <link>https://imrcao.top/posts/0.2%E4%BB%8E%E9%9B%B6%E6%90%AD%E5%BB%BA%E5%85%A8%E8%87%AA%E5%8A%A8%E5%8C%96%E6%9E%81%E5%AE%A2%E5%8D%9A%E5%AE%A2/</link>
      <pubDate>Thu, 23 Apr 2026 17:29:43 +0800</pubDate>
      <guid>https://imrcao.top/posts/0.2%E4%BB%8E%E9%9B%B6%E6%90%AD%E5%BB%BA%E5%85%A8%E8%87%AA%E5%8A%A8%E5%8C%96%E6%9E%81%E5%AE%A2%E5%8D%9A%E5%AE%A2/</guid>
      <description>一、引言：为什么选择这套工作流？ 痛点分析：
我之前使用的是wordpress + WampServer + 阿里云创建的网站，这个流程最大的缺点就是在编辑笔记时需要去wordpress后台，后台不仅慢，编辑起来还费劲，虽然也可以在Obsidian中配合wordpress插件，但总还是感觉wordpress臃肿，不仅如此，服务器使用的是轻量级的，只有2M的带宽，访问很慢，而且域名备案流程繁琐且缓慢。接下来我介绍的流程可以免费托管，只需要为域名付费即可，而且域名无需在国内备案。
我的终极解法：
一套本地丝滑写作、云端自动构建、且几乎零成本的现代化技术博客方案。
核心技术栈预览：
Obsidian (本地编辑) + PicGo (图床管理) + Hugo (静态生成) + GitHub (版本控制) + Vercel (全球部署)。
二、 构建本地终极写作环境 (Obsidian 篇) 1. 认识 Obsidian
为什么它是技术笔记的神器（Markdown 原生、双链、极速响应），在遇到Obsidian之前我使用的是有道云和xmind，随着笔记内容越来越多有道云启动都要半天，现在还有好多广告。Obsidian完全本地化管理，数据安全，社区插件生态丰富，可以创建白板，一定程度上可以取代xmind。下载链接：https://obsidian.md/zh/
2. 图文分离：优雅的图片管理方案 (PicGo)
（1）、本地图片的痛点（分享不便、打包体积大）。技术笔记里面通常有很多图片，当积累一定规模时，无论时分享还是传到Github上进行云端备份都是一个棘手的问题。如果将笔记部署到网站里，那么图片多的时候往往加载很慢，对服务器带宽是一个极大的考验。所以图文分离是一个很有必要的步骤。
（2）、配置阿里云OSS对象存储。关于OSS不细述，只讲几个关键点。首先是关于AccessKey的，点击头像找到“权限与安全-&amp;gt;AccessKey”，我这里使用RAM用户AccessKey，如图1所示。然后根据配置执行生成即可，保存好你的AccessID和Key，只显示一次。然后进入对象存储OSS控制页面，先创建一个bucket，点击创建的bucket，找到权限控制-&amp;gt;阻止公共访问，点击关闭，如图2所示。在同一个页面，找到读写权限，将“Bucket ACL&amp;quot;设置为公共读。不然当你将图片链接放入笔记中时并不会正常显示图片。OSS有桌面版可视化管理工具，也可以下载使用。
（3）、配置 PicGo 图床方案（搭配阿里云 OSS 云存储）。首先安装PicGo，Github下载链接：https://github.com/Molunerfinn/PicGo/releases。我下载的是2.5.2版本。如图2-2-2-1所示，我使用的是阿里云的OSS作为图床，填入相关配置后，保存即可。关于
（4）、在 Obsidian 中实现“复制粘贴，自动上传并返回图床链接”的丝滑体验。这一步可以实现在Obsidian笔记中直接粘贴图片（配合Snipaste截图软件更方便，F1直接截图，Ctrl + V直接复制），自动将图片传到图床，并返回图床的链接。在Obsidian中下载一个叫“Image auto upload”的第三方插件，启用插件后，进入插件设置，设置PicGOServer 上传接口：http://127.0.0.1:36677/upload，一般默认就是这个值，端口号和PicGo中设置的保持一致，如下图所示。
3. 云端托管与版本控制 (Obsidian Git)
安装与配置 Obsidian Git 插件。
（1）、即使不准备搭建个人博客，只要你有记录笔记的习惯，这一部分对你也有很多帮助。Obsidian自带有云端同步功能，而且是端到端加密的，但是需要付费。另一个方案就是将Obsidian仓库上传到Github，这样可以实现在不同的工作地点对同一篇笔记进行无缝编辑。 （2）、首先创建一个Github仓库，然后将仓库克隆到本地，这一步可以参考笔记“Github配合Sourcetree管理UE4工程”（牵扯到SSH密钥）。在Obsidian中点击仓库管理，选择打开本地仓库，将刚才克隆的本地到仓库作为Obsidian的工作空间。在.gitignore文件中可以设置忽略的文件。
（3）、在Obsidian中下载Git第三方插件，启用后会在右侧出现Git操作面板，如图所示。常用的流程如下，当修改文件后，点击加号（Stage All）暂存所有，然后在输入框（默认Update Bolg：）输入当前修改的内容，接着点击对号（Commit）提交，最后点击上传按钮（push）推送到GitHub仓库。如果是比较小的修改，可以直接点击第一个向上的箭头（Commit-And-Sync）一键提交和推送。
总结
到这里已经实现了Obsidian + Picgo + Github的笔记托管方案。如果不考虑创建个人博客的话，这套流程用来写笔记也是非常舒服的，数据同步，免费托管，图文分离。</description>
    </item>
    <item>
      <title>使用UE挂载Pak时遇到的一个问题</title>
      <link>https://imrcao.top/posts/0.1%E4%BD%BF%E7%94%A8ue%E6%8C%82%E8%BD%BDpak%E6%97%B6%E9%81%87%E5%88%B0%E7%9A%84%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98/</link>
      <pubDate>Mon, 20 Apr 2026 11:27:15 +0800</pubDate>
      <guid>https://imrcao.top/posts/0.1%E4%BD%BF%E7%94%A8ue%E6%8C%82%E8%BD%BDpak%E6%97%B6%E9%81%87%E5%88%B0%E7%9A%84%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98/</guid>
      <description>问题 用PakTools插件打包出来的pak文件，打包运行挂载pak文件后（使用PakLoader插件加载），有的pak文件系统无法加载指定路径的资产。
原因分析： 使用cmd命令查看pak文件，得到如下输出：
1 2 3 4 5 6 cmd：UnrealPak.exe F:\00_Imrcao\01_MyProject\PreviewTools\Saved\DownloadedPaks\Models\chair_P.pak -List Mount point ../../../PreviewTool/ LogPakFile: Display: &amp;#34;AssetRegistry.bin&amp;#34; offset: 0, size: 3948 bytes, LogPakFile: Display: &amp;#34;Content/Assets/Materials/Models/Fabric_3.uasset&amp;#34; LogPakFile: Display: &amp;#34;Content/Assets/Materials/Models/Fabric_3.uexp&amp;#34; LogPakFile: Display: &amp;#34;Content/Assets/Materials/Models/Metal_2.uasset&amp;#34; 1 2 3 4 5 6 7 cmd：UnrealPak.exe F:\00_Imrcao\01_MyProject\PreviewTools\Saved\DownloadedPaks\Models\Bed_P.pak -List Mount point ../../../ PreviewTool/Content/Assets/Texture/UMG/Thumbnails/Models/Bed.ubulk&amp;#34; LogPakFile: Display: &amp;#34;PreviewTool/Content/Assets/Texture/UMG/Thumbnails/Models/Bed.uexp&amp;#34; LogPakFile: Display: &amp;#34;PreviewTool/Content/Blueprints/Sku/Models/Bed.uasset&amp;#34; LogPakFile: Display: &amp;#34;PreviewTool/Content/Blueprints/Sku/Models/Bed.uexp&amp;#34; 可以发现两个pak文件的mountPoint不一样，默认mountPoint系统自己计算，但也可以自己设置。那么mountPoint不一致会有什么问题呢？先看我的挂载代码。
1 UPakLoaderLibrary::MountPakFile(PakPaths, &amp;#34;&amp;#34;) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 //挂载pak UPakLoaderLibrary::MountPakFile(PakPaths, &amp;#34;&amp;#34;) //注册挂载点，这个是核心 UPakLoaderLibrary::RegisterMountPoint(&amp;#34;/PTPakDLC/&amp;#34;, &amp;#34;.</description>
    </item>
    <item>
      <title>Ctrl &#43; Z撤销功能实现思路</title>
      <link>https://imrcao.top/posts/0.4ctrl-&#43;-z%E6%92%A4%E9%94%80%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0%E6%80%9D%E8%B7%AF/</link>
      <pubDate>Tue, 03 Feb 2026 16:28:04 +0800</pubDate>
      <guid>https://imrcao.top/posts/0.4ctrl-&#43;-z%E6%92%A4%E9%94%80%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0%E6%80%9D%E8%B7%AF/</guid>
      <description>一、基本思路 操作封装。将每一个可撤销的用户行为，抽象为一个&amp;quot;命令对象&amp;quot;（IUndoableCommand），该对象下有两个方法：Do()、Undo()； 使用 TArray 存储最近的 5 步操作。创建撤销栈，先进后出。 创建撤销管理器：FUndoManager，管理&amp;quot;命令对象&amp;quot;。 绑定 Ctrl + Z。 二、核心类设计 1、抽象命令接口 IUndoableCommand
1 2 3 4 5 6 7 8 9 10 #pragma once #include &amp;#34;CoreMinimal.h&amp;#34; class IUndoableCommand { public: virtual ~IUndoableCommand() {} virtual void Do() = 0; virtual void Undo() = 0; }; 2、创建命令对象，比如平移对象：FTranslateActorCommand。（也可以类似实现：FActorPropertyCommand、FDeleteActorCommand 等操作）
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #pragma once #include &amp;#34;CoreMinimal.</description>
    </item>
    <item>
      <title>UE4打包IOS详细笔记</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue4%E6%89%93%E5%8C%85ios%E8%AF%A6%E7%BB%86%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Wed, 03 Sep 2025 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue4%E6%89%93%E5%8C%85ios%E8%AF%A6%E7%BB%86%E7%AC%94%E8%AE%B0/</guid>
      <description>前言： 第一次使用UE4打包IOS的话会遇到很多坑，这里记录了各种坑的填补方法。其实打包的方法有很多，需要有一台MAC电脑，如果你习惯在MAC上使用UE4，可以直接在MAC上进行打包。也可以在PC端进行远程连接打包。我这里只记录在PC上进行远程打包。我将这篇笔记分为四部分：MAC上创建证书相关；PC苹果开发者网站中证书及文件操作相关部分；PC主机和MAC机连接部分；UE4配置及打包部分。我测试的环境：一台MAC一体机，一台PC主机，一台IPADPro，使用UE427创建的C++工程，具有苹果开发者账号（不讲账号购买部分）。
一、MAC上创建开发者证书 在MAC上，找到“钥匙串”程序，打开后在电脑的上左上方的菜单栏中找到钥匙串-&amp;gt;证书助理-&amp;gt;从开发机构申请颁布证书。打开后输入邮箱和名称，在下方勾选“存储到磁盘”和“让我指定密钥对信息”，如图1-1所示。点击“继续”选择存储位置，在“密钥对信息”页面使用默认值就行，点击“继续”会创建一个后缀为“.certSigningRequest”的证书，如图1-2所示。证书创建好后拷贝到PC主机上（因为苹果开发者账号是从PC主机上登录的），在MAC上登录就不用拷贝了。
图1-1
图1-2
二、登录苹果开发者账号 1、进入网站“https://idmsa.apple.com/”。登录进去后首先开始创建证书，如图2-1-1所示。我这里选择“IOS App Developmant”，如图2-2-2所示。下一步选择从MAC上创建的后缀为“.certSigningRequest”的开发者证书，如图2-2-3所示。下一步点击“Download”将配置好的证书下载到本地，如图2-4所示。最终会得到一个“.cer”格式的文件。
图2-1-1
图2-1-2
图2-1-3
图2-1-4
2、第二步添加身份标识，创建AppID。如图2-2-1所示。选择App IDs，如图2-2-2所示，下一步选择“APP”，点击继续，如图２-2-3所示。首先填写描述，根据项目填写就行，接着填写“BundleID”，根据提示填写，我这里写的是“com.imrcao.ledv3.app”,要将BundleID记住，后面要在UE4的项目设置中用的。如图2-2-4所示。点击继续后就可以点击注册了，如图2-2-5所示。
图2-2-1
图2-2-2
图2-2-3
图2-2-4
图2-2-5
3、接着要添加设备，这里要获取IPAD的UDID，获取方法可以在网上搜一下，可以使用“蒲公英”，也可以使用爱思助手（个人比较推荐这个），使用爱思助手还可以安装自己的IPA程序。点击添加按钮，如图２-3-1所示。输入名字和UDID后点击继续即可，如图２-3-2所示。 图2-3-1
图2-3-2
4、第四步创建配置文件，这个文件是要在UE4中使用的。点击添加按钮，如图2-4-1所示。在新的一页选择“ios App Developmant”，点击继续如图2-4-2所示。选择第二步创建的AppID，点击继续，如图2-4-3所示。接着选择第一步创建的证书，如图2-4-4所示。点击继续后选择第三步创建的设备ID，如图2-4-5所示。最后预览信息无误后点击生成按钮，生成配置文件。如图2-4-6所示。配置好后回到“Profiles”列表，点击“Download”下载配置文件，会得到一个后缀为“.mobileprovision”文件。这个文件后面会直接导入UE4项目设置中使用。
图2-4-1
图2-4-2
图2-4-3
图2-4-4
图2-4-5
图2-4-6
三、MAC上认证“.cer”安全证书 1、第二部分完成后PC本地应该有后缀分别为“.cer”和“.mobileprovision”两个文件，如图3-1-1所示。接下来要将“.cer”文件拷贝到MAC上，认证证书，然后生成&amp;quot;.p12&amp;quot;信息交换文件。 图3-1-1
2、在MAC上双击“.cer”文件，在钥匙串的登录页就可以看到证书，注意在窗口上方一栏中会显示“此证书有效”的图标，如图3-2-1所示。如果证书是无效的话，应该是缺少两个系统证书，如图3-2-2所示，一个23年过期，一个30年过期。在证书有效的情况下对刚才导入的&amp;quot;.cer&amp;quot;文件单击右键选择导出（注意不是在“专用密钥”那一栏单击，在这里单击导出我没有试过）。在弹出的窗口点击“存储”，如图3-2-3所示。然后输入密码即可。这时会生成一个&amp;quot;.p12&amp;quot;文件。将这个文件传输到PC上，后面在UE4项目设置中直接导入。
图3-2-1
图3-2-2
图3-2-3
3、在PC上最终我们会使用这个两个文件，分别是后缀“.mobileprovision”和“.p12”文件。如图3-3-1所示。 图3-3-1
四、连接PC主机和MAC 1、如果你创建的是UE4的C++工程，那么打包IOS时就需要使用XCode编译，由于我们是在PC上打包，PC上是没有XCode的，所以要连接MAC机。使用无线和有线连接都可以，最终要使两台机器处于同一个局域网内，且可以“Ping”通。连接好后，在MAC上打开“共享”窗口，勾选“远程登录”，选择“所有用户”。如图4-1-1所示。
图4-1-1
2、查看MAC的用户名：在MAC中找到“终端”程序，终端窗口上面的名字就是用户名，这个在UE4项目设置中会用到。如图4-2-1所示。 图4-2-1
五、在PC上使用UE４打包。 1、在UE４工程的项目设置中找到“Platforms-&amp;gt;iOS”，点击“Import Provision”选择后缀“.mobileprovision”文件并导入，点击“Import Certificate”选择后缀“.p12”文件，输入密码后导入。在“Status”下显示“Valid”说明证书有效。有时候证书和密钥很多，如果前面的复选框都不勾选的话就使用默认的移动证书和密钥，勾选的话就使用指定证书和密钥。如图5-1-1所示。 2、在下方的“Bundle Information”一栏需要填写证书相关的信息，这里就会用到在开发者网站中创建AppID时填写的Bundle ID。Bundle Display Name是APP的显示名称，可以随便填写。Bundle Name也可以自己填写。Bundle Identifier一栏填写在开发者网站中创建AppID时填写的Bundle ID。如图5-1-1所示。 图5-1-1
3、接着要生成SSH Key，在项目设置“Platforms - ios-Build”下，展开“Remote Build Options”。 Remote Server Name 填写Mac的IP地址，RSync User Name 填写MAC的用户名（可以使用终端程序查看），接着就可以点击“Generate SSH Key”按钮了。 接下来会弹出一个命令行窗口。 （1）、首先随便按一个键继续； （2）、接下来会提示你输入MAC用户对应的登录密码，输入后按回车（这里输入是不可见的，盲打就行）； （3）、Enter same passphrase again:什么都不要输入，直接回车； （5）、接着会出来一堆代码，不要管直接按回车继续； （6）、接着再次输入MAC用户的登录密码，回车继续； 如果没有提示什么错误的话，说明Remote Build就设置成功过了，过一会SSH Key文件就生成在本地了。如图5-3-1所示。</description>
    </item>
    <item>
      <title>C&#43;&#43;编程-禁用优化</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/c&#43;&#43;%E7%BC%96%E7%A8%8B-%E7%A6%81%E7%94%A8%E4%BC%98%E5%8C%96/</link>
      <pubDate>Sat, 03 May 2025 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/c&#43;&#43;%E7%BC%96%E7%A8%8B-%E7%A6%81%E7%94%A8%E4%BC%98%E5%8C%96/</guid>
      <description>在 C++ 编程中，#pragma optimize(&amp;quot;&amp;quot;, off) 和 #pragma optimize(&amp;quot;&amp;quot;, on) 是用于控制特定代码段的编译器优化设置的预处理指令。这些指令可以帮助在调试特定代码段时禁用优化，以便更容易地跟踪和调试问题。 在 Unreal Engine 4 的开发中，可以使用这些指令来确保某些代码段在编译时不被优化，通常用于调试复杂逻辑或在执行关键任务时确保代码的行为与预期一致。</description>
    </item>
    <item>
      <title>IK Rig重定向</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ik-rig%E9%87%8D%E5%AE%9A%E5%90%91/</link>
      <pubDate>Tue, 11 Feb 2025 07:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ik-rig%E9%87%8D%E5%AE%9A%E5%90%91/</guid>
      <description>前言 在本指南中你将了解IKRig和IKRetargeter的使用方法；将使用了不同的骨架网格体的动画序列进行重定向，使动画序列具有通用性。使用了Epic商城中的AnimStarterPack和UnrealLearningKitGames；使用引擎版本：Unreal Engine5.1；目的：将AnimStarterPack中的动画序列重定向到UnrealLearningKitGames项目中的卡通人物。 IK Rig创建 在Content文件夹中单机右键找到：Animation-&amp;gt;IK Rig即可创建这两个资产。注意创建IK Rig时需要选择一个Skeletal Mesh。 需要创建两个IK Rig，分别选择Skeletal Mesh：SK_Mannequin And SK_EpicCharacter，分别命名为：Mannequin_IKRig And LearningKitCharacter_IKRig。如下图所示。 IK Rig重定向根骨骼 需要分别对两个IK Rig进行重定向根骨骼 重定向根骨骼：一般选择胯部的骨骼，例如pelvis, Hip。选中骨骼单机右键，选择SetRetargetRoot。如下图所示。 IK Rig重定向链 什么是链 起始骨骼指向性单一，中间不要有分支，如下图所示：左侧为指向性单一的骨骼，可以形成一条链，右侧将会形成两条链。 创建骨骼链。 选中指定骨骼，单机右键选择“New Retarget Chain from Selected Bones”，重命名后选择“No Goal”。 需要注意的是在为大腿创建骨骼时有一个旋转骨骼“calf_twist_01_I&amp;quot;不要包含进去，如下图所示。如果你想重定向这个骨骼的话需要单独创建一个链。 最后创建完成后的骨骼链列表，如下图所示。 IKRetargeter创建 在Content空白处单机右键找到：Animation-&amp;gt;IK Rig。创建一个Retargeter，需要选择一个IKRig，因为我们需要将AnimStarterPack中的动画序列重定向给UnrealLearningKitGames中的Sk_EpicCharacter。所以这里选择EpicCharacter_IKRig。命名为：Mannequin_Retargeter.如下图所示。 选择目标：LearningKitCharacter_IKRig。 IKRetarget面板 1：管理目标和源的姿势，点击”Edit Mode“可以编辑保存创建姿势，最常用的是T-Pos和A-Pos。如果目标和源的姿势不一样，需要调整其中一个骨骼的姿态尽量和另外一个相似，相似度越高重定向出来的动画越准确。 2：源和目标的骨骼列表。 3：预览视图。 4：细节面板，在这里可以调整Mesh的偏移值，初始两个Mesh有可能重叠。通过调整偏移值使两个Mesh分开。 5：骨骼链列表和动画序列列表。通过骨骼链列表可以查看骨骼链的映射情况，也可手动更改。通过点击动画序列可以预览重定向后的动画。 调整两个Skeletal mesh的姿态，使其最大程度重叠，是重定向动画成功的关键。进入编辑模式后通过调整指定骨骼的旋转等值，如下图所示。 调整到你认为满意的时候，选中需要重定向的动画序列，点击”Export Selected Animations&amp;quot;导出动画序列。 </description>
    </item>
    <item>
      <title>Gameplay游戏框架</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/gameplay%E6%B8%B8%E6%88%8F%E6%A1%86%E6%9E%B6/</link>
      <pubDate>Mon, 03 Jun 2024 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/gameplay%E6%B8%B8%E6%88%8F%E6%A1%86%E6%9E%B6/</guid>
      <description>本节内容 这一节主要讲述在多人游戏中，Gemaplay框架相关各个类是如何处理每个游戏会话中的各种事务的。 GameMode 在多人网络游戏中，GameMode只存在于服务器中。 GameMode可以用来设置游戏中的各个默认类，比如GameState、Default Pawn、HUD、PlayerController等等。除了设置默认类外还有其它丰富的功能，负责游戏规则，比如确定玩家淘汰后会发生什么，以及处理玩家的重生；游戏模式中还可以运行计时器，以便管理比赛的时间。 GameState 在多人网络游戏中，GameState存在于服务器和所有客户端中。由于GameMode只存在于服务器中，那么GameMode中的数据如何传输到客户端呢，GameState可以处理这件事情，它可以将服务器中的数据复制到客户端。GameState更多用于存储游戏状态，比如存储游戏中所有玩家的得分、各个队伍的排名等。 PlayerState 和GameState类似，它也只存在于服务器和所有客户端中。PlayerState只负责处理单个玩家的状态，比如当前玩家的得分、击败数量、身上携带的弹药、属于哪支队伍等。 PlayerController PlayerController存在于服务器和当前本地客户端中。它负责拥有并控制一个Pawn，也可以访问HUD，因此一旦我们有了健康条、得分、击败次数和弹药数量等信息，我们就可以通过PlayerController访问HUD来更新这些信息。 Pawn Pawn其实也就是玩家角色，它存在于服务器和所有客户端中。 HUD 只存在于本地客户端中，HUD负责各种屏幕信息显示，生命条、击败次数、弹药数量等。
总结 在编写游戏时，我们要时刻考虑哪些逻辑应该写在哪个地方，充分利用引擎游戏框架内置好的功能函数才能使编程事半功倍。</description>
    </item>
    <item>
      <title>TAVP虚拟摄影棚数字资产库终端系统用户手册.</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/tavp%E8%99%9A%E6%8B%9F%E6%91%84%E5%BD%B1%E6%A3%9A%E6%95%B0%E5%AD%97%E8%B5%84%E4%BA%A7%E5%BA%93%E7%BB%88%E7%AB%AF%E7%B3%BB%E7%BB%9F%E7%94%A8%E6%88%B7%E6%89%8B%E5%86%8C./</link>
      <pubDate>Sun, 03 Dec 2023 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/tavp%E8%99%9A%E6%8B%9F%E6%91%84%E5%BD%B1%E6%A3%9A%E6%95%B0%E5%AD%97%E8%B5%84%E4%BA%A7%E5%BA%93%E7%BB%88%E7%AB%AF%E7%B3%BB%E7%BB%9F%E7%94%A8%E6%88%B7%E6%89%8B%E5%86%8C./</guid>
      <description>前言 前言：《用户手册》将向用户介绍TAVP虚拟摄影棚数字资产库终端系统（以下简称TAVP客户端）操作方法和TAVP虚拟摄影棚控制系统（以下简称TAVP控制系统）的使用方法。以帮助用户迅速正确的使用该系统。此用户手册将分为两部分：TAVP客户端使用手册和TAVP控制系统使用手册。
功能概述 TAVP虚拟摄影棚数字资产终端系统是时光坐标自主研发的一套能够快速预览、并下载使用数字资产系统，提供了更丰富、更真实、更易用的数字资产集，搭配IPAD控制工具可以实时对数字场景的光影变化进行调整，极大增强了对LED舞台操作的支持，在虚拟拍摄快节奏、高压力环境中，这套系统将极大提高拍摄效率。
TAVP客户端使用手册 在给用户使用此终端系统之前，技术人员需要将系统正确部署在摄影棚的计算机集群中，并调试运行成功。 1、启动软件 双击“TAVPClient.exe”程序，进入软件的登录界面，如图1所示。输入正确的账号密码后，点击登录按钮。如果用户输入的账号密码错误或者是电脑没有宽带网络都会导致登录失败，且提示“账号或密码错误”。
图 1
2、主界面介绍 登录成功后就会进入主界面，首先显示的（1）部分是资产列表页，显示所有已经上传的资产，每个资产包含缩略图、名称、类别。，（2）部分是菜单，可以切换“资产列表”页和“我的资产”页。（3）部分表示搜索栏，支持模糊搜索。（4）部分表示资产类型筛选。（5）部分表示连接状态，绿色表示连接正常，红色表示连接失败。如图2所示。
图 2 3、资产详情页 点击任意一个资产就会进入资产详情页，包含资产的预览缩略图、简介，出品方等信息，点击获取按钮即可将此资产添加到“我的资产”页中。如图3-2所示。 图 3 4、我的资产页 我的资产页中显示所有已经获取的资产，每个资产有若干个状态，比如下载、下载中、解压中、打开、关闭。如图4所示。此系统支持将资产添加到下载队列以及断电续传，下载过程中会显示进度，下载完毕后资产下方状态图标会变为打开状态。在一起准备就绪后，就可以点击打开任意一个场景了。根据场景的大小以及摄影棚配置的不同，打开场景的时间不同，点击打开按钮后，LED大屏会处于黑屏状态，此时要等待一段时间。
图 4
TAVP终端系统使用常见问题排查方法 1、登录失败：点击登录按钮提示“账号或者密码错误” ** 排查方法：** （1）、再三确认输入的账号密码是否正确（注意大小写）； （2）、检查PC主机是否接入了宽带网络； （3）、检查配置文件“TavpConfigInfo.ini”中的“tavp.ServerAddress”字段是否被修改过，默认服务器地址为：“http://123.60.70.27:80/”，配置文件通常在软件的根目录。（这一项通常由技术人员排查） 2、登录成功后右上角显示“连接失败” ** 排查方法：** （1）、检查各个渲染机器是否开始了TAVPListener服务器。 （2）、配置文件“TavpConfigInfo.ini”中的tavp.PrescribdRoute字段值是一个资产存储路径，检查此路径下是否有名为“TAVPNdisConfig”的文件。（这一项通常由技术人员排查） （3）检查“TAVPNdisConfig”的文件中的IP信息是否和摄影棚渲染机设备的IP是否一致。（这一项通常由技术人员排查） 3、点击打开按钮后LED屏幕长时间黑屏 ** 排查方法：** （1）、大场景一般都开的时间都比较长，请耐心等待。（例如四季森林在横店的打开时间为90秒） 3、点击打开按钮后ＬＥＤ屏幕没有反应 ** 排查方法：** （1）、请查看TAVPListener服务器上的log信息。（这一项通常由技术人员排查）
４、下载过程中网络中断或者是意外断电：再次打开软件可继续之前的进度下载。 ５、LED远程控制系统无法控制调整TAVP终端系统打开的场景 ** 排查方法：** （1）、请检查运行LED远程控制程序的IPAD连接的无线网络是否和渲染主机处于同一个局域网内。通俗讲就是是否连接的是同一个ｗｉｆｉ。
５、使用TAVP终端系统打开场景后，使用动捕的Tracker不能驱动内视锥 ** 排查方法：** （1）、请检查运行动捕（例如：青瞳）的机器有没有打开动捕的服务器和客户端 （2）、如果动捕的客户端已经打开，请检查动捕客户端软件中是否能够识别的处于摄影棚中的刚体Tracker。
TAVP控制系统使用手册 功能概述 TAVP控制系统主要是为了实现远程控制虚拟场景中的一些环境以及LED中的其它参数。例如环境颜色和灯光氛围。 客户端 1、进入软件输入运行UE4实例的主机IP地址，点击连接进入控制页面，如图1-1所示。 图 5
2、默认进入颜色校正界面，控制的是场景中的后处理相关参数，可依次控制整个场景中的全局部分、阴影部分、中间调部分、高光部分。其中每个页面包括饱和度、对比度、伽马、增益、偏移和曝光等，如图５所示。此外还可以控制整个场景的曝光，如图６所示，可控参数有曝光基数、最大亮度和最小亮度以及自适应的的速度值。 图 6 图 7 3、下一页面是灯光控制页面，主要控制UE4场景中的环境部分，其中包括天光、太阳光、大气雾等。天光部分可以控制的包括：HDR、强度、旋转和颜色；太阳光可以控制的包括：强度、色温、旋转；大气雾可以控制的包括：大气雾浓度、半衰减值、透明度和颜色；如图8、9、10所示。
图 8 图 9 图 10</description>
    </item>
    <item>
      <title>如何剥离UE4独立程序</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E5%A6%82%E4%BD%95%E5%89%A5%E7%A6%BBue4%E7%8B%AC%E7%AB%8B%E7%A8%8B%E5%BA%8F/</link>
      <pubDate>Fri, 03 Nov 2023 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E5%A6%82%E4%BD%95%E5%89%A5%E7%A6%BBue4%E7%8B%AC%E7%AB%8B%E7%A8%8B%E5%BA%8F/</guid>
      <description>引言： 什么是引擎独立应用程序?让我们首先看一下虚幻引擎的Launcher运行器。不知道大家是否曾经好奇， 虚幻引擎的Launcher运行行器是用什么写的呢?如果你曾经仔细观察过虚幻引擎的运行器的文件结构，你会惊讶地发现，这个文件结构非常类似于虚幻引擎本身的文件结构，而非虚幻引擎编译打包形成的游戏的文件结构。这意味着，虚幻引擎的运行器是一个微型虚幻引擎，而不是一个打包形成的游戏! 如何开发这样的东西呢?如果我们希望在-个小型的、不是游戏的应用程序中继续使用虚幻引擎的一部分API，那么我们就需要学习虚幻引擎运行器这样的技术。&amp;mdash;此段引言自：《大象无形 虚幻引擎程序设计浅析》（如何开发一个简易版的独立程序后面再写，也可以参考这本书的第十四章）
如何剥离独立程序：
《大象无形》这本书中讲解了一种方法：一个最简单的方式就是去\Engine\Binaries\Win 64文件夹下找到Blank Program .exe，拷贝到你的Epic运行器文件夹对应目录。没错， 就是虚幻引擎那个登录账号的运行器的目录。在笔者电脑上， 它位于Epic Games\Launcher\Engine\Binaries\Win 64。双击一下，你依然会发现程序能正常工作，验证了笔者的说法：你的程序不需要依赖一个引擎也能运行。
但这种方法到目前为止貌似行不通了，我目前使用的版本是UE4-425源码版本，按照书本上的方法，点击应用程序发现会闪退。 另外一种比较笨的方法：直接拷贝文件。去\Engine\Binaries\Win 64文件夹下找到你的EXE程序，将它按照源目录拷贝出去。例如：我这里创建的独立程序是一个服务器，起名为“DbServer”，则可以创建一个名为“DbServer”的文件夹（其实名称随意），但需要在这个文件夹下按照一定的文件夹结构进行创建，结构示意如图1-1所示：相关文件都要去引擎源码对应目录下去找。这样独立应用程序就可以运行了。 </description>
    </item>
    <item>
      <title>使用UE4_DS服务器实现房间功能</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E4%BD%BF%E7%94%A8ue4_ds%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%AE%9E%E7%8E%B0%E6%88%BF%E9%97%B4%E5%8A%9F%E8%83%BD/</link>
      <pubDate>Fri, 03 Nov 2023 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E4%BD%BF%E7%94%A8ue4_ds%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%AE%9E%E7%8E%B0%E6%88%BF%E9%97%B4%E5%8A%9F%E8%83%BD/</guid>
      <description>引言： 如何为你的游戏加入房间系统，可以进行加入、创建、搜索、销毁等功能？这段时间一直在查找相关的资料并不断进行各种测试，最终选择了配合UE4原生的DS服务器做房间系统。提到房间功能首先想到的是UE4的“Session”节点，使用“Create Session”等节点可以快速在局域网内搭建自己的房间系统，但是如果需要接入网络的话就比较麻烦，无论是选择“Online Subsystem Steam”还是选择“epic onLine Server”都是比较有难度的，当然后者应该是最优选择，它们内部都集成了房间、匹配、语音等比较完善的功能。我这边选择DS服务器采用“创建进程”方式来做房间系统，原因就是比较简单，对于新手来说是比较容易理解和入门的。下面主要记录一下开发房间系统的一些过程。
DS服务器 DS服务器是UE4的专属服务器，服务器代码和游戏逻辑代码是写到一块的，关于如何打包DS服务器可以参考UE官方文档“（设置专属服务器）。 https://docs.unrealengine.com/4.27/zh-CN/InteractiveExperiences/Networking/HowTo/DedicatedServers/
每启动一次DS服务器就相当于开启一个新的进程，也可以理解为创建了一个房间，那么我们可以通过启动多个DS服务器来做房间系统，客户端可以通过IP和端口号来加入DS服务器，也就是房间，端口号是自动分配的，我们需要手动指定，并不能和其它进程的端口重复即可。那么思路就明确了，在点击创建房间按钮的时候，需要启动一个DS服务器程序，并在代码中指定好端口，点击加入房间的时候，使用IP和端口号进入房间。退出房间就销毁进程。
启动本地可执行程序 那么我们如何通过代码来启动外部程序呢？这里提供两种方式，第一种就是使用C标准库&amp;lt;stdlib.h&amp;gt;中的system()函数执行命令，和在CMD命令行中执行命令相似，执行结果如图1-1所示。参考链接如下。 https://www.runoob.com/cprogramming/c-function-system.html
1 2 3 4 5 6 7 8 9 10 11 12 13 #include &amp;lt;stdio.h&amp;gt; #include &amp;lt;string.h&amp;gt; #include&amp;lt;stdlib.h&amp;gt; int main () { char command[50]; strcpy( command, &amp;#34;ls -l&amp;#34; ); system(command); return(0); } 还有一种方式是使用UE4原生模块“runtime”中的一个函数“FPlatformProcess::CreateProc()”，使用方法如下代码所示， #include&amp;quot;../Runtime/Core/Public/GenericPlatform/GenericPlatformProcess.h&amp;quot;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 void AMyProject2Character::TestOpenExe(FString URL, FString Params) { Handle_ = FPlatformProcess::CreateProc(*URL, *Params, true, false, false, nullptr, 0, nullptr, nullptr); //Handle_ = &amp;amp;currHandle; //FPlatformProcess:: UE_LOG(LogTemp, Warning, TEXT(&amp;#34;URL:::%s&amp;#34;), *URL); } void AMyProject2Character::TestCloseExe() { //FProcHandle currHandle = FPlatformProcess::CreateProc(*URL, nullptr, true, false, false, nullptr, 0, nullptr, nullptr); if (Handle_.</description>
    </item>
    <item>
      <title>关于UE4动态加载LoadClass使用日志</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E5%85%B3%E4%BA%8Eue4%E5%8A%A8%E6%80%81%E5%8A%A0%E8%BD%BDloadclass%E4%BD%BF%E7%94%A8%E6%97%A5%E5%BF%97/</link>
      <pubDate>Fri, 03 Feb 2023 17:23:10 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E5%85%B3%E4%BA%8Eue4%E5%8A%A8%E6%80%81%E5%8A%A0%E8%BD%BDloadclass%E4%BD%BF%E7%94%A8%E6%97%A5%E5%BF%97/</guid>
      <description>UCPT_HomePage继承自UUserWidget，在某个函数下使用LoadClass加载Content下的蓝图资产：
1 2 3 4 void UCPT_HomePage::ConstructRecentProjectPanel(TArray&amp;lt;FString&amp;gt; TRecentProjectInfo) { TSubclassOf&amp;lt;UCPT_UnitProjectButton&amp;gt; UnitProjectButton = LoadClass&amp;lt;UCPT_UnitProjectButton&amp;gt;(nullptr, TEXT(&amp;#34;/Game/Blueprints/UI/UnitUI/WPT_UnitProjectButton.WPT_UnitProjectButton_C&amp;#34;)); } BUG：这样写在编辑器状态下没问题，可以正常加载资产，UnitProjectButton有效。但是打包后，UnitProjectButton是空的，也就是说无法加载指定路径的资产。（已验证：蓝图路径没问题，确实存在） 原因：搜索发现，导致此BUG的原因是，由于WPT_UnitProjectButton资产没有被外界引用，比如蓝图没有被显式引用（如直接拖入关卡或被资源表单引用），可能会被 Unreal 的打包流程优化掉。 解决方案：确保资源被打包了。 方案1：显式引用资源:在任意代码模块的构造函数中引用蓝图路径来确保加载。例如，添加一个加载步骤来触发依赖打包：
1 2 3 4 5 6 7 8 9 UCPT_HomePage::UCPT_HomePage(const FObjectInitializer&amp;amp; ObjectInitializer) :Super(ObjectInitializer) { ConstructorHelpers::FClassFinder&amp;lt;UUserWidget&amp;gt; WPT_UnitProjectButton(TEXT(&amp;#34;/Game/Blueprints/UI/UnitUI/WPT_UnitProjectButton.WPT_UnitProjectButton_C&amp;#34;)); if (WPT_UnitProjectButton.Succeeded()) { UnitProjectButton = WPT_UnitProjectButton.Class; } } 方案2：使用 Cooking 设置加载资源 打开 Project Settings -&amp;gt; Packaging -&amp;gt; Advanced Settings。 在 Additional Asset Directories to Cook 添加你的 UnitUI 目录 (/Game/Blueprints/UI/UnitUI)。</description>
    </item>
    <item>
      <title>云服务器中VC&#43;&#43;和Wamp的环境配置</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%ADvc&#43;&#43;%E5%92%8Cwamp%E7%9A%84%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/</link>
      <pubDate>Tue, 03 Jan 2023 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%ADvc&#43;&#43;%E5%92%8Cwamp%E7%9A%84%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/</guid>
      <description>引言： 最近我的腾讯云服务器快到期了，正好看到腾讯云正在搞活动，新用户有很大优惠，就注册了一个新的账户，花了将近二百买了一个三年期限的轻量级服务器（2核4G），打了0.4折，还是非常值的。这样就需要把在老服务器上面部署的分布式和网站数据迁移到新的服务器上。简单找了一下好像不能跨账户进行镜像共享，所以只好从头开始配置服务器环境了，这里也正好记录一下。
可以了解到什么： 配置VC++运行环境 安装设置Wamp集成环境 服务器的防火墙设置 配置Mysql环境，使本地可以Ping通并访问Mysql数据库 安装“Navicat Premium”并建立连接
配置VC++运行环境 一个新的系统在初次打开EXE可执行程序时有可能会报错丢失各种“Dll”库，解决方法有很多，可以去网上下载对应的DLL并将其放到合适的位置，一般Win系统可以放在“C:\Windows\System32”下，这个需要根据自己系统的位数来定；也可以去下载继承环境的包，直接点击运行即可，我这里提供一个window服务器依赖环境的程序包（程序包见文章末尾的链接），点击运行进行相关操作即可，具体步骤如图１－１所示，先点击检测并修复，若此时运行EXE还是报错，就点击工具－选项－扩展－开始扩展，它会扩展基本的C++数据包。如果运行的是UE４打包出来的程序，当系统中缺少相关环境时，UE４的打包程序会自动启动一个安装VC++２０１５的程序。如果这些方法都不行，就装一个VS，勾选上C++相关选项即可。
图１－１
安装部署Wａｍｐ集成环境： 介绍 Wamp是Windows下的Apache+Mysql/MariaDB+Perl/PHP/Python，一组常用来搭建动态网站或者服务器的开源软件。软件网上即可下载，文章末尾的链接中也有软件安装包
安装 官网下载安装包，安装Wamp，安装过程中如果有提示窗口直接点“否”即可。
启动 管理员运行Wamp，软件会启动三个服务程序，全部启动成功后右下角图标会变成绿色，一般新的系统配置完成后，会直接变成绿色。
wamp图标变为橙色 如果是红色或者是橙色则是只启动了一个或两个服务，如果你的系统中之前装有Mysql服务的话，可以去任务管理器中的“详细信息”中找到相关程序（例如：“mysqld.exe”）选中后将其结束任务，然后再重启Wamp即可。
还有可能是因为80端口被占用导致的，比如这台服务器之前部署过本地的Web服务，都会导致80端口被占用，最直接的解决方案是找到Windows的IIS管理器，关闭所有服务，或者更改服务的端口，具体步骤如下： （1）、快捷键win+R 输入compmgmt.msc(打开计算机管理)，找到IIS，点击进入界面，如图所示：
（2）、选择网站，单击右键，可以停止服务，也可以选择“编辑绑定”，修改成其它端口，如下图所示：
设置wamp服务自启动 如果是云服务器可以不用设置自启动，因为服务器可以一直开着。如果是在本地部署的Wamp，想自启动的话可以按照以下步骤设置。 尝试过在C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp中放入wamp程序的快捷方式，测试发现程序并没有自启动，取消管理员运行也未能成功。尝试了多种方法，发现下面这个方案可行。 Win+R输入services.msc，会弹出服务面板，找到“wampapache64&amp;quot;,&amp;ldquo;wampmariadb64&amp;rdquo;,wampmysqld64&amp;quot;，单击右键，选择属性，在启动类型一栏中选择”自动“。设置好后重新启动计算机，你会发现右下角并没有wamp的图标，但是当你再次打开服务面板时你会发现这三个服务已经开启了，你可以测试访问一下本地的web服务。
服务器的防火墙设置 1、在你的服务器上找到防火墙，我这里用的是腾讯云的服务器，点击添加规则，添加3306端口，一般服务器中会有MySQL的预设直接选择就行（如图１－２所示），这样在MySQL配置正确的情况下，其他客户端就可以链接MySQL服务器了。 ２、如果你需要其他的规则，可以添加自定义的。我这里就添加了UDP协议类型，端口是自定义的，但不能重复，我这里是为了测试一个游戏的服务器使用的临时端口。 图１－２
配置Mysql 1、更改密码 初次部署好的WａｍｐServer，Mysql是没有密码的，首先进入命令台修改一下密码，默认用户名都是ｒｏｏｔ。点击MySQL找到MySQLconsole，进入命令行，如图１－３所示。 进入命令行后，它会提示输入密码，初始是没有密码的，直接点击空格即可（确保之前没有改过密码），更改密码的MySQL语句为： update mysql.user set authentication_string=password(&amp;rsquo;&amp;rsquo;) where user=&amp;rsquo;&#39;;
需要注意的是不要使用下面这条语句，因为５.７版本的MySQL已经没有password这个字段了，改为了authentication_string update user set password=PASSWORD(&amp;lsquo;要修改的密码&amp;rsquo;) where user=&amp;lsquo;root&amp;rsquo;;
完整的语句如下：
mysql -u root -p Enter password: ******** Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 12 Server version: 5.</description>
    </item>
    <item>
      <title>在UE4中使用WebSocket</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E5%9C%A8ue4%E4%B8%AD%E4%BD%BF%E7%94%A8websocket/</link>
      <pubDate>Sat, 03 Dec 2022 17:23:10 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E5%9C%A8ue4%E4%B8%AD%E4%BD%BF%E7%94%A8websocket/</guid>
      <description>前言 这一节会介绍WebSocket协议，和在UE4中如何使用WebSocket进行通讯。引擎中内置了现成的WebSockets模块和第三方库“libWebSockets”，接下来会调用现有模块来创建两个插件，分别负责创建WebSocket服务器和WebSocket客户端。 为什么是WebSocket
介绍 WebSocket是一种全双工、双向通信协议，设计用于在单个TCP连接上进行实时通信。 WebSocket特点 1、双向通信：客户端和服务器可以在任何时间相互发送消息，而不需要轮询或长轮询。 2、低延迟：因为它建立在TCP连接之上，并且避免了HTTP请求和响应的开销，WebSocket通信具有较低的延迟。 3、持久连接：WebSocket连接一旦建立，可以持续使用，直到客户端或服务器主动关闭连接。 工作原理 1、握手阶段：WebSocket通信开始时，客户端发起一个标准的HTTP请求，包含一些特殊的头信息，表明它希望升级到WebSocket协议。 2、协议升级：如果服务器支持WebSocket协议，它会通过HTTP响应确认升级请求。完成握手后，HTTP连接升级为WebSocket连接。 3、数据传输：握手完成后，客户端和服务器之间可以通过WebSocket协议进行全双工通信，可以传输文本和二进制等格式消息。
使用场景 WebSocket协议适用于需要实时更新和低延迟的应用，如： 1、即时通讯：如聊天应用和消息系统。 2、实时通知：如股票价格更新、体育比分等。 3、在线游戏：需要快速、频繁的状态更新。 4、协同编辑：如多人同时编辑文档、表格等。 和HTTP区别 1、HTTP有一个缺陷就是通讯只能由客户端发起，它们只能单向请求，如果客户端需要监测服务器中会连续变化的某一参数，我们只能使用“轮询”，即没隔一段时间就发送一个查询请求，这种轮询效率比较低，且浪费资源。 2、WebSocket连接一旦建立，客户端和服务器都可以主动发送消息给彼此，即它是一种双向通讯。
总结 WebSocket协议提供了一种高效、低延迟的双向通信方式，适用于需要实时数据传输的应用场景。通过WebSocket，客户端和服务器可以在单个持久TCP连接上自由地交换数据，而不必受到传统HTTP请求/响应模式的限制。 客户端实现 Unreal Engine中的“Runtime/Online/下有一个”WebSocket“模块，模块中的IWebSocket接口提供了客户端常用的功能，连接、关闭、发送消息等。 1、创建插件后在.Build.cs中加入”WebSockets“模块
1 2 3 4 5 6 7 8 PublicDependencyModuleNames.AddRange( new string[] { &amp;#34;Core&amp;#34;, &amp;#34;WebSockets&amp;#34;,. } ); 2、我这里创建一个继承自UObject的类：UWSClients。WSClients.h实现如下： /********************************************************* *
@copyright @author Imrcao @date 2024年06月27日16:25:00 @brief 创建一个WebSocket客户端，支持Win64，Win32，IOS，MacOS，Linux平台 @See **********************************************************/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #pragma once #include &amp;#34;CoreMinimal.</description>
    </item>
    <item>
      <title>UTexture2D转二进制数据</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/utexture2d%E8%BD%AC%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%95%B0%E6%8D%AE/</link>
      <pubDate>Thu, 03 Nov 2022 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/utexture2d%E8%BD%AC%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%95%B0%E6%8D%AE/</guid>
      <description>想要在网络中传输媒体资源，就需要将媒体资源转为二进制数据。这里以简单的图片为例，将UE4中的UTexture2D资产转为TArray类型。这篇笔记不详细讲原理，只放代码。
**读取图片的颜色信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 bool UTextureToolsBPLibrary::TextureToColorData(TArray&amp;lt;FColor&amp;gt;&amp;amp; colorDataPtr, int&amp;amp; outW, int&amp;amp; outh, UTexture2D* Texture) { colorDataPtr.</description>
    </item>
    <item>
      <title>跨账户迁移个人网站数据</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E8%B7%A8%E8%B4%A6%E6%88%B7%E8%BF%81%E7%A7%BB%E4%B8%AA%E4%BA%BA%E7%BD%91%E7%AB%99%E6%95%B0%E6%8D%AE/</link>
      <pubDate>Mon, 03 Oct 2022 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E8%B7%A8%E8%B4%A6%E6%88%B7%E8%BF%81%E7%A7%BB%E4%B8%AA%E4%BA%BA%E7%BD%91%E7%AB%99%E6%95%B0%E6%8D%AE/</guid>
      <description>引言：最近要换服务器，需要将部署在旧服务器上的数据迁移到新的服务器上。咨询了腾讯云的客服，由于我是跨账户迁移且两个账户的地域不一致，所以不能使用共享镜像的方式，那就只能手动迁移数据了。每个人使用的环境和工具不同，方法自然也不同，下面主要整理一下步骤以及记录一下在这个过程中遇到了一些问题。
步骤： 1、服务器wordpress(网站)本地数据的拷贝； 2、MySQL数据库数据迁移（巨坑）； 3、MySQL数据表wp_options中部分字段数据更改； 4、进入WordPress后台； 5、网站备案迁移； 6、新服务器上的备案迁入和备案变更； 7、域名重新解析； 8、等待备案完成（1-3个工作日）；
1、服务器wordpress(网站)本地数据的拷贝； 我这里使用的wampserver集成环境，环境配置建议查看文章(服务器VC++和Mysql环境置)。首先去旧服务器上在wamp的安装目录中找到“www”文件夹，压缩并拷贝到新服务器的wamp对应的目录下。如图1-1所示；
图1-1
2、MySQL数据库数据迁移（巨坑）； 数据库的迁移按道理说是非常简单的，直接导出、运行sql文件就行了，但不知道是什么原因运行sql文件的时候总是报错导致数据和结构都进不来，我这里用的MySQL版本为5.7.24，使用版本“5.5.5-10.3.12-MariaDB”就可以直接运行同一个sql文件，很诡异，不想改变版本的情况下只能再想其它办法迁移数据了。 尝试了很多方法，最后长到了一种勉强可以用的方法吧，为什么说是勉强可以用呢，因为它还是不能完美的把数据和结构迁移过来。使用“导出”的方式，如图2-1所示，有很过格式供你选择，多尝试几个格式发现其中两个格式还是挺好用的分别为“.mdb”和&amp;quot;.dbf&amp;quot;。 在导入的时候要注意：“源表”和“目标表”要一致，如图2-2所示。如果在新服务器中的数据库中没有这个数据表，则在“新建表”下会打对勾✔，表示会新建一个MySQL数据表。 最后你可能还会发现数据导入丢失和数据表结构不对，此时我是手动调整的，如果你有好的方法欢迎私信交流。对于数据丢失的情况可以手动复制粘贴，如图2-3所示。数据表结构不对的话可以手动进行复制和粘贴。 总之，无论用什么方法，最终目的就是将旧服务器中MySQL的数据迁移到新的服务器中。
图2-1
图2-2
图2-3
3、MySQL数据表wp_options中部分字段数据更改； 数据迁移完毕后找到数据表“wp_options”，找到字段“option_name”和“option_value”，更改“siterul”和“home”对应的值为“http://127.0.0.1”，如图3-1所示：
图3-1
4、进入WordPress后台； 更改完毕后就可以在浏览器中输入“http://127.0.0.1”进入主页，输入“http://127.0.0.1/wp-login.php”进入登录页面，输入之前WordPress的账户和密码就可以进入wordpress后台。如图4-1所示。 图4-1
5、网站备案迁移； 以上步骤就完成了数据的迁移，目前网站只能在服务器上的本地运行查看，还不能通过域名进入。因为账号换了所以备案也需要迁移，进入旧服务器中的控制台，找到备案-&amp;gt;更多-&amp;gt;迁移备案账号，如图5-1所示。输入相关信息即可。
图5-1
6、新服务器上的备案迁入和备案变更； 备案迁移完成后，在新服务器中就可以看到备案信息了，此时备案中的信息还是之前服务器中的公网IP，要改成现在服务器的公网IP，需要“变更备案”，如图6-1所示。这个过程输入的资料和信息还是很多的。
图6-1
7、域名重新解析； 变更备案完成后，最后需要对域名进行重新解析，如图7-1所示
图7-1
8、等待备案完成（1-3个工作日）； 等待备案完成后即可通过域名访问自己的网站了。</description>
    </item>
    <item>
      <title>如何使用腾讯云短信API发送验证码</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E8%85%BE%E8%AE%AF%E4%BA%91%E7%9F%AD%E4%BF%A1api%E5%8F%91%E9%80%81%E9%AA%8C%E8%AF%81%E7%A0%81/</link>
      <pubDate>Mon, 03 Oct 2022 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E8%85%BE%E8%AE%AF%E4%BA%91%E7%9F%AD%E4%BF%A1api%E5%8F%91%E9%80%81%E9%AA%8C%E8%AF%81%E7%A0%81/</guid>
      <description>前言： （写在前面的一些废话）最近在写给手机发送短信的一个功能，之前一直在用“创蓝253短信平台”，调用起来也是非常简单，根据域名构建一个Http请求即可。但是最近这个平台对签名审核变得非常的严格且对一些平台和APP是不发的（应该是因为这些小平台的安全性没有做好，才会这么严格），申请的时候还需要 APP的下载地址、官网、设计图纸等等，付款还需要公对公，这对于我们这些独立开发者来说很不友好，我提供了公司的营业执照（一个朋友的空壳公司）和部分APP的设计图纸（做的一个交友类小游戏），申请了三四次都给我驳回了，联系客服又给我说交友类、棋牌类游戏不发（一万个草泥马）。决定还是研究腾讯的短信服务吧，但是腾讯的短信API调用起来不是一般的麻烦（由于腾讯的SDK不支持在Windows环境，所以只能硬着头皮调用API了）。下面主要记录一下在调用腾讯短信API中的一些主要步骤。
最终目的： 使用UE4调用腾讯的发送短信API，给手机发送短信。
介绍腾讯云短信服务及用“API Explorer&amp;quot;在线发送验证码 官方文档上有详细的文档说明，这里就不多赘述，这里主要是总结一下用法。我用的V3.0版本的API，使用 API的核心就是通过一些加密算法构建“签名串”，这个签名串用于构建HTTP请求，加密算法主要用的是“Opessll库”里面的部分函数，这个库的用法我单独写了一篇文章，参考“在Windows下配置Openssl环境”。 在测试阶段推荐使用“API Explorer”，这个可以在线发送验证码，生成签名串。发送验证码需要开通短信服务并申请签名和签名模板，还要申请腾讯SDK的秘钥和 ID（每个用户最多申请两个秘钥和 ID，）这部分官方文档有详细步骤，参考我当时发送的界面如图1-1所示。“API Explorer”生成的签名串可以用来验证你的生成签名串的程序，如图1-2所示。
使用&amp;quot;Postman&amp;quot;测试发送Http/Https请求 在使用C++编写HTTP请求之前，可以先使用软件“Postman”发送测试请求，以确保请求串没有错误。使用方法如图1-3所示： 使用纯C++项目生成“签名串” 创建一个C++的空项目，添加一个CPP文件后，将官网的代码粘贴进去（官方文档链接：https://cloud.tencent.com/document/product/382/52072#C.2B.2B），参考文章“在Windows下配置Openssl环境”配好环境后，还需要改一个名叫“get_data”函数，如下面示例所示，之后应该就可以编译通过了。官网示例使用的接口不是发送短信接口，所以需要稍微改动一下代码。发送短信的部分改动代码如下：
函数改动： string get_data(int64_t&amp;amp; timestamp) {
int64_t ii = 1231232133; string utcDate; char buff[20] = { 0 }; //改动了这里，牵扯到time_t类型的初始化 time_t timenow = (time_t)(timestamp);
1 2 3 4 5 6 7 8 9 10 11 struct tm sttime; //sttime = *gmtime(&amp;amp;timestamp); gmtime_s(&amp;amp;sttime, &amp;amp;timenow); //gmtime_s(, ); strftime(buff, sizeof(buff), &amp;#34;%Y-%m-%d&amp;#34;, &amp;amp;sttime); utcDate = string(buff); return utcDate; } SendSms接口，生成字符串所必要的一些参数： // 密钥参数 string SECRET_ID = &amp;ldquo;AKI**evvfCU&amp;rdquo;; string SECRET_KEY = &amp;ldquo;3pLaZrkNkFTQ6VdU5PS&amp;rdquo;;</description>
    </item>
    <item>
      <title>UE4 windows打包IOS 踩坑记录</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue4-windows%E6%89%93%E5%8C%85ios-%E8%B8%A9%E5%9D%91%E8%AE%B0%E5%BD%95/</link>
      <pubDate>Sun, 03 Jul 2022 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue4-windows%E6%89%93%E5%8C%85ios-%E8%B8%A9%E5%9D%91%E8%AE%B0%E5%BD%95/</guid>
      <description>经本人完整踩坑之后，已经成功在windows PC上将UE4项目打包IOS。本文主要记录踩坑过程，并介绍在Windows PC上将UE4 项目打包IOS 的方法，包含配置证书、配置Mac，编译及打包等几个方面。 一般的，UE4开发主要在win平台进行，主要原因是渲染和平台支持优于Mac。到了打包时，仅蓝图的ios项目可以在window进行编译及打包（此方法本文不做说明），而C++ ios项目必须在Mac机器进行编译及打包，所以这就决定了Windows开发，Mac打包的主要路线。 那么，我们先要有台Mac机器，如果没有，那就只能先在Windows上安装Mac虚拟机。如果有，直接跳过步骤一
一、Mac虚拟机的安装 1、下载安装VMware15.5 链接：https://pan.baidu.com/s/1JeXYaF1gX4knxOs3Me1POw 提取码：wrbf 其他虚拟机能不能安装MacOS 未知，注意使用15版本不要使用16最新版 序列码YG5H2-ANZ0H-M8ERY-TXZZZ-YKRV8 2、用Unlocker解锁 使用大佬魔改过的MK Unlocker，下载解压后（可以不放入VMware安装文件夹）右键“以管理员身份打开” win_install.cmd，让它自己进行就好了，这个版本应该不会有问题。
此时成功解锁之后，安装虚拟机时可以有MacOS选项 下载MacOS镜像 macos 10.15下载： 下载链接：点击下载 提取码：spc4
1 2 本人下载的是Catalina10.15.1.cdr 版本，不过后来启动之后直接来了一场更新， 可以到这里找一下较新的镜像文件。 安装虚拟机的过程不在赘述，有一点就是分配硬盘时不要分配动态空间，选择直接分配，不然后续MacOS 无法在此虚拟硬盘完成安装，具体原因不清楚。 MacOS虚拟机安装完成之后，就相当于有Mac机啦 接着马上安装Xcode，重要！
二、证书 证书和描述文件的配置也不做太多赘述，搜索一下文章一大堆，这里主要说一下关键点。证书的配置需要在UE4中和Mac机都完成配置，配置好之后大概如下两图： 三、配置远程Mac 1、在Mac系统中，系统偏好设置-共享 打开远程登录选项，并选择所有用户 2、UE4中 项目设置-平台-IOS-构建 远程服务名处可输入远程mac登录名 或者IP地址 用户名处输入mac用户名。 点击生成SSH键，生成工程中要设置此SSH的密码，建议直接摁回车，不设置密码。 此SSH可共享给其他人，那么其他人也可以连接此远程Mac进行打包
四、远程打包 此时，在UE4中打包项目 选择IOS 竟然打开了浏览器及UE4帮助文档。。。 1、安装Itunes 和Windows Store？ 搜索之后发现还需要在Windows中安装Itunes，据说是因为需要使用Itunes的Mac SDK? 本人之前在Itunes官网进行了下载及安装，安装完成之后发现没有用，点击打包依然打开了浏览器？ 经过多方搜索后，发现需要在Windows Store 安装Itunes？？？ UE4的这一步操作实在是不太懂。 那就照做把，然而当我卸载掉Itunes，打开了windows主菜单，发现没有Windows Store。。。 大概是因为现在大部分win10系统镜像都删除了应用商店把。 尝试多种安装Windows Store方法后，发现此方法是唯一可行的： Windows LTSC、LTSB、Server 安装 Windows Store 应用商店</description>
    </item>
    <item>
      <title>更新日志之LivelinkVRPN（HTCVive）</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue_427%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97%E4%B9%8Blivelinkvrpnhtcvive/</link>
      <pubDate>Fri, 03 Jun 2022 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue_427%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97%E4%B9%8Blivelinkvrpnhtcvive/</guid>
      <description>前言：UE4-427版本在虚拟拍摄领域迎来了一次大更新，各种工具趋于完善，现场的效率越来越高，其中一项更新就是LiveLinkVRPN插件的引入，之前版本是通过在“配置文件”中读取跟踪设备数据的（例如HTC），现在可以通过这个插件直接获取数据，VRPN服务器还是要一直开着的。 注意事项：（需要打开SteamVR、LivelinkVRPN插件、VRPN服务器）
1、LivelinkVRPN 427中如何使用Vive手柄进行输入 在配置文件中移除了使用VRPN的输入配置，用livelike代替，使用方法： （1）、首先打开SteamVR和VRPN服务器，
（2）、打开UE4编辑器，打开livelike,如图所示添加一个Livelink源，如图所示
IPAddress &amp;ndash; 输入IP地址（需要注意的是后面要加“:3884”端口号）
Device Name &amp;ndash; 输入设备名称（VRPN服务器上的名称，如上图红线所示）
Subject Name&amp;ndash;源名称（ 随便填写）
Type &amp;ndash; 源类型（使用Vive的话，就选Tracker）
（3）、选择刚刚创建的Livelink源，添加一个“Pre Processors”，需要注意的是Livelink的三个轴向。如图所示：
（4）（注意）如果需要在Ndisplay模式下运行的话，需要开启“SteamVR”插件，不然使用SwitchBoard启动的时候，SteamVR会产生崩溃，导致VIVE手柄的位置信息不能进入UE。
（5）、在全部设置好后，将LiveLink设置保存为一个模板，并在项目设置中指定此模板，这样才能在下次启动工程的时候自动接收livelink数据。如图所示： </description>
    </item>
    <item>
      <title>Python和UE4结合建立WebSocket通信</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/python%E5%92%8Cue4%E7%BB%93%E5%90%88%E5%BB%BA%E7%AB%8Bwebsocket%E9%80%9A%E4%BF%A1/</link>
      <pubDate>Thu, 03 Feb 2022 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/python%E5%92%8Cue4%E7%BB%93%E5%90%88%E5%BB%BA%E7%AB%8Bwebsocket%E9%80%9A%E4%BF%A1/</guid>
      <description>前言 最近在做一个直播中用到的小工具，需求是从斗鱼或者虎牙平台中拉去直播的数据（弹幕和礼物等等），并将这些数据实时推流到一个UE4客户端，在客户端中根据这些数据做一些业务逻辑。这里采用的模型是，使用python写数据推流服务器，UE4作为客户端持续接收数据。这里主要记录一下整个过程中遇到的问题。
为什么是WebSocket https://www.ruanyifeng.com/blog/2017/05/websocket.html
PIP（python包管理工具） https://baike.baidu.com/item/PIP/20435212?fr=aladdin
python配置环境变量 https://www.cnblogs.com/huangbiquan/p/7784533.html
在cmd中安装Python工具包（webSocket） https://jingyan.baidu.com/article/86f4a73ea7766e37d7526979.html
在PyCharm中安装Python工具包 https://blog.csdn.net/m0_37332816/article/details/81353659
https://zhuanlan.zhihu.com/p/314507897</description>
    </item>
    <item>
      <title>202110-UE427版本-Ndisplay快速入门</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue427%E7%89%88%E6%9C%AC-ndisplay%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/</link>
      <pubDate>Sun, 03 Oct 2021 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue427%E7%89%88%E6%9C%AC-ndisplay%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/</guid>
      <description>前言：最近虚幻引擎更新到427版本，在影视方面更新了很多的重要的内容，特别是Ndisplay-LED（InVFXCamea）拍摄这一块，用官方的话说，这个版本的Ndisplay是可以用于生产的版本。更新的内容的深度和广度都很大，导致之前的低版本功能无法直接升级到427版本。下面来看一下如何使用新版本的Ndisplay功能。
一、创建工程，部署环境 选择Ndisplay模板，创建一个空的工程，如图1-1所示。
图1-1
选在并打开配置文件“NDC_Basic”，选择“Node_0(Master)”，在细节面板中更改Window的尺寸大小（根据自己显示器分辨率进行调整）；选择“VP_0”，调整投影策略“Projection Policy”，并调整视口大小。如图1-2所示。
图1-2
打开SwitchboardListener，然后再打开Switchboard，如图1-3所示。首次打开会提示安装相关环境，等待安装完毕即可。 （注意）有的时候Switchboard界面弹不出来（点击任务栏图标的时候，总是出现纯白色预览缩略图，就是点出界面，这里无法好像无法截图，只能描述。应该是个bug，后面可能会修复吧），在纯白缩略图上单击右键，选择最大化即可。如图1-4所示。
图1-3
图1-4
创建配置文件：现在打开了Switchboard的监听和客户端，首次打开创建一个新的配置文件，如图1-5所示。配置文件界面如图1-6所示： (注意)ConfigPath是配置文件存储的路径，注意界面上只会显示配置文件名称，不会显示路径，初始应该是默认路径，我这里的完整路径是“D:\Program Files\Epic Games\UE_4.27\Engine\Plugins\VirtualProduction\Switchboard\Source\Switchboard\configs” Uproject和Engine DIr就常规填写项目位置和引擎位置即可。点击ok创建配置文件，如图1-5所示。
图1-5
图1-6
添加Ndisplay节点，点击“AddDevice”选择“Ndisplay”类型，在弹出来的界面上点击“Browse”，选择模板自带的配置文件。如图1-7所示。
图1-7
添加Unreal项目，用于多用户编辑，填写IP地址后点击ok，这里IP填127.0.0.1。如图1-8所示。
图1-8
点击“Settings”，在MultiUserServer一栏下，将AutoJoin勾选上。如图1-9所示
图1-9
8、首先启动Ndisplay节点，先点击链接（1），再点击启动（2）（在启动之前记得将“SteamVR”插件勾选上，不然会造成SreamVR软件的崩溃，如图1-10所示）。在启动Unreal编辑器之前，将Settings-&amp;gt;MultiUserServe-&amp;gt;AutoLunch勾选掉，不用启动Server服务器了（上一次启动过了）。在UnrealDevice下先点击连接（3），再点击启动（4）。如图1-11所示
图1-10
图1-11
到这里就完成了在单个机器上启动Ndisplay和多用户编辑。在编辑器中做出更改，Ndisplay视口中会发生实时的变化。
二、添加InnerVFXCamera(内视锥) 向场景中拖入一个“CineCameraActor”,并将它作为Ndis配置文件“Monitor_1Host_1Node”的子节点（我这里将Ndis配置文件改了名字）。选中CineCameraActor，在细节面板下添加一个“LiveLinkComponentController”，并在属性下指定自己的LiveLink。如图所示2-1所示
图2-1
打开Ndisplay配置文件，添加组件“ICVFXCamera”，
回到世界大纲，选中配置文件，在细节面板中指定刚才拖入的CinCameraActor即可。
关于如何使用Livelink接收数据，请参考文章“” 现在保存退出即可。 根据上述步骤使用Switchboard启动，就可以根据HTCVive手柄驱动内视锥了。
LivelinkVRPN 前言：UE4-427版本在虚拟拍摄领域迎来了一次大更新，各种工具趋于完善，现场的效率越来越高，其中一项更新就是LiveLinkVRPN插件的引入，之前版本是通过在“配置文件”中读取跟踪设备数据的（例如HTC），现在可以通过这个插件直接获取数据，VRPN服务器还是要一直开着的。 注意事项：（需要打开SteamVR、LivelinkVRPN插件、VRPN服务器） 427中如何使用Vive手柄进行输入 在配置文件中移除了使用VRPN的输入配置，用livelike代替，使用方法： （1）、首先打开SteamVR和VRPN服务器，
（2）、打开UE4编辑器，打开livelike,如图所示添加一个Livelink源，如图所示
IPAddress &amp;ndash; 输入IP地址（需要注意的是后面要加“:3884”端口号）
Device Name &amp;ndash; 输入设备名称（VRPN服务器上的名称，如上图红线所示）
Subject Name&amp;ndash;源名称（ 随便填写）
Type &amp;ndash; 源类型（使用Vive的话，就选Tracker）
（3）、选择刚刚创建的Livelink源，添加一个“Pre Processors”，需要注意的是Livelink的三个轴向。如图所示：
（4）（注意）如果需要在Ndisplay模式下运行的话，需要开启“SteamVR”插件，不然使用SwitchBoard启动的时候，SteamVR会产生崩溃，导致VIVE手柄的位置信息不能进入UE。
（5）、在全部设置好后，将LiveLink设置保存为一个模板，并在项目设置中指定此模板，这样才能在下次启动工程的时候自动接收livelink数据。如图所示： IPad控制
1、首先在Content下创建“Remote Control Preset”资产，在“Miscellaneous”下找到此项，创建并命名，如图4-1所示 图4-1
2、双击打开远程控制资源类，在右上角找到“EditMode”打开编辑模式，如图4-2所示，此模式打开后，在世界大纲中选中需要被控制的Actor，选中Actor后就可以在Detail面板中看到各个属性前面有一个小眼睛，选择需要控制的属性，点击小眼睛图标即可，如图4-4所示。 图4-2
3、在图4-2上点击设置图标进入Remote Control设置页面，勾选“Auto Start Web Server”，即项目启动时运行WebServer。如图4-3所示。 图4-3</description>
    </item>
    <item>
      <title>在Windows下配置Openssl环境</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E5%9C%A8windows%E4%B8%8B%E9%85%8D%E7%BD%AEopenssl%E7%8E%AF%E5%A2%83/</link>
      <pubDate>Sun, 03 Oct 2021 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E5%9C%A8windows%E4%B8%8B%E9%85%8D%E7%BD%AEopenssl%E7%8E%AF%E5%A2%83/</guid>
      <description>前言： SSL是Secure Sockets Layer（安全套接层协议）的缩写，可以在Internet上提供秘密性传输。库中包含很多加密函数，可以对数据进行加密。Openssl整个软件包主要包含三部分：SSL协议库、应用程序、密码算法库。下面主要介绍如何在Windows环境下下载安装Openssl，并配置环境，用C++调用其中的部分函数对数据进行加密。测试案例是：生成一个签名串，这个签名串是腾讯云短信服务中“发送短信”API中需要的必要参数。
下载安装： 下载地址：https://slproweb.com/products/Win32OpenSSL.html，我这里选择的版本是“Win64 OpenSSL v1.1.1L”选择了“EXE”格式，如果你的操作系统是32位或者你的项目是32位的话，就选择下载32位的安装包。安装过程比较简单直接点击下一步即可。
配置Windows环境： 配置环境变量：右键单击“我的电脑”-&amp;gt;“属性”-&amp;gt;&amp;ldquo;高级系统设置&amp;rdquo;，在弹窗中找到“高级”-&amp;gt;&amp;ldquo;环境变量&amp;rdquo;，新建环境变量，变量名“Path”，变量值为“C:\Program Files\OpenSSL-Win64\bin”，变量值为安装目录；如图1-1所示； 图1-1
配置VS项目环境： 1、如果要在VS项目中使用SSL库，还需要在VS项目中进行相关设置。我这里使用的是VS2019创建的一个空的C++项目；添加一个“.cpp”文件“Source.cpp”，加入头文件“#include &amp;lt;openssl/sha.h&amp;gt;”和“#include &amp;lt;openssl/hmac.h&amp;gt;”，编译会报错并提示找不到头文件。 2、项目设置：项目-单击右键-属性，在属性面板中找到“VC++ Directories”-&amp;gt;&amp;ldquo;Include Directories(包含目录)&amp;quot;,添加新的目录“C:\Program Files\OpenSSL-Win64\include”；同样在库目录“Library Directories”下也添加一个新的目录“C:\Program Files\OpenSSL-Win64\lib”。如图1-2所示。最后配置静态链接库：选择连接器“Linker”-&amp;gt;输入“Input”-&amp;gt;添加依赖项“Additional Dependercies” 将“libssl.lib、libcrypto.lib”粘贴到空白处，点击确定即可。如图1-3所示。现在再编译项目即可编译通过。到此Openssl的环境配置就完成了，可以尝试调用一下其中的函数，后面会通过一个案例来使用Openssl库。
图1-2
图1-3
在UE4C++项目中使用 在 UE4项目中配置Openssl环境（UE4中引用第三方链接库）。 在UE4项目中无法按照文章“在Windows下配置Openssl环境”配置相关环境，UE4的项目属性中没有“链接器-&amp;gt;输入”，所以无法指定第三方静态链接库。UE4引用第三方静态链接库需要在“.Build.cs”文件中配置。 首先在插件的根目录的下创建文件夹“ThirdParty”，然后去“Openssl”的安装目录下找到文件夹“OpenSSL-Win64”（我这里的目录为“C:\Program Files\OpenSSL-Win64”），最后将这个文件夹复制到“ThirdParty”中，并保留文件夹“Include”、“Lib”两个文件夹，其余全删除。如图1-4所示。
图1-4
在VS工程模块中的“.build.cs”文件中加载第三方静态链接库，代码如下所示。 // Some copyright should be here&amp;hellip; using System.IO; using UnrealBuildTool;
public class SimpleHttp : ModuleRules { /&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;Begin&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;/ private string ModulePath { // get { return Path.GetDirectoryName(RulesCompiler.GetModuleFilename(this.GetType().Name)); } get { return ModuleDirectory; } }
private string ThirdPartyPath { get { return Path.</description>
    </item>
    <item>
      <title>解决UE4万向节锁（Gimbal Lock）的问题</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E8%A7%A3%E5%86%B3ue4%E4%B8%87%E5%90%91%E8%8A%82%E9%94%81gimbal-lock%E7%9A%84%E9%97%AE%E9%A2%98/</link>
      <pubDate>Sun, 13 Jun 2021 11:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E8%A7%A3%E5%86%B3ue4%E4%B8%87%E5%90%91%E8%8A%82%E9%94%81gimbal-lock%E7%9A%84%E9%97%AE%E9%A2%98/</guid>
      <description>一、问题描述 在开发类似飞行类游戏的时候往往需要将相机的旋转范围设置到[-180~180]，但引擎默认会将pitch和roll两个轴向限定到[-90~90]，这并不是一个bug，是引擎为了适配FPS游戏所做的限制，你可以垂直向上或者向下看，超过这个角度就没有意义了且会导致万向节锁的现象，为了避免这种现象我们可以采用四元数的方法。
二、解决步骤 使用的是飞行模板，创建自己的GameMode和Controller和pawn并在worldSettings中设置为我们的GameMode。如图示1.1（注意Pawn类中要加入Camera组件）
1 2 图示1.1 项目设置中添加输入，如图示1.2
1 2 图示1.2 接下来是主要的一步，使用四元数的方法解决万向节锁的现象。为了方便使用，我这里写成了一个插件。如图1.3所示，选择模板“BlueprintLibrary”，创建一个插件。
1 2 图示1.3 打开VS，将如下代码加入到.h和.cpp中。注意：在cpp中将函数名称“UMyFunctionName”替换为自己的类名称。如图1.4所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 public: // 旋转公式:将欧拉角的度数转换为四元数 UFUNCTION(BlueprintCallable, meta = (DisplayName = &amp;#34;Euler To Quaternion&amp;#34;, Keywords = &amp;#34;rotation, quaterion&amp;#34;), Category = &amp;#34;Quaternion Rotation&amp;#34;) static FQuat Euler_To_Quaternion(FRotator Current_Rotation); // 根据输入的四元数设置组件的世界坐标的旋转 UFUNCTION(BlueprintCallable, meta = (DisplayName = &amp;#34;Set World Rotation (Quaterion)&amp;#34;, Keywords = &amp;#34;rotation, quaternion&amp;#34;), Category = &amp;#34;Quaternion Rotation&amp;#34;) static void SetWorldRotationQuat(USceneComponent* SceneComponent, const FQuat&amp;amp; Desired_Rotation); // 根据输入的四元数设置组件的相对旋转 UFUNCTION(BlueprintCallable, meta = (DisplayName = &amp;#34;Set Relative Rotation (Quaterion)&amp;#34;, Keywords = &amp;#34;rotation, quaternion&amp;#34;), Category = &amp;#34;Quaternion Rotation&amp;#34;) static void SetRelativeRotationQuat(USceneComponent* SceneComponent, const FQuat&amp;amp; Desired_Rotation); // 添加本地旋转量 UFUNCTION(BlueprintCallable, meta = (DisplayName = &amp;#34;Add Local Rotation (Quaterion)&amp;#34;, Keywords = &amp;#34;rotation, quaternion&amp;#34;), Category = &amp;#34;Quaternion Rotation&amp;#34;) static void AddLocalRotationQuat(USceneComponent* SceneComponent, const FQuat&amp;amp; Delta_Rotation); // 根据输入的四元数设置Actor的世界坐标的旋转 UFUNCTION(BlueprintCallable, meta = (DisplayName = &amp;#34;Set Actor World Rotation (Quaternion)&amp;#34;, Keywords = &amp;#34;rotation, quaternion&amp;#34;), Category = &amp;#34;Quaternion Rotation&amp;#34;) static void SetActorWorldRotationQuat(AActor* Actor, const FQuat&amp;amp; Desired_Rotation); //根据输入的四元数设置Actor的相对旋转 UFUNCTION(BlueprintCallable, meta = (DisplayName = &amp;#34;Set Actor Relative Rotation (Quaternion)&amp;#34;, Keywords = &amp;#34;rotation, quaternion&amp;#34;), Category = &amp;#34;Quaternion Rotation&amp;#34;) static void SetActorRelativeRotationQuat(AActor* Actor, const FQuat&amp;amp; Desired_Rotation); // 添加本地旋转量 UFUNCTION(BlueprintCallable, meta = (DisplayName = &amp;#34;Add Actor Local Rotation (Quaternion)&amp;#34;, Keywords = &amp;#34;rotation, quaternion&amp;#34;), Category = &amp;#34;Quaternion Rotation&amp;#34;) static void AddActorLocalRotationQuat(AActor* Actor, const FQuat&amp;amp; Delta_Rotation); FQuat UQuaternoinsBPLibrary::Euler_To_Quaternion(FRotator Current_Rotation) { //声明输出四元数 FQuat q; //将度数转换为弧度 float yaw = Current_Rotation.</description>
    </item>
    <item>
      <title>UE4的静态加载和动态加载（引用资源）</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue4%E7%9A%84%E9%9D%99%E6%80%81%E5%8A%A0%E8%BD%BD%E5%92%8C%E5%8A%A8%E6%80%81%E5%8A%A0%E8%BD%BD%E5%BC%95%E7%94%A8%E8%B5%84%E6%BA%90/</link>
      <pubDate>Thu, 03 Jun 2021 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue4%E7%9A%84%E9%9D%99%E6%80%81%E5%8A%A0%E8%BD%BD%E5%92%8C%E5%8A%A8%E6%80%81%E5%8A%A0%E8%BD%BD%E5%BC%95%E7%94%A8%E8%B5%84%E6%BA%90/</guid>
      <description>引言 在日常的开发中会遇到很多使用C++来加载资源的情况，例如我们要引用Content下的蓝图类和非蓝图类，那么在UE4中提供了很多机制来引用这些资源。从网上查到的很多资料来看，很多游戏开发者将这种机制称之为“静态加载”和“动态加载”，但是从官方文档上来看，我并没有搜到静态加载相关的词语，官方将这种机制称之为“硬性引用(HardRefernences)”和“软性应用(SoftReferences)”。在这篇文章中我会把网上的资料和官方资料整理一下，也方便以后查阅。
静态加载-硬性引用 我这里理解的是静态加载和硬性引用一个意思，对应的动态加载和软性引用一个意思。硬性应用由两种场景的情况。 （1）直接属性引用：这是最常见的资源引用情况，通过宏UPROPERTY暴露给蓝图，这样可以允许设计人员在编辑器中指定相关资源。示例代码如下： /** construction start sound stinger */
UPROPERTY(EditDefaultsOnly, Category=Building)
USoundCue* ConstructionStartStinger;
（2）构造时引用：在构造函数引用确切的资源，这里是使用特殊的类ConstructorHelpers完成的，这个类中有两个对应的方法：FObjectFinder()和FClassFinder()，它们分别加载的是非蓝图资产（动画、贴图、模型、音效等）和蓝图类（角色蓝图、Widget控件）资产。示例代码如下：
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 static ConstructorHelpers::FClassFinder&amp;lt;AChatOnline_WFYCharacter&amp;gt; PlayerPawnBPClass(TEXT(&amp;#34;/Game/ChatOnline/WFY_Blueprint/Core/WFY_Character&amp;#34;)); static ConstructorHelpers::FClassFinder&amp;lt;AHUD&amp;gt; PlayerHUDBPClass(TEXT(&amp;#34;/Game/ChatOnline/WFY_Blueprint/Core/ChatOnline_WFYHUD_BP&amp;#34;)); //DefaultPawnClass = AChatOnline_WFYCharacter::StaticClass(); if (PlayerPawnBPClass.Class!=NULL) { DefaultPawnClass = PlayerPawnBPClass.Class; } if (PlayerHUDBPClass.Class!=NULL) { HUDClass = PlayerHUDBPClass.Class; } class UTexture2D* BarFillTexture; static ConstructorHelpers::FObjectFinder&amp;lt;UTexture2D&amp;gt; BarFillObj(TEXT(&amp;#34;/Game/UI/HUD/BarFill&amp;#34;)); BarFillTexture = BarFillObj.Object; （了解更多：在以上构造函数中，ConstructorHelpers 类将尝试在内存中查找该资源，如果找不到，则进行加载。请注意，使用资源的完整路径来指定要加载的内容。如果该资源不存在或者由于出错而无法加载，那么该属性将设置为 nullptr。发生这种情况时，尝试访问纹理的代码将崩溃。最好进行声明，指出资源已正确加载（如果后续代码假设引用有效）。 UPROPERTY 的声明与前面的硬性引用示例相同。它们的工作方式相同，只不过是最初的设置方式有所差别。有关硬性引用的一个注意事项是，当对象加载并实例化时，还将加载以硬性方式引用的资源。您必须仔细地进行考虑，否则内存使用量会因为同时加载许多资源而迅速增加。如果您希望推迟该加载或确定要在运行时加载的内容，那么下列各节可以帮助您完成这些任务。）
动态加载-软性引用 动态加载最常用的两个模板化方法是LoadObject&amp;lt;&amp;gt;()和LoadClass&amp;lt;&amp;gt;()。同样的前者加载非蓝图类资产后者加载蓝图类资产。需要注意的是使用LoadClass时，路径名必须带_C后缀，LoadObject不需要带后缀。示例代码如下： //加载Content目录下的资源文件 UTexture2D* SpeackCheck; UTexture2D* MicCheck; //方法一： SpeackCheck = LoadObject(nullptr, TEXT(&amp;quot;/Game/ChatOnline/WFY_Textture/Icon/Speaker_Check&amp;quot;));</description>
    </item>
    <item>
      <title>浮点型数据转换为网络字节序</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E6%B5%AE%E7%82%B9%E5%9E%8B%E6%95%B0%E6%8D%AE%E8%BD%AC%E6%8D%A2%E4%B8%BA%E7%BD%91%E7%BB%9C%E5%AD%97%E8%8A%82%E5%BA%8F/</link>
      <pubDate>Thu, 03 Jun 2021 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E6%B5%AE%E7%82%B9%E5%9E%8B%E6%95%B0%E6%8D%AE%E8%BD%AC%E6%8D%A2%E4%B8%BA%E7%BD%91%E7%BB%9C%E5%AD%97%E8%8A%82%E5%BA%8F/</guid>
      <description>前言： 最近在写使用UE4联动“六轴平台”的控制程序，这里就用到了机器硬件交互和计算机网络相关的知识。拿到硬件厂商的网络协议后，就要根据协议编写相关代码，下面记录一下开发过程。
网络字节序： 首先要明白和机器通讯中所传输的数据一般为字节流，即网络字节序，顾名思义就是字节的顺序。一般系统都会采用 UDP协议，UDP的好处就是机器只管接收就行。
进行 UDP广播： 在开始前，你需要了解如何使用UE4进行 UDP广播数据，你可以参考这篇文章“使用UE4原生模块进行简单UDP广播和数据接收”。
float转字节序： 直接上代码：这个函数可以将float类型的数据转为unsigned char类型的数组。 /*
Describe:将float类型数据转换为unsigned char数组（即网络字节序） Paramfvalue待转换数据 Paramarr传入的字节序 ParamIndex从数组的第几位开始转换，默认为0 **/ 1 2 3 4 void AUDPSend::ftoc(float fvalue, int Index, unsigned char* arr) { unsigned char* pf; unsigned char* px; unsigned char i; //计数器 pf = (unsigned char*)&amp;amp;fvalue; /unsigned char型指针取得浮点数的首地址/ px = arr; /字符数组arr准备存储浮点数的四个字节,px指针指向字节数组arr/ for (i = Index; i &amp;lt; Index + 4; i++) { *(px + i) = *(pf + (i - Index)); /使用unsigned char型指针从低地址一个字节一个字节取出/ }</description>
    </item>
    <item>
      <title>使用SaitekX52接入到UE4</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E4%BD%BF%E7%94%A8saitekx52%E6%8E%A5%E5%85%A5%E5%88%B0ue4/</link>
      <pubDate>Thu, 03 Jun 2021 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/%E4%BD%BF%E7%94%A8saitekx52%E6%8E%A5%E5%85%A5%E5%88%B0ue4/</guid>
      <description>介绍： 罗技的赛钛克手柄（logitech-saitak X52）主要用于飞行类游戏，使用这个飞行控制器模拟飞行具有不错的体验。虚幻引擎作为一个游戏引擎应该也支持这类手柄，但虚幻引擎并不能做直接接收赛钛克手柄输入（不像XBox360，它可以直接输入进引擎）。下面记录一下如何使用Saitek手柄接入到虚幻引擎。
环境： 虚幻引擎425、Saitek X52
步骤一 首先安装Saitek X52控制器驱动，可以去官网下载（官网见：参考资料）。下载好的驱动直接点击安装即可。 安装好驱动后打开“设备管理器”，找到“人体学输入设备”，在下拉列表中找到对应的控制设备，打开“属性-&amp;gt;详细信息-&amp;gt;-硬件ID”。“VID_”后面的“06A3”和“PID_”后面的“075C”分别为品牌ID和设备ID。如图1-1所示。这两个值为16进制数，记下这两个值，后面引擎中会用到。
图1-1
步骤二 使用虚幻引擎蓝图版本的飞机模板（Flying），在Plugins中找到并勾选插件“Windows Rawinput”，重启后在项目设置中找到“Plugins-&amp;gt;Raw Input”。插件“Windows RawInput”提供了八个轴向的输入和二十个按钮输入。 添加一个设备配置插槽，Vendor ID和Product ID分别填入“0x06A3”和“0x075C”。在属性添加一个轴向属性，勾选上“Enable”和“Gamepad stick”。勾选上“Gamepad stick”的意思是让输入变为“-1到1”而不是“0-1”。如图2-1所示。 打开“Engine-&amp;gt;Input”，在轴向映射下面的“MoveUp”一栏添加刚刚的一个轴向输入“GenericUSBController Axis 1”。如图2-2所示。这样手柄就可以进行输入了。
图2-1
图2-2
三、下面记录一下八个轴向的输入和二十个按钮输入对应关系，如图3-1所示。 图3-1
四、Saitek X52支持的一些游戏，如图4-1所示。 图4-1
参考资料： saitek官网： https://www.logitechg.com/en-gb/products/space/x56-space-flight-vr-simulator-controller.945-000059.html
论坛： https://forums.unrealengine.com/t/3-new-plugins-joystick-hotas-support-blueprint-easing-functions-saitek-x52-pro/6620
官方文档 https://docs.unrealengine.com/4.26/zh-CN/InteractiveExperiences/Input/RawInput/</description>
    </item>
    <item>
      <title>UE4-VIrtualCamera2.0源代码浅析</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue4-virtualcamera2.0%E6%BA%90%E4%BB%A3%E7%A0%81%E6%B5%85%E6%9E%90/</link>
      <pubDate>Mon, 03 May 2021 17:03:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue4-virtualcamera2.0%E6%BA%90%E4%BB%A3%E7%A0%81%E6%B5%85%E6%9E%90/</guid>
      <description>VirtualCamera是虚幻引擎中的工程示例项目。虚幻引擎4.26版本中将其升级到了2.0（Beta版本），功能和UI都全面更新（如图1-1所示）。虚拟摄像机在虚幻引擎中驱动电影摄像机（Cine Camera），它能够将结果输出到各种外部设备中。我使用它主要用来拍摄镜头预演。 演示连接：https://www.bilibili.com/video/BV195411w75h/
图1-1
VirtualCamera如何在输出上覆盖自定义的UMG控件
我这边采用的是“BlackMagic”采集卡（型号：）通过SDI线将画面传输到监视设备。根据引擎自带的“BlackMagic”插件是能够将画面采集并输出到监视设备的，但并不能将“UMG”控件采集并输出。“VirtualCamera”中可以实现这样的功能。下面简单分析一下这一块的逻辑是如何执行的。 UMG是在Vcam组件属性中OutputPrivider中指定的，打开源码找到对应的文件 VcamOutputProviderBase.h。简单阅读一遍后很容易就能发现逻辑是从初始化函数“Initialize()”开始执行的，经过一系列判断后一次执行“Acitvate()”、“CreateUMG()”和“DisplayUMG()”。具体代码如下：
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 void UVCamOutputProviderBase::CreateUMG() { if (!</description>
    </item>
    <item>
      <title>20191004-UE4C&#43;&#43;实现异步批量加载资源</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue4c&#43;&#43;%E5%AE%9E%E7%8E%B0%E5%BC%82%E6%AD%A5%E6%89%B9%E9%87%8F%E5%8A%A0%E8%BD%BD%E8%B5%84%E6%BA%90/</link>
      <pubDate>Tue, 04 Jun 2019 15:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/ue4c&#43;&#43;%E5%AE%9E%E7%8E%B0%E5%BC%82%E6%AD%A5%E6%89%B9%E9%87%8F%E5%8A%A0%E8%BD%BD%E8%B5%84%E6%BA%90/</guid>
      <description>目的：异步加载指定路径下的所有Texture2D资源，并将它们显示到WIdget的Image上，每隔一定时间更新一次图片。
知识点包括：1、获取UI组件，2、获得场景中的Actor,3、实现异步批量加载资源，4、UE4定时器使用
一、分别创建继承自UUserWidget和AActor的C++类，UWealthWidget和AWealthActor。 基于UWealthWidget创建一个蓝图UWealthWidget_BP,在蓝图控件中创建Image命名为TexImage。
二、回到VS中，UWealthWidget.h中代码如下： 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #pragma once #include &amp;#34;CoreMinimal.h&amp;#34; #include &amp;#34;Blueprint/UserWidget.h&amp;#34; #include &amp;#34;WealthWidget.generated.h&amp;#34; class UImage; class UOverlay; UCLASS() class FRAMECOURSE_API UWealthWidget : public UUserWidget { GENERATED_BODY() public: //利用UE4反射机制获得UMG中的控件，这里的名字一定要和蓝图中创建的Image的名字一致。 UPROPERTY(Meta = (Bindwidget)) UImage* TexImage; public: //重载父类的初始化函数 virtual bool Initialize() override; //加载2D图片 void AssignTexture(UTexture2D* InTexture); }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 UWealthWidget.</description>
    </item>
    <item>
      <title>Slate定制样式</title>
      <link>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/slate%E5%AE%9A%E5%88%B6%E6%A0%B7%E5%BC%8F/</link>
      <pubDate>Mon, 03 Jun 2019 17:23:09 +0800</pubDate>
      <guid>https://imrcao.top/posts/%E5%BD%92%E6%A1%A3/slate%E5%AE%9A%E5%88%B6%E6%A0%B7%E5%BC%8F/</guid>
      <description>一：Slate定制样式 （一）预期效果：用Slate写一个控件，它的样式所用的美术资源默认是从本地加载的，创建一个SlateWidgetStyle能够从项目中加载美术资源（Content文件夹下的资源）。 如下图所示，用slate写的控件可以像UMG一样很容易的设置美术资源。 （二）实现步骤：（开始前已经用Slate写好了一个控件） （1）、创建C++类：MySlateWidgetStyleContainerBase（类创建好后UE4会报错，不用管它，重启一下就好了） （2）、自己定义类的名称和路径后，在VS中打开
1 2 在.h文件中，如下图： 后面创建 SlateWidgetStyle的时候，会选择下面这个类创建。 FMyWidgetStyle是一个结构体，如下图所示： 1 2 在.cpp中有结构体FMyWidgetStyle中函数的相关实现，如下图： （3）获取样式。slate样式制作好后，就是如何获取到FMyWidgetStyle。
在负责生成具体控件的类中获取slate样式FMyWidgetStyle。（最后创建slate样式的时候，样式的名称一定要和这里的名称“MyWidgetStyle_BP”一样。而且需要在指定的目录下创建，具体的路径是在负责slate样式的类中指定的。）
（4）在UE4插件自己生成的负责控件样式的类中，更改资源的加载方式，如下图所示： （一定要在指定的路径下创建slate样式）
（5）、编译代码，启动程序。在UE4中指定的路径下创建slate Widget Style:单击右键-&amp;gt;选择UserWidget-&amp;gt;选择slate Widget style。在弹出来的对话框中选择，我们自己创建的C++样式类：UTaskWidgetStyle （6）最后自己添加美术资源进行测试： </description>
    </item>
  </channel>
</rss>
