用户指南

概述

EthernetIPForUE v1.0.1.1 是一个在 Unreal Engine 5.0~5.7 中实现 EtherNet/IP (CIP) 协议的插件。它使 UE 项目能够与工业 PLC、机器人控制器及其他 EIP 兼容设备通过标准 TCP/IP 网络进行通信。

插件支持两大角色,各角色下可创建多个命名实例,每个实例独立连接不同的设备

Adapter(服务端)

UE 作为 EIP 设备,等待外部 Scanner 连接。支持两种协议:

协议 实例类 说明
Assembly UEIPAssemblyAdapter 暴露固定长度的 Assembly 数据缓冲区
Tag UEIPTagAdapter 暴露按名称读写的 Tag 标签(CIP Symbol 服务)

Scanner(客户端)

UE 作为扫描器连接远程 EIP 设备。支持两种协议:

协议 实例类 说明
Assembly UEIPAssemblyScanner 通过 Assembly 实例号循环读写
Tag UEIPTagScanner 通过 CIP Symbol 服务按名称读写标签

快速入门

1. 启用插件

  1. 打开 UE 项目
  2. 进入 编辑 → 插件
  3. 搜索 "EthernetIPForUE" 并勾选 已启用
  4. 重启编辑器

2. 启动 Adapter(UE 作为服务端)

通过 UEIPAdapterManager 创建并启动一个 Adapter 实例:

Event BeginPlay
    → GetGameInstance → Get EIP Adapter Manager
    → GetAssemblyAdapter("MyAdapter")
    → Start(Port: 44818)

适配器开始监听端口 44818。外部 EIP 扫描器可以连接并读写数据。

同时启动多个 Adapter(不同端口):

→ GetAssemblyAdapter("RobotArm")   → Start(44818)
→ GetTagAdapter("SensorHub")       → Start(44819)

3. 启动 Scanner(UE 作为客户端)

通过 UEIPScannerManager 连接远程设备:

→ GetGameInstance → Get EIP Scanner Manager
→ GetAssemblyScanner("PLCMain")
→ SetConnectionParams("192.168.1.100", 44818)
→ Start()

4. 管理实例

方法 说明
GetAssemblyAdapter(Name) 获取或创建 Assembly Adapter
GetTagAdapter(Name) 获取或创建 Tag Adapter
GetAssemblyScanner(Name) 获取或创建 Assembly Scanner
GetTagScanner(Name) 获取或创建 Tag Scanner
Del(Name) 删除指定实例
DelAll() 删除所有实例
GetActiveNames() 获取所有活跃实例名称列表
GetActiveCount() 获取活跃实例数量

实例通过 UPROPERTY 持有,不会被 GC 回收。Del(Name) 从管理器移除后自动进入回收队列。

5. 读写数据

所有实例名称(Name/TagName)均为 FName 类型。

Assembly Adapter(服务端) — 读写远程 Scanner 写入/读取的数据缓冲区:

方法 说明
ReadFloat(ByteOffset) 从输入缓冲区读取浮点数(Scanner 写入的数据)
ReadFloat16(ByteOffset) 从输入缓冲区读取半精度浮点数
ReadInt32(ByteOffset) 从输入缓冲区读取 32 位整数
ReadInt16(ByteOffset) 从输入缓冲区读取 16 位整数
ReadByte(ByteOffset) 从输入缓冲区读取字节
ReadBool(ByteOffset, BitIndex) 从输入缓冲区读取布尔值
ReadRaw(ByteOffset, Count) 从输入缓冲区读取原始字节序列
WriteFloat(ByteOffset, Value) 写入浮点数到输出缓冲区(Scanner 读取的数据)
WriteFloat16(ByteOffset, Value) 写入半精度浮点数到输出缓冲区
WriteInt32(ByteOffset, Value) 写入 32 位整数到输出缓冲区
WriteInt16(ByteOffset, Value) 写入 16 位整数到输出缓冲区
WriteByte(ByteOffset, Value) 写入字节到输出缓冲区
WriteBool(ByteOffset, BitIndex, Value) 写入布尔值到输出缓冲区

Assembly Scanner(客户端) — 读写远程设备的 Assembly 数据缓冲区:

方法 说明
WriteFloat(ByteOffset, Value) 写入浮点数到远程设备
WriteFloat16(ByteOffset, Value) 写入半精度浮点数到远程设备
WriteInt32(ByteOffset, Value) 写入 32 位整数到远程设备
WriteInt16(ByteOffset, Value) 写入 16 位整数到远程设备
WriteByte(ByteOffset, Value) 写入字节到远程设备
WriteBool(ByteOffset, BitIndex, Value) 写入布尔值到远程设备
ReadFloat(ByteOffset) 从远程设备读取浮点数
ReadFloat16(ByteOffset) 从远程设备读取半精度浮点数
ReadInt32(ByteOffset) 从远程设备读取 32 位整数
ReadInt16(ByteOffset) 从远程设备读取 16 位整数
ReadByte(ByteOffset) 从远程设备读取字节
ReadBool(ByteOffset, BitIndex) 从远程设备读取布尔值
ReadRaw(ByteOffset, Count) 从远程设备读取原始字节序列

