<?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>UE4 on 云笺小筑</title>
    <link>https://imrcao.top/tags/ue4/</link>
    <description>Recent content in UE4 on 云笺小筑</description>
    <generator>Hugo -- 0.122.0</generator>
    <language>zh-cn</language>
    <lastBuildDate>Wed, 03 Jun 2026 17:23:09 +0800</lastBuildDate>
    <atom:link href="https://imrcao.top/tags/ue4/index.xml" rel="self" type="application/rss+xml" />
    <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>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>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>关于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>在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>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>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>解决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>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>
  </channel>
</rss>
