Skip to content

Commit 320ac03

Browse files
Mikalai Lazitskijulien-moreau
authored andcommitted
refactor: enhance Unity converters with utility functions for property access
- Introduced a new utility function `getUnityProp` to streamline access to Unity serialized properties, supporting both standard and prefixed naming conventions. - Updated various converters (e.g., color, shape, particle system) to utilize the new utility function, improving code clarity and reducing redundancy. - Refactored error handling in the Unity prefab conversion process to ensure consistent return of empty data structures on failure. - Enhanced the handling of GameObject and component references to ensure proper type conversion and error resilience.
1 parent f54a4e7 commit 320ac03

7 files changed

Lines changed: 310 additions & 193 deletions

File tree

editor/src/editor/windows/effect-editor/converters/unity/colorConverter.ts

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Color4 } from "@babylonjs/core/Maths/math.color";
22
import type { IConstantColor, IGradientColor, IRandomColor, IRandomColorBetweenGradient } from "babylonjs-editor-tools/src/effect/types";
3+
import { getUnityProp } from "./utils";
34

45
/**
56
* Convert Unity Color to our Color4
@@ -9,29 +10,36 @@ export function convertColor(unityColor: { r: string; g: string; b: string; a: s
910
}
1011

1112
/**
12-
* Convert Unity Gradient to our Color
13+
* Convert Unity Gradient to our Color (supports m_NumColorKeys / numColorKeys etc.)
1314
*/
1415
export function convertGradient(gradient: any): IConstantColor | IGradientColor {
16+
const numColorKeys = getUnityProp(gradient, "numColorKeys") ?? gradient.m_NumColorKeys ?? 0;
17+
const numAlphaKeys = getUnityProp(gradient, "numAlphaKeys") ?? gradient.m_NumAlphaKeys ?? 0;
1518
const colorKeys: Array<{ time: number; value: [number, number, number, number] }> = [];
1619

17-
// Parse color keys
18-
for (let i = 0; i < gradient.m_NumColorKeys; i++) {
19-
const key = gradient[`key${i}`];
20-
const time = parseFloat(gradient[`ctime${i}`]) / 65535; // Unity stores time as 0-65535
20+
for (let i = 0; i < numColorKeys; i++) {
21+
const key = gradient[`key${i}`] ?? gradient[`m_ColorKeys`]?.[i];
22+
const timeRaw = gradient[`ctime${i}`] ?? gradient[`m_CTime${i}`] ?? 0;
23+
const time = typeof timeRaw === "number" ? timeRaw : parseFloat(timeRaw) / 65535;
24+
if (!key) continue;
25+
const r = key.r ?? key.m_R;
26+
const g = key.g ?? key.m_G;
27+
const b = key.b ?? key.m_B;
2128
colorKeys.push({
2229
time,
23-
value: [parseFloat(key.r), parseFloat(key.g), parseFloat(key.b), 1],
30+
value: [parseFloat(r ?? "1"), parseFloat(g ?? "1"), parseFloat(b ?? "1"), 1],
2431
});
2532
}
2633

27-
// Parse alpha keys
2834
const alphaKeys: Array<{ time: number; value: number }> = [];
29-
for (let i = 0; i < gradient.m_NumAlphaKeys; i++) {
30-
const key = gradient[`key${i}`];
31-
const time = parseFloat(gradient[`atime${i}`]) / 65535;
35+
for (let i = 0; i < numAlphaKeys; i++) {
36+
const key = gradient[`key${i}`] ?? gradient[`m_AlphaKeys`]?.[i];
37+
const timeRaw = gradient[`atime${i}`] ?? gradient[`m_ATime${i}`] ?? 0;
38+
const time = typeof timeRaw === "number" ? timeRaw : parseFloat(timeRaw) / 65535;
39+
if (!key) continue;
3240
alphaKeys.push({
3341
time,
34-
value: parseFloat(key.a),
42+
value: parseFloat(key.a ?? key.m_A ?? "1"),
3543
});
3644
}
3745

@@ -52,43 +60,36 @@ export function convertGradient(gradient: any): IConstantColor | IGradientColor
5260
}
5361

5462
/**
55-
* Convert Unity MinMaxGradient to our Color
63+
* Convert Unity MinMaxGradient to our Color (supports m_MinMaxState, m_MaxColor, etc.)
5664
*/
5765
export function convertMinMaxGradient(minMaxGradient: any): IConstantColor | IGradientColor | IRandomColor | IRandomColorBetweenGradient {
58-
const minMaxState = minMaxGradient.minMaxState;
66+
const minMaxState = String(getUnityProp(minMaxGradient, "minMaxState") ?? minMaxGradient.minMaxState ?? "0");
67+
const maxColor = getUnityProp(minMaxGradient, "maxColor") ?? minMaxGradient.maxColor ?? {};
68+
const minColor = getUnityProp(minMaxGradient, "minColor") ?? minMaxGradient.minColor ?? {};
69+
const maxGradient = getUnityProp(minMaxGradient, "maxGradient") ?? minMaxGradient.maxGradient;
70+
const minGradient = getUnityProp(minMaxGradient, "minGradient") ?? minMaxGradient.minGradient;
71+
72+
const toRgba = (c: any): [number, number, number, number] => [
73+
parseFloat(c?.r ?? c?.m_R ?? "1"),
74+
parseFloat(c?.g ?? c?.m_G ?? "1"),
75+
parseFloat(c?.b ?? c?.m_B ?? "1"),
76+
parseFloat(c?.a ?? c?.m_A ?? "1"),
77+
];
5978

6079
switch (minMaxState) {
61-
case "0": // Constant color
62-
return {
63-
type: "ConstantColor",
64-
value: [
65-
parseFloat(minMaxGradient.maxColor.r),
66-
parseFloat(minMaxGradient.maxColor.g),
67-
parseFloat(minMaxGradient.maxColor.b),
68-
parseFloat(minMaxGradient.maxColor.a),
69-
] as [number, number, number, number],
70-
};
71-
case "1": // Gradient
72-
return convertGradient(minMaxGradient.maxGradient);
73-
case "2": // Random between two colors
80+
case "0":
81+
return { type: "ConstantColor", value: toRgba(maxColor) };
82+
case "1":
83+
return convertGradient(maxGradient ?? {});
84+
case "2":
7485
return {
7586
type: "RandomColor",
76-
colorA: [
77-
parseFloat(minMaxGradient.minColor.r),
78-
parseFloat(minMaxGradient.minColor.g),
79-
parseFloat(minMaxGradient.minColor.b),
80-
parseFloat(minMaxGradient.minColor.a),
81-
] as [number, number, number, number],
82-
colorB: [
83-
parseFloat(minMaxGradient.maxColor.r),
84-
parseFloat(minMaxGradient.maxColor.g),
85-
parseFloat(minMaxGradient.maxColor.b),
86-
parseFloat(minMaxGradient.maxColor.a),
87-
] as [number, number, number, number],
87+
colorA: toRgba(minColor),
88+
colorB: toRgba(maxColor),
8889
};
89-
case "3": // Random between two gradients
90-
const grad1 = convertGradient(minMaxGradient.minGradient);
91-
const grad2 = convertGradient(minMaxGradient.maxGradient);
90+
case "3": {
91+
const grad1 = convertGradient(minGradient ?? {});
92+
const grad2 = convertGradient(maxGradient ?? {});
9293
if (grad1.type === "Gradient" && grad2.type === "Gradient") {
9394
return {
9495
type: "RandomColorBetweenGradient",
@@ -102,8 +103,8 @@ export function convertMinMaxGradient(minMaxGradient: any): IConstantColor | IGr
102103
},
103104
};
104105
}
105-
// Fallback to constant color if conversion failed
106106
return { type: "ConstantColor", value: [1, 1, 1, 1] };
107+
}
107108
default:
108109
return { type: "ConstantColor", value: [1, 1, 1, 1] };
109110
}

editor/src/editor/windows/effect-editor/converters/unity/gameObjectConverter.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,15 @@ export function convertGameObject(gameObject: any, components: Map<string, any>)
9999
children: [],
100100
};
101101

102-
// Recursively convert children
102+
// Recursively convert children (components Map uses string keys)
103103
if (transform && transform.m_Children) {
104104
for (const childRef of transform.m_Children) {
105-
const childTransform = components.get(childRef.fileID);
105+
const childId = childRef?.fileID ?? childRef;
106+
const childTransform = components.get(childId != null ? String(childId) : childId);
106107
if (childTransform && childTransform.Transform) {
107108
const childGORef = childTransform.Transform.m_GameObject;
108-
const childGOId = childGORef?.fileID || childGORef;
109-
const childGO = components.get(childGOId);
109+
const childGOId = childGORef?.fileID ?? childGORef;
110+
const childGO = components.get(childGOId != null ? String(childGOId) : childGOId);
110111

111112
if (childGO && childGO.GameObject) {
112113
if (!group.children) {

0 commit comments

Comments
 (0)