Tag Scanner(客户端)

方法 说明
ReadTag(TagName) 按名称读取标签(FName
WriteTag(TagName, Value) 按名称写入标签(FName

Tag Adapter(服务端)

方法 说明
RegisterTag(TagName, InitialValue) 注册一个外部可访问的标签(FName
SetTagValue(TagName, Value) 设置标签值(FName
GetTagValue(TagName) 获取标签值(FName

管理器参考

UEIPAdapterManager

管理器,管理所有 Adapter 实例。

方法 返回类型 说明
GetAssemblyAdapter(Name) UEIPAssemblyAdapter* 获取或创建 Assembly Adapter 实例
GetTagAdapter(Name) UEIPTagAdapter* 获取或创建 Tag Adapter 实例
Del(Name) void 停止并删除指定名称的实例
DelAll() void 停止并删除所有实例
GetActiveNames() TArray<FName> 获取所有活跃实例名称
GetActiveCount() int32 获取活跃实例数量

所有实例名称参数(Name)为 FName 类型。

UEIPScannerManager

管理器,管理所有 Scanner 实例。

方法 返回类型 说明
GetAssemblyScanner(Name) UEIPAssemblyScanner* 获取或创建 Assembly Scanner 实例
GetTagScanner(Name) UEIPTagScanner* 获取或创建 Tag Scanner 实例
Del(Name) void 停止并删除指定名称的实例
DelAll() void 停止并删除所有实例
GetActiveNames() TArray<FName> 获取所有活跃实例名称
GetActiveCount() int32 获取活跃实例数量

所有实例名称参数(Name)为 FName 类型。


组件参考

UEIPLinkComponent

挂载到任意 Actor 上。通过 ByteOffset 或 DataBind 索引读写绑定的 Scanner 实例。

属性:

属性 默认值 说明
ScannerName Default 绑定的 Scanner 实例名称(传给 GetAssemblyScanner/GetTagScanner),FName 类型
SubsystemType Assembly 绑定的子系统类型(Assembly / Tag)
ReadInstance 100 读取实例号
WriteInstance 101 写入实例号
UpdateInterval 0.0 数据更新间隔(秒),0 = 每帧
DataBinds 数据绑定列表(ByteOffset + DataType + Scale + Offset),每帧自动读取
InitialBufferSize 24 原始值缓冲区初始大小,DataBinds 超出时自动扩展

事件:

事件 说明
OnEIPConnected 连接成功时触发
OnEIPDisconnected 断开连接时触发
OnDataUpdated 数据更新时触发
OnEIPError 发生错误时触发

逐字节读取方法:

  • GetFloatValue(ByteOffset)
  • GetFloat16Value(ByteOffset)
  • GetIntValue(ByteOffset)
  • GetInt16Value(ByteOffset)
  • GetBoolValue(ByteOffset, BitIndex)
  • GetByteValue(ByteOffset)

逐字节写入方法:

  • WriteFloatValue(ByteOffset, Value)
  • WriteFloat16Value(ByteOffset, Value)
  • WriteIntValue(ByteOffset, Value)
  • WriteInt16Value(ByteOffset, Value)
  • WriteByteValue(ByteOffset, Value)
  • WriteBoolValue(ByteOffset, BitIndex, Value)

DataBind 索引读取方法:

方法 说明
GetItem(Index) 获取单个 DataBind 条目的原始字节缓冲区
GetItems() 获取所有 DataBind 条目的原始字节缓冲区
GetValueAsFloat(Index) 获取 DataBind 索引处的值(float,已应用 Scale/Offset)
GetValueAsInt(Index) 获取 DataBind 索引处的值(int32)
GetValueAsInt64(Index) 获取 DataBind 索引处的值(int64)
GetValuesAsFloat() 获取全部值(float 数组,索引与 DataBinds 对齐)
GetValuesAsInt() 获取全部值(int32 数组)

内部通过 UEIPScannerManagerGetAssemblyScanner(ScannerName)GetTagScanner(ScannerName) 进行读写。

UEIPAnimLinkComponent

继承自 UEIPLinkComponent。添加了每帧平滑值缓存,支持可配置的插值速度。

属性 默认值 说明
MonitorLinks 监视链接数组(ByteOffset + DataType + Scale + Offset)
InterpSpeed 10.0 FInterpTo 插值速度(0 = 无平滑)
CachedValues (只读)平滑后的值缓存

全局配置 (v1.0.1.1+ 灵活模式)

v1.0.1.1 开始,配置系统转向更自由的使用方式。UEIPGlobalConfig 是一个 BlueprintType 的 UObject,你可以在蓝图中创建、修改配置对象,再传递给 Scanner/Adapter 使用。

核心类:UEIPGlobalConfig

配置对象可通过 GetEipConfig(Key) 获取命名单例(Key 默认为 "Default"),自动从 Config/EIPConfig.ini 加载/保存。

蓝图方法 说明
GetEipConfig(Key) 获取命名配置单例(不存在则创建)
LoadFromFile() EIPConfig.ini 加载(缺失字段保持默认值)
SaveToFile() 保存到 EIPConfig.ini

所有字段均可通过 BlueprintReadWrite 在蓝图编辑器中直接修改。

Scanner 用法(推荐)

两种方式任选:

方式一 — 蓝图加载配置传递给 Scanner:

→ GetEipConfig("PLC1")                     // 获取命名配置
→ Set AssemblyIPAddress / AssemblyPort / ...  // 可选:在蓝图中修改
→ GetAssemblyScanner("PLCMain")
→ LoadConfig("PLC1")                        // 从 Config 加载参数
→ Start()                                   // 启动连接

LoadConfig(Key) 会自动读取对应配置对象的 Assembly 连接参数(IP、端口、Assembly ID、缓冲区大小等)。找不到预设时会写出当前配置到文件。

方式二 — 手动设置参数(适合简单场景):

→ GetAssemblyScanner("PLCMain")
→ SetConnectionParams("192.168.1.100", 44818, 100, 101)
→ Start()

Adapter 用法

Adapter 更简单,直接指定端口启动即可:

→ GetAssemblyAdapter("RobotArm")
→ Start(44818)

Tag Adapter 同理:

→ GetTagAdapter("SensorHub")
→ Start(44819)

Adapter 的端口号也可通过 UEIPGlobalConfig.AdapterPort 管理,但非必须。

你也可以自己管理 Config

UEIPGlobalConfig 是普通的 UObject,你可以完全自行控制:

  • 创建后手动设置字段,调用 SaveToFile() 持久化
  • 下次运行时调用 GetEipConfig(Key) 自动加载
  • 多个命名配置对应 INI 文件中的不同节([EIPGlobalConfig_PLC1][EIPGlobalConfig_PLC2]

配置字段一览

分类 字段 默认值 说明
Assembly AssemblyIPAddress 127.0.0.1 目标设备 IP
Assembly AssemblyPort 44818 目标端口
Assembly ReadAssemblyID 100 读取实例号
Assembly WriteAssemblyID 101 写入实例号
Assembly AssemblyBlockSize 256 数据块大小
Assembly AssemblyOutBufSize 256 输出缓冲区大小
Assembly AssemblyInBufSize 256 输入缓冲区大小
Assembly bAssemblyAutoReconnect true 自动重连
Assembly AssemblyReconnectDelay 3.0 重连延迟(秒)
Assembly AssemblySyncPeriod 0.1 同步周期(秒)
Adapter AdapterPort 44818 监听端口
Adapter AdapterBlockSize 512 数据块大小
Adapter bAdapterAutoStart false 自动启动
Tag TagIPAddress 192.168.1.1 目标设备 IP
Tag TagPort 44818 目标端口
Tag bTagAutoReconnect true 自动重连
Tag TagSyncFrequencyHz 10.0 同步频率(Hz)
Tag TagRequestTimeout 5.0 请求超时(秒)

配置文件路径:<项目>/Config/EIPConfig.ini,每个命名配置对应一个独立节([EIPGlobalConfig_<Key>])。向后兼容旧的 [EIPGlobalConfig] 节。


版本历史

版本 变更
1.0.1.1 ⚠️ 与 1.0.0.x 不兼容!
增加了多 Adapter、多 Scanner 支持
重构为多实例架构:管理器管理多个命名实例,FString 全面更换为 FName
新增 Tag Adapter 支持(UEIPTagAdapter
删除旧单例子系统(旧版 GetEIP*Subsystem 方法已移除)
Adapter 数据 API:SetBufferData/ReadBufferDataReadFloat/WriteFloat 等类型化方法
Scanner 数据 API:WriteValue/ReadValueWriteFloat/ReadFloat 等类型化方法
GetActiveNames() 返回类型从 TArray<FString> 改为 TArray<FName>
Scanner/Adapter/Tag 实例类属性 InstanceName 改为 FName
增加了对位的读写操作功能(ReadBool/WriteBool 支持 BitIndex)
UEIPLinkComponent 新增 ScannerNameFName,默认 "Default")、DataBinds、事件、DataBind 索引读取
将 Config 从子系统中分离出来,让用户更自由的控制
UEIPGlobalConfig 作为 BlueprintType UObject,通过 GetEipConfig(Key) 多命名配置,支持 LoadFromFile()/SaveToFile()
GetEipConfig 参数从 FString 改为 FName
Scanner 启动方式改为 SetConnectionParams(...)Start()Start() 不再传参)
1.0.0.6 修复 FSocket 跨平台兼容性(WinSock2 → UE Socket API)
1.0.0.5 初始 Fab 发布版本

重要说明

  • 端口冲突: 每个监听实例需要独立端口。确保没有其他服务占用。
  • 防火墙: Windows 防火墙可能阻止端口。如需入站连接,请为 UE 编辑器进程添加入站规则。
  • Assembly 实例约定: Scanner 从实例 100(默认)读取,写入实例 101(默认)。
  • 线程安全: 所有读取 API 线程安全。蓝图调用始终在主线程执行。
  • 平台: 仅支持 Windows(Win64)。使用 UE5 Socket API,跨平台兼容。
  • GC: 实例由管理器通过 UPROPERTY 持有,不会被垃圾回收。