1. 蓝图接口

内容浏览器中,右键→蓝图→蓝图接口,定义蓝图接口,双击蓝图接口进入界面,可以点击细节 (Detail) 添加函数 (Function)

接口的函数可以没有参数,也可以在细节继续添加传入参数。

① 声明方法

关卡蓝图或者物体蓝图细节,可以搜索上面定义的接口名字添加接口注意添加之后要编译蓝图,此时我的蓝图中,就会出现接口中的函数 (假设其中一个函数的名字为 Action )

右键事件图表,搜索 Action,即可找到出==添加事件====的 Event ActionBPI Remote ActivableActionAction (Message) :

特性 (Feature) Event Action (K2Node_Event_0)(事件节点) Action (K2Node_CallFunction_23) (函数调用节点) Action (Message) (K2Node_Message_1) (消息节点)
节点类 (Node Class) /Script/BlueprintGraph.K2Node_Event /Script/BlueprintGraph.K2Node_CallFunction /Script/BlueprintGraph.K2Node_Message
所属蓝图 (Owning BP) 物体关卡 物体关卡 物体关卡
相关接口/函数 Action (来自 BPI_RemoteActivable_C) Action (来自 BPI_RemoteActivable_C) Action (来自 BPI_RemoteActivable_C)
主要作用 (Role) 实现/接收 Action 事件 调用/发送 Action 接口函数 调用/发送 Action 接口函数
如何激活 (Activation) 当此蓝图实例的 Action 事件被外部调用时 当其自身的 "execute" (执行) 输入引脚被激活时 当其自身的 "execute" (执行) 输入引脚被激活时
"Target" / "Self" 引脚 不适用 (隐式为当前蓝图实例 self) 输入引脚 (self),类型为 BPI_RemoteActivable_C 接口 (指向调用目标) 输入引脚 (self),类型为通用 Object 对象引用 (指向消息目标)
关键属性 (Key Attribute) bOverrideFunction=True (表明它覆盖/实现接口事件) bIsInterfaceCall=True (表明它是一个接口调用) bIsInterfaceCall=True (表明它是一个接口调用)
输出执行 ("then") 当事件被触发后,从此引脚开始执行后续逻辑 函数/消息成功调用/发送后,从此引脚开始执行后续逻辑 函数/消息成功调用/发送后,从此引脚开始执行后续逻辑
使用场景 (Use Case) 定义当 物体关卡接收到 Action 消息时应该做什么 物体关卡内部向另一个对象发送 Action 消息 物体关卡内部向另一个对象发送 Action 消息
现代性/推荐性 事件实现的唯一方式 调用接口函数的现代、类型安全方式 调用接口函数的较旧但仍有效的方式

总结来说:

② 外部调用方法

关于启动 UE 服务器的端口和方法,物体或关卡的路径,其他文章和官方文档有详细说明:

( 1 ) UE 服务器的端口和方法:

文章:远程控制

索引文档:虚幻引擎远程控制 | 虚幻引擎 5.4 文档 | Epic Developer Community

远程控制快速入门 (如何启动服务器) :虚幻引擎远程控制快速入门 | 虚幻引擎 5.4 文档 | Epic Developer Community

API | HTTP 参考:虚幻引擎的远程控制APIHTTP参考 | 虚幻引擎 5.4 文档 | Epic Developer Community

( 2 ) 物体或关卡的路径:

文章:远程控制

下面是是示例代码:

import requests
import json

# 定义请求URL
url = "http://localhost:30010/remote/object/call" 
# Web Remote Control API 端点 (使用哪个api端点详情见上述文章)

# 物体或者关卡的运行时路径 (如何找到路径详情见上述文章)
level_script_actor_path = "/Path/Location"

# 定义请求体
payload = {
    "objectPath": level_script_actor_path,
    "functionName": "Action",  # 接口函数名字
    "parameters": {}           # 现在是没有参数的情况
}

# 若有,改为"parameters": {
#        "parameter_1": value_1, 
#        "parameter_2": value_2,  
#        "parameter_3": value_3,
#        ...
#    }
# 参数名字必须和接口中定义的一致

headers = {
    "Content-Type": "application/json"
}

print(f"Attempting to call function '{payload['functionName']}' on object: {payload['objectPath']}")
try:
    # 发送PUT请求 (使用什么方法请求详情见上述文章)
    response = requests.put(url, data=json.dumps(payload), headers=headers)
    
    # 打印响应状态码
    print(f"Response Status Code: {response.status_code}")

    # 检查响应状态
    if response.status_code == 200:
        print("Request successful!")
        print("Response content:")
        try:
            # 尝试将响应内容解析为JSON并格式化打印
            print(json.dumps(response.json(), indent=4, ensure_ascii=False))
        except json.JSONDecodeError:
            # 如果响应不是有效的JSON
            print("Response body is not valid JSON, raw text:")
            print(response.text)
    else:
        print(f"Request failed, Status Code: {response.status_code}")
        print("Response content (raw text):")
        print(response.text)
        
except requests.exceptions.RequestException as e:
    print(f"An error occurred during the request: {e}")
except Exception as e:
    print(f"An unexpected Python error occurred: {e}")