Skip to content

Commit a403b13

Browse files
authored
Fix extraction of 3D custom objects and prevent extracting 2D+3D custom objects (#7040)
1 parent 83dba6c commit a403b13

File tree

3 files changed

+71
-6
lines changed

3 files changed

+71
-6
lines changed

newIDE/app/src/SceneEditor/CustomObjectExtractor/CustomObjectExtractor.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export const extractAsCustomObject = ({
7474

7575
let zOrder = 0;
7676
let layer = '';
77+
let isRenderedIn3D = null;
7778
for (const serializedInstance of serializedSelection) {
7879
const instance = new gd.InitialInstance();
7980
unserializeFromJSObject(instance, serializedInstance);
@@ -89,6 +90,13 @@ export const extractAsCustomObject = ({
8990
if (!childObjects.hasObjectNamed(objectName)) {
9091
const object = getObjectByName(globalObjects, sceneObjects, objectName);
9192
if (object) {
93+
if (isRenderedIn3D === null) {
94+
const objectMetadata = gd.MetadataProvider.getObjectMetadata(
95+
project.getCurrentPlatform(),
96+
object.getType()
97+
);
98+
isRenderedIn3D = objectMetadata.isRenderedIn3D();
99+
}
92100
const serializedObject = serializeToJSObject(object);
93101
const childObject = childObjects.insertNewObject(
94102
project,
@@ -104,6 +112,7 @@ export const extractAsCustomObject = ({
104112
);
105113
}
106114
}
115+
newEventsBasedObject.markAsRenderedIn3D(!!isRenderedIn3D);
107116

108117
newEventsBasedObject
109118
.getInitialInstances()

newIDE/app/src/SceneEditor/CustomObjectExtractor/ExtractAsCustomObjectDialog.js

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@ import HelpButton from '../../UI/HelpButton';
1313
import SelectField from '../../UI/SelectField';
1414
import SelectOption from '../../UI/SelectOption';
1515
import { enumerateEventsFunctionsExtensions } from '../../ProjectManager/EnumerateProjectItems';
16+
import getObjectByName from '../../Utils/GetObjectByName';
17+
import AlertMessage from '../../UI/AlertMessage';
18+
19+
const gd: libGDevelop = global.gd;
1620

1721
type Props = {|
1822
project: gdProject,
23+
globalObjectsContainer: gdObjectsContainer | null,
24+
objectsContainer: gdObjectsContainer,
1925
initialInstances: gdInitialInstancesContainer,
2026
selectedInstances: Array<gdInitialInstance>,
2127
onApply: (
@@ -31,6 +37,8 @@ const CREATE_NEW_EXTENSION_PLACEHOLDER = '<create a new extension>';
3137

3238
export default function ExtractAsCustomObjectDialog({
3339
project,
40+
globalObjectsContainer,
41+
objectsContainer,
3442
initialInstances,
3543
selectedInstances,
3644
onApply,
@@ -80,16 +88,50 @@ export default function ExtractAsCustomObjectDialog({
8088
[initialInstances, selectedInstances]
8189
);
8290

91+
const has2DAnd3D = React.useMemo(
92+
() => {
93+
let has2D = false;
94+
let has3D = false;
95+
for (const selectedInstance of selectedInstances) {
96+
const objectName = selectedInstance.getObjectName();
97+
const object = getObjectByName(
98+
globalObjectsContainer,
99+
objectsContainer,
100+
objectName
101+
);
102+
if (object) {
103+
const objectMetadata = gd.MetadataProvider.getObjectMetadata(
104+
project.getCurrentPlatform(),
105+
object.getType()
106+
);
107+
has2D = has2D || !objectMetadata.isRenderedIn3D();
108+
has3D = has3D || objectMetadata.isRenderedIn3D();
109+
if (has2D && has3D) {
110+
return true;
111+
}
112+
}
113+
}
114+
return false;
115+
},
116+
[globalObjectsContainer, objectsContainer, project, selectedInstances]
117+
);
118+
83119
const apply = React.useCallback(
84120
(i18n: I18nType) => {
85-
onApply(
86-
extensionName || i18n._(t`UntitledExtension`),
87-
isNewExtension,
88-
eventsBasedObjectName || i18n._(t`MyObject`),
89-
canRemoveSceneObjects && shouldRemoveSceneObjectsWhenNoMoreInstance
90-
);
121+
if (has2DAnd3D) {
122+
onCancel();
123+
} else {
124+
onApply(
125+
extensionName || i18n._(t`UntitledExtension`),
126+
isNewExtension,
127+
eventsBasedObjectName || i18n._(t`MyObject`),
128+
canRemoveSceneObjects && shouldRemoveSceneObjectsWhenNoMoreInstance
129+
);
130+
}
91131
},
92132
[
133+
has2DAnd3D,
134+
onCancel,
93135
onApply,
94136
extensionName,
95137
isNewExtension,
@@ -116,6 +158,7 @@ export default function ExtractAsCustomObjectDialog({
116158
label={<Trans>Move instances</Trans>}
117159
primary={true}
118160
onClick={() => apply(i18n)}
161+
disabled={has2DAnd3D}
119162
/>,
120163
]}
121164
secondaryActions={[
@@ -135,6 +178,15 @@ export default function ExtractAsCustomObjectDialog({
135178
Selected instances will be moved to a new custom object.
136179
</Trans>
137180
</Text>
181+
{has2DAnd3D ? (
182+
<AlertMessage kind="error">
183+
<Trans>
184+
Custom objects can't contain both 2D or 3D.
185+
<br />
186+
Please select either 2D instances or 3D instances.
187+
</Trans>
188+
</AlertMessage>
189+
) : null}
138190
<ResponsiveLineStackLayout noMargin expand>
139191
<SelectField
140192
floatingLabelText={

newIDE/app/src/SceneEditor/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,6 +2294,10 @@ export default class SceneEditor extends React.Component<Props, State> {
22942294
{this.state.extractAsCustomObjectDialogOpen && (
22952295
<ExtractAsCustomObjectDialog
22962296
project={project}
2297+
globalObjectsContainer={
2298+
this.props.globalObjectsContainer
2299+
}
2300+
objectsContainer={this.props.objectsContainer}
22972301
initialInstances={this.props.initialInstances}
22982302
selectedInstances={this.instancesSelection.getSelectedInstances()}
22992303
onCancel={() =>

0 commit comments

Comments
 (0)