插件
官方
商城
Python Editorhttps://www.fab.com/listings/f4c99ba0-1a86-4f6a-b19d-2fd13f15961b
GitHUB
好像只更新到了2020年4.2x的版本。可能有大佬改了5.x的版本。也希望分享给我一份。谢谢
https://github.com/20tab/UnrealEnginePython
学习笔记
网上教程一大堆。边学边写。学会到哪写到哪。哪天不更新了。就是这个笔记又太监了。写的不对的地方喷的时候也麻烦轻点。
Sequencer中的Python脚本https://dev.epicgames.com/documentation/zh-cn/unreal-engine/python-scripting-in-sequencer-in-unreal-engine?application_version=5.0
UE 使用Python控制Sequencehttps://zhuanlan.zhihu.com/p/13347612063
这下面这个文档解释的比较细:
UE5 中用 Python 接口创建 Level Sequence 与设置 TriggerEvent-腾讯云开发者社区-腾讯云遇到了一个美术需求,需要批量读取一段动画,制作成 UE 中的 Level Sequence,然后给动画添加几个 Event Track。随后,需要在 Event Track 中添加 Trigger Event,设置插件 uDraper 布料的缓存数据路径。总之,最终效果如下:https://cloud.tencent.com/developer/article/2146577
跟着学的案例
目前还没“复刻”成功=复制粘贴都不行.gif:
复刻成功=没学会:
1.这个Json文件少了个]。其他按照他这个做基本能复刻。
UE5 Python脚本自动化Sequence Key帧_ue sequnece python-CSDN博客
2.Json(latitude,longitude,elevation)= Python(uex,uey,uez)。因为我没有PythonEditor所以改成了固定的main方式。
【UE4】Python读取Json数据创建对应关卡序列_json设计关卡-CSDN博客
Json相关
读取(祖传代码)
(filename = 外部输入的名字)特别要注意的是Json格式问题。
#def JsonGetData(filename):
# 读取/项目目录/JsonFile中的JSON文件数据存入json_data
root_path = unreal.SystemLibrary.get_project_directory() + 'Content/Json/'
final_path = root_path + filename + '.json'
fp = open(final_path, 'r', encoding='utf-8')
json_str = fp.read()
json_data = json.loads(json_str)
unreal.log("=== INFO: Json Get OK ===")
return json_data
报这个错误就是Json格式出现问题了。
JSON在线 | JSON解析格式化—SO JSON在线工具
解析
示例
"commands": [
{
"commandtype": "Create",
"objectcreateinfo": {
"object": {
"id": "1",
"objecttype": "myship"
},
"propertys": [
{
"key": "DisplayName",
"value": "我的船",
"propertytype": "String",
"displaystring": "我的船"
}
],
#读取各项数据创建关键帧
commands = json_data["commands"]
#循环获取commands里面的数据
for index in range(0,len(commands)):
#for command in commands:
#json中commandtype为Create时执行
if commands[index]["commandtype"] == "Create":
# 获取到"commands->objectcreateinfo->object->objecttype"这一层是否等于myship
if commands[index]["objectcreateinfo"]["object"]["objecttype"] == "myship":
Main方法
没有这个函数的话。直接右键运行是不会执行任何东西的。
//有这个右键脚本运行才能有效
if __name__ == '__main__':
create()
python获取场景中的actor
# 获取Actor子系统以抓取选定的Actor
actor_system = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
# 获取选定的Actor
actor = actor_system.get_selected_level_actors()[0]
# 将Actor作为可拥有物添加到关卡中
actor_binding = level_sequence.add_possessable(actor)
# 刷新以直观地查看添加的新绑定
unreal.LevelSequenceEditorBlueprintLibrary.refresh_current_level_sequence()
# 使用绑定将轨迹添加到Sequencer(由轨迹类型指定)
transform_track = actor_binding.add_track(unreal.MovieScene3DTransformTrack)
属性/状态
#transform
# 将分段添加到轨迹以便能够设置范围、参数或属性
transform_section = transform_track.add_section()
#位移:
获取位置的xyz通道
channel_location_x = transform_section.get_channels()[0]
channel_location_y = transform_section.get_channels()[1]
channel_location_z = transform_section.get_channels()[2]
#获取旋转yz的关键帧
channel_rotation_x = transform_section.get_channels()[3]
channel_rotation_y = transform_section.get_channels()[4]
channel_rotation_z = transform_section.get_channels()[5]
#添加关键帧
links = json_path["links"]
for index in range(0, len(links)):
new_time0 = unreal.FrameNumber(value=index*int(json_path["fov"]))
#channel_fov.add_key(new_time0, float(json_path["fov"]), 0.0)
channel_location_x.add_key(new_time0, float(links[index]["x"]), 0.0)
channel_location_y.add_key(new_time0, float(links[index]["y"]), 0.0)
channel_location_z.add_key(new_time0, float(links[index]["z"]), 0.0)
channel_rotation_x.add_key(new_time1, float(links[index]["roll"]), 0.0)
channel_rotation_y.add_key(new_time1, float(links[index]["pitch"]), 0.0)
channel_rotation_z.add_key(new_time1, float(links[index]["yaw"]), 0.0)
#设置显示隐藏:
#为actor添加可视性(隐藏)关键帧
channel_visibility_bool = visibility_section.get_channels()[0]
#添加关键帧
channel_visibility_bool.add_key(new_time,False)
获取蓝图自定义的变量(感谢DeepSeeK)
import unreal
# 方法1:获取当前关卡中所有蓝图实例
def get_blueprint_variable(actor_class_name, variable_name):
# 获取当前关卡所有Actor
actors = unreal.EditorLevelLibrary.get_all_level_actors()
# 遍历查找目标蓝图类实例
for actor in actors:
if actor.get_class().get_name() == actor_class_name:
# 检查变量是否存在
if actor.property_exists(variable_name):
value = actor.get_editor_property(variable_name)
print(f"Found variable '{variable_name}': {value}")
return value
else:
print(f"Variable '{variable_name}' not found in actor.")
return None
print(f"Actor of class '{actor_class_name}' not found.")
return None
# 使用示例:获取类名为"MyBlueprintClass"的Actor的"MyVariable"变量
get_blueprint_variable("MyBlueprintClass", "MyVariable")
# 方法2:通过选中Actor获取(需提前在编辑器中选中)
selected_actors = unreal.EditorLevelLibrary.get_selected_level_actors()
if selected_actors:
actor = selected_actors[0]
value = actor.get_editor_property("MyVariable")
print(f"Selected actor's variable value: {value}")
#我自己是用的这个写法(上面都是DeepSeek发的)
# 获取Actor子系统以抓取选定的Actor
actor_system = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
# 获取选定的Actor
actor = actor_system.get_selected_level_actors()[0]
print(actor)
value = actor.get_editor_property("TestInt")
Sequence添加Int/float轨道
# 创建整型轨道(int)
int_track = actor_binding.add_track(unreal.MovieSceneIntegerTrack)
property_name_int = "VAR_Index"
int_track.set_property_name_and_path(property_name_int, property_name_int)
#将分段添加到轨迹以便能够设置范围、参数或属性
int_section = int_track.add_section()
#设置开始和结束帧数
int_section.set_start_frame_seconds(0)
int_section.set_end_frame_seconds(600)
channel_int = int_section.get_channels()[0] # 假设第一个通道是整型通道
# 创建浮点轨道(假设变量类型为float)
float_track = actor_binding.add_track(unreal.MovieSceneFloatTrack)
property_name = "Alpha"
float_track.set_property_name_and_path(property_name, property_name)
#将分段添加到轨迹以便能够设置范围、参数或属性
float_section = float_track.add_section()
#设置开始和结束帧数
float_section.set_start_frame_seconds(0)
float_section.set_end_frame_seconds(600)
channel_float = float_section.get_channels()[0] # 假设第一个通道是float通道
links = json_path["links"]
for index in range(0, len(links)):
new_time0 = unreal.FrameNumber(value=index*int(json_path["fov"]))
#channel_fov.add_key(new_time0, float(json_path["fov"]), 0.0)
channel_int.add_key(new_time0, float(links[index]["va"]), 0.0)
#print("index",float(links[index]["va"]))
#float_track.add_key(new_time0, float(links[index]["al"]), 0.0)
channel_float.add_key(new_time0, float(links[index]["al"]), 0.0)
尝试
Json
{
"starttimestamp": 0,
"endtimestamp": 600,
"frametime": 60,
"seqname": "VideoPlayerSeqSpline",
"fov": 60,
"links": [
{
"x": 0,
"y": 0,
"z": 0
},
{
"x": 1088.2844551244866,
"y": -6.1749946553391055e-05,
"z": 9.0949470177292824e-13
},
{
"x": 962.03462911456836,
"y": 1326.0205919409059,
"z": -2.1247876702545909e-07
},
{
"x": 1655.6119959682651,
"y": 1939.9672775097956,
"z": 6.2318827929175313e-06
},
{
"x": 2921.7209372361831,
"y": 1163.8111134544288,
"z": -1.546140993013978e-11
},
{
"x": 3168.7212710348158,
"y": -502.86935341987612,
"z": 36.471531137039221
},
{
"x": 3168.7212776581878,
"y": -1900.5658369533642,
"z": 36.471531137031945
},
{
"x": 3168.7212858682856,
"y": -2762.9053314381854,
"z": 15.992892525690252
},
{
"x": 1705.8193762352209,
"y": -2821.7894823782708,
"z": 15.992892525679338
},
{
"x": 1705.8193759169985,
"y": -1617.7851900597982,
"z": 15.992892525679792
},
{
"x": 273.03898678036694,
"y": -1617.7851516590028,
"z": 15.992892525679792
}
]
}
Python
#连接虚幻API库
import unreal,json,os
def JsonGetData(filename):
# 读取/项目目录/JsonFile中的JSON文件数据存入json_data
root_path = unreal.SystemLibrary.get_project_directory() + 'Content/Json/'
final_path = root_path + filename + '.json'
fp = open(final_path, 'r', encoding='utf-8')
json_str = fp.read()
json_data = json.loads(json_str)
unreal.log("=== INFO: Json Get OK ===")
return json_data
def Seqcreate():
json_path = JsonGetData("test")
# 获取资产工具
asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
# 在根内容文件夹中创建一个名为LevelSequenceName的关卡序列
level_sequence = unreal.AssetTools.create_asset(asset_tools, asset_name=json_path["seqname"],
package_path="/Game/Sequence/",
asset_class=unreal.LevelSequence,
factory=unreal.LevelSequenceFactoryNew())
# 创建一个帧率对象并设置为所需的fps数值
frame_rate = unreal.FrameRate(numerator=json_path["frametime"], denominator=1)
# 设置显示速率
level_sequence.set_display_rate(frame_rate)
# 设置播放范围
level_sequence.set_playback_start(json_path["starttimestamp"])
level_sequence.set_playback_end(json_path["endtimestamp"])
# 获取Actor子系统以抓取选定的Actor
actor_system = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
# 获取选定的Actor
actor = actor_system.get_selected_level_actors()[0]
# 将Actor作为可拥有物添加到关卡中
actor_binding = level_sequence.add_possessable(actor)
# 刷新以直观地查看添加的新绑定
unreal.LevelSequenceEditorBlueprintLibrary.refresh_current_level_sequence()
# 使用绑定将轨迹添加到Sequencer(由轨迹类型指定)
transform_track = actor_binding.add_track(unreal.MovieScene3DTransformTrack)
# 将分段添加到轨迹以便能够设置范围、参数或属性
transform_section = transform_track.add_section()
transform_section.set_start_frame_seconds(json_path["starttimestamp"])
transform_section.set_end_frame_seconds(json_path["endtimestamp"])
channel_location_x = transform_section.get_channels()[0]
channel_location_y = transform_section.get_channels()[1]
channel_location_z = transform_section.get_channels()[2]
links = json_path["links"]
for index in range(0, len(links)):
new_time0 = unreal.FrameNumber(value=index*int(json_path["fov"]))
#channel_fov.add_key(new_time0, float(json_path["fov"]), 0.0)
channel_location_x.add_key(new_time0, float(links[index]["x"]), 0.0)
channel_location_y.add_key(new_time0, float(links[index]["y"]), 0.0)
channel_location_z.add_key(new_time0, float(links[index]["z"]), 0.0)
unreal.EditorAssetLibrary.save_loaded_asset(level_sequence, False)
# 刷新以直观地查看新增的轨迹和分段
unreal.LevelSequenceEditorBlueprintLibrary.refresh_current_level_sequence()
unreal.log("=== INFO: Seq Create Completed Please check the file===")
if __name__ == '__main__':
Seqcreate()