2024-4-9-SendToUE水石国际中国特色连排别墅

原版sketchup这个材质太诡异了,另外目前遇到个问题是sketchup的素材只有正面,背面自己创作暂时还没发借助人工智能实现,参考的pinterest案例。

建模重构用了一天不到,这个案例不涉及楼层叠加问题,或者说我暂时没法想象它如何改造叠加楼层,因此建模前我也没做切分。

昨天被卡住的问题是大量部件需要等建模完成后用bakemaster烘焙,理想中的状况是全选所有物体包含instance关系的则只选其中一个,blender内置没有这个功能,我找了下插件也没办法,后来通过先归类collection再选collection中第一个物体实现了,详情见2024-4-10-大量部件烘焙批量选中问题用python代码解决

烘焙完成后我开始给第二套uv做分割,大概用了1个小时多。然后是对窗户join内景伪装的面片,join前确认uv展开朝向。

导入ue后我遇到了一个问题,对于要批量生成材质的mesh如何批量快速选取呢?情景是对于大量static mesh选取含有某种特定材质的那些,我在网上找方法、插件未果,问chatgpt无果,让它编写python脚本不成功。后来发现直接用select菜单下select all with same material,然后browse to asset即可实现上述需求。之后我发现MaterialConvertInstance.py这个脚本无法对中文路径操作,必须用英文和数字、下划线才行。

随后我发现了两个问题:

1.存在3类mesh,一种只有a材质,一种只有b材质,一种既有a又有b材质,MaterialConvertInstance.py一次只能根据material slot index批量生成一种材质,假设所有既有a又有b材质的mesh按照1a2b排列material slot,那么对material slot index 0执行MaterialConvertInstance.py后,a消失被xx替代,此时再用MaterialConvertInstance.py去对b做生成会出问题因为二者的material slot index不同。为解决这个问题,我优化了代码,不过这次chatgpt能帮的忙有限,这个api可能太小众了,参考了Unreal Automatically Assigning Material by Material Slot Name with Python Unreal Automatically Assigning Material by Material Slot Name with Python 对最后赋予材质这段做了循环判断,深入解读了get_material_index(slot_name)和get_material_slot_names(StaticMeshComponent)。成功实现了对位material slot name来赋予材质。

sm_component = unreal.StaticMeshComponent()
sm_component.set_static_mesh(sm_asset)
material_slot_names = unreal.StaticMeshComponent.get_material_slot_names(sm_component)
print(“material_slot_names:”,material_slot_names)
for slot in material_slot_names:
if slot == “bb”: # Replace “YourTargetMaterialSlotName” with your target material slot name
sm_asset.set_material(sm_component.get_material_index(slot), mi_asset)
print(“sm_component.get_material_index(slot)”,sm_component.get_material_index(slot))
break

成功自动生成材质实例并赋予到相同名称的两个不同slot index

2.在blender创建部件以及烘培纹理,理想状态是所有部件和纹理的名称是对应的。实际发现data name都跟随了最大尾数物体的名称,解决办法很容易,只要选中最小尾数的物体data name from object即可。这样就不会使static mesh名称和烘焙名称不符了。

打包packed blueprint level actor时经常会在框选时加入一些意想不到的其他actor比如skydome什么的,用Actor Lock插件alt+”,” 冻结选中的actor, alt+”.”解冻选中的actor。

ctrl+F全选与当前选中actor具有相同材质的actor,ctrl+b把这些选中的actor对应的static mesh在content browser中高亮选中,借助b站【UE5开发】快速调试python脚本_哔哩哔哩_bilibili 这个启动脚本,在菜单栏上增加一栏,点开run script即运行MaterialConvertInstance.py.

没有多选skydome的情况下,packed blueprint level actor打包的房子pivot居中正常,调出时位于z轴0点。

完成packed level actor blueprint后我发现ctrl+d复制出来的blueprint actor内景是一样的(下图1),其中的instancing random seed每个复制品都一样。网上找不到关于这个参数的编程控制方式,没办法问题又回到了Num Custom Data Floats,最早接触matrix项目时就发现只要改动这个数值就能更改内景,具体原理就不深究了,然而网上找了很久只有关于Custom Data Value设置的,Num Custom Data Floats则需要手动设置,那么多的部件都要这么搞那得累死了,之前查到一条说ue5.3对这个参数做了expose,由于当时对blueprint完全不懂所以也就没深究,这次有了前几天完成deco per socket blueprint复刻的底气后,我打算试试看ue5.3能否实现这东西。

