UE开发的一点心得经验(二)
UE开发的一点心得经验(二)
lingyun前言
上期讲了怎么用Python去导入fbx或abc,怎么去找到并修改一个对象的属性等等。
这期是一些关于Sequencer的操作技巧。
大致内容有:
- 如何创建 level sequencer
- 如何在 level sequencer 中导入摄像机fbx
- 如何在 level sequencer 添加绑定actor
- 如何为其绑定actor添加动画asset
这个系列的主旨不是直接贴代码告诉结果,而是想更多分享过程上的东西。
有了chatGPT后,我们可能不再需要靠猜测推断来得知实现目标方法的代码(也许?)。文章写于chatGPT前,所以是在一个没有chatGPT的角度下去处理和分析问题。
创建Sequencer
通过上一篇可以知道,sequencer是asset的一种,
所以搜索一下有没有create_asset
相关的方法。
果然是有的,然后根据文档试一下。
首先看下create_asset
的四个必要参数。
- asset_name
- package_path
- asset_class
- factory
前面三个根据参数名和文档释义很容易看出来,依次是:asset名称,路径和asset类对象。
名称和路径都是字符串。
要得知asset_class要传什么对象进去,可以先手动创建一个LevelSequencer,调用__class__
方法。
这里比较有疑问的是最后一个factory(工厂),不知道该传入什么参数。
先点进去看看它是个什么对象。
那直接把Factory代入进去试试(其实文档描述可以看出来,它应该是一个factory类型的基类)
1 | asset_tools.create_asset('test_seq', |
果然执行报错了:Error: Exception: Factory: Class 'Factory' is abstract
既然它是一个抽象类(factory的基类),那么看看有没有LevelSequencer的Factory,搜索一下:
带入进去再试试:
1 | unreal.AssetTools.create_asset('test_seq', |
还是报错了:TypeError: descriptor 'create_asset' requires a 'AssetTools' object but received a 'str'
不过这次没有说factory的参数问题,字面意思是’create_asset’需要一个’AssetTools’对象。
那试试先实例化呢asset_tools = unreal.AssetTools()
,得到反馈说它也是个抽象类。
那直接在帮助文档搜索AssetTools
看看,搜索结果中看到有个AssetToolsHelpers
,看名称是个有关Asset_tools辅助类。
它可以返回AssetTools
对象。
用它试试,果然就可以进行sequencer的创建了。
1 | asset_tools = unreal.AssetToolsHelpers.get_asset_tools() |
其实对于这样的基础操作,更快捷的方式是在google上直接进行搜索“unreal how to create sequence with python”
我这里搜出来的第二个结果就可以看到:
这里是想分享一个”处理”问题的过程。
导入相机fbx到sequencer
需要执行这样一个操作,选择camera的fbx导入到sequencer中
用代码实现的话,首先想到的是从sequencer这个对象里找方法。
查看文档,没有能导入fbx的函数。于是又找到它的父级unreal.MovieSceneSequence
,依旧是没有相关方法。
那就需要换个思路,在文档连续搜索了几个关键词:
- import camera sequence
- add camera sequence
- import fbx sequence
在最后的关键词找到了一个SequencerTools.import_level_sequence_fbx
,这个跟AssetToolsHelpers
有点像。
有五个必要参数需要传入:
- world:Game世界
- sequence:
LevelSequence
对象 - bindings:
SequencerBindingProxy
数组 - import_fbx_settings:导入的fbx设置
- import_filename:文件路径
world 在上一篇获取所有Actor的例子中知道使用unreal.EditorLevelLibrary.get_editor_world()
来获取,代表的是当前Game世界。
sequence 是LevelSequence
类对象,获取当前选择的asset对象就行。
bindings 不知道是个什么,好像是数组,这里暂时给个空列表试试。
import_fbx_settings 是导入的设置选项,这个在上一节也讲过类似的。
直接实例化MovieSceneUserImportFBXSettings
,然后传参就行了。
import_filename 是路径字符串。
带入到代码中试试。
1 | # 导入的摄像机fbx路径 |
成功了,相机被导入到了Sequencer中。
不过到这里还是没有明白bindings参数会对导入产生什么影响,去文档里探索一下。
使用搜索大法:
这里看到一个眼熟的对象,也就是方才提到的LevelSequence
的父级unreal.MovieSceneSequence
,且有一个get_binding
的方法。
打印一下看它是个什么:
1 | sequence = unreal.EditorUtilityLibrary.get_selected_assets()[0] |
返回的是SequencerBindingProxy
对象组成的数组。
再试试创建一个新的Sequencer,查看这个属性呢。
结果返回的是一个空列表[]
。所以当Sequencer里面没有东西的时候,传入一个空列表是允许的。
如果要添加新的对象进去,可能就需要将binding先获取再传参给unreal.SequencerTools.import_fbx
。
到现在也没有弄清楚这个参数是什么意思,感兴趣的朋友可以研究研究,也欢迎大佬告知一下。
复制文本大法
前面都是讲的如何通过搜索和联想来找到所需要的方法和参数。
这里讲一个复制文本的技巧(脑洞来自于Nuke的编程思路)。
我当时遇到一个问题,如何在levelSequencer中添加actor,并为其添加动画。
在软件中,是这样操作:
得到这样的结果:
但作为TD得需要知道,如何用脚本去实现它。
第一步是找到如何添加actor到levelSequencer中,首先想到的是在unreal.LevelSequence
文档中找方法。
一眼望去没有相似的方法可以用,那么去它的父级看看
根据经验来说,添加一个什么东西,函数一般以add
开头。
这个对象下大概有7个函数方法是以add
开头的,看看每个函数的传参可以过滤出来,
下面两个比较像是能够传入一个actor对象。
那么从第一个add_possessable
方法开始尝试一下
1 |
|
添加成功了!
不过感觉少了点什么。
和手动添加的对比,发现少了Transfrom
和Animation
。
发现man_rig
后有个小+号,点击+号可以添加它们。
并且知道了这个东西叫作Track
。
那怎么用代码去添加这个Track
,找到刚刚的函数,
返回一个叫MovieSceneBindingProxy
的对象
发现这个对象有个add_track
的方法,参数是track_type
类型
找到了函数方法,那么要传什么参数类型进去,这个类型当时困扰了一会。
后来脑洞大开,想到unreal会不会可以像nuke一样,复制这个”节点“,然后粘贴到文本编辑器,能看到这个”节点“的参数细节。
于是我先手动创建了一个 Transfrom Track
,并选中它,按下 Ctrl + C
,
打开文本编辑器,Ctrl + V
。
于是在第二行找到了这个对象,去文档搜索发现是有的:
修改代码:
1 | rig_actor = unreal.EditorLevelLibrary.get_selected_level_actors()[0] |
执行后发现,虽然有 Transfrom Track
了,但依旧比手动添加时,少一些元素,需要再点击Section
按钮添加。
这个问题也好解决,根据之前的经验找对应的文档方法就行了。
添加完Section,发现时间范围没有被设置,从文档中找到set_range
方法。
完整的代码如下
1 | # 获取 asset和actor对象 |
最后是添加 Animation Track
,通过复制文本得知track对象名称
那么代码应该就是这样的
1 | ani_track = possessable.add_track(track_type=unreal.MovieSceneSkeletalAnimationTrack) |
那如何把动画资产给添加进去
一开始是在unreal.MovieSceneSkeletalAnimationTrack
和unreal.MovieSceneSkeletalAnimationSection
对象中找方法,
但是好像没有一个可以去设置动画asset的函数。
于是乎又开脑洞,手动添加一下动画asset,复制文本。
与之前没有动画asset的文本进行对比看看。
找到了 /Game/test/man_ani.man_ani
这个资产是被放在Params
里的。
这样的话,MovieSceneSkeletalAnimationSection
里就有一个params
的属性。
接下来的事情就轻车熟路了。
找到MovieSceneSkeletalAnimationParams
文档,实例化它,赋予属性。
完整的添加Animated代码如下
1 |
|
以上就是通过复制文本来获取关键信息,从而找到实现功能的函数模块。
总结
之前使用Python对UE开发,因为文档比较难以阅读,网上的资料也很少,大多命令方法都要靠推断和尝试。
如今有了chatGPT以及一段时间的过渡,一些简单功能的实现可以直接从Google和chatGPT获得答案。当然chatGPT的答案准确率依然不高,但它能给予提示和灵感,或是一个寻找答案的方向。
最近的工作暂时告别UE开发了,对于UE更深度的开发使用C++更适合一些(正在学)。
那这个系列基本结束,感谢阅读和支持。