测试成功!可以观察到图2、3中custom data 的值不同(也就是custom data value)。那么问题就变成整个平台从5.2到5.3的迁移了,整个拷贝一份原来的工程我觉得没必要,那个工程文件有60多个GB里面包含了大量我自己都忘记的unused asset,而用清理工具去搞是有风险的,因此不如下定决心整个重排架构。目前看下来不再需要PBG和PRG了,也可以再做两个项目来验证,我不知道之前的插件对ue5.3有没有兼容问题,也是时候随着项目整理来确定其他插件的使用问题了。

重构了室内伪装的master material把perintancerandom替换成perinstanceCustomData,脑筋一时间没转过来,这个值太大了怎么在材质函数里获取0-1范围,后来想到这个值是在construction script的blueprint里面控制的,直接限定那边的值0-1即可,random float in range.

最后贴一下完整的MaterialConvertInstance.py代码

按照材质slot名称创建带packedA texture的材质实例并赋予选中的StaticMeshAsset
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
  

import unreal

def set_mi_texture(mi_asset, param_name, tex_path):
if not unreal.EditorAssetLibrary.does_asset_exist(tex_path):
unreal.log_warning("Can't find texture: " + tex_path)
return False
tex_asset = unreal.EditorAssetLibrary.find_asset_data(tex_path).get_asset()
return unreal.MaterialEditingLibrary.set_material_instance_texture_parameter_value(mi_asset, param_name, tex_asset)

unreal.log("---------------------------------------------------")
AssetTools = unreal.AssetToolsHelpers.get_asset_tools()
MaterialEditingLibrary = unreal.MaterialEditingLibrary
EditorAssetLibrary = unreal.EditorAssetLibrary
mtl_parentname = "MI_Bldg_PaintedStone_Black"
base_mtl = unreal.EditorAssetLibrary.find_asset_data("/Game/RealEstate_Building/villa1/Materials/" + mtl_parentname)

# Iterate over selected meshes
sel_assets = unreal.EditorUtilityLibrary.get_selected_assets()
for sm_asset in sel_assets:
if sm_asset.get_class().get_name() != "StaticMesh":
continue # Skip non-static-meshes

asset_name = sm_asset.get_name()
if asset_name.startswith("S_"):
asset_name = asset_name[2:] # Store mesh name without prefix
asset_folder = unreal.Paths.get_path(sm_asset.get_path_name())
base_folder = asset_folder[:-7] # Get base folder (subtract "Meshes" from base path)
mtl_folder = base_folder + "/Materials/"
tex_folder = base_folder + "/Textures/"

# Create folder for materials if not exist
if not unreal.EditorAssetLibrary.does_directory_exist(mtl_folder):
unreal.EditorAssetLibrary.make_directory(mtl_folder)

# Name of material instance for this mesh
mi_name = mtl_parentname + "_" + asset_name
mi_full_path = mtl_folder + mi_name

# Check if material instance already exists
if EditorAssetLibrary.does_asset_exist(mi_full_path):
mi_asset = EditorAssetLibrary.find_asset_data(mi_full_path).get_asset()
unreal.log("Asset already exists")
else:
mi_asset = AssetTools.create_asset(mi_name, mtl_folder, unreal.MaterialInstanceConstant, unreal.MaterialInstanceConstantFactoryNew())

# Set material instance parameters
MaterialEditingLibrary.set_material_instance_parent(mi_asset, base_mtl.get_asset()) # Set parent material

# Find textures for this mesh
set_mi_texture(mi_asset, "PackedA Tex", tex_folder + asset_name)

# Set new material instance on static mesh based on material slot name
sm_component = unreal.StaticMeshComponent()
sm_component.set_static_mesh(sm_asset)
material_slot_names = unreal.StaticMeshComponent.get_material_slot_names(sm_component)
print("material_slot_names:",material_slot_names)
for slot in material_slot_names:
if slot == "黑色涂料": # Replace "YourTargetMaterialSlotName" with your target material slot name
sm_asset.set_material(sm_component.get_material_index(slot), mi_asset)
print("sm_component.get_material_index(slot)",sm_component.get_material_index(slot))
break
2024-4-15-SendToUE世界地形道路人行道的构建流程 2024-4-9-第二套UV的必要性

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×