Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
add modal and fix update duplicated prefab
Browse files Browse the repository at this point in the history
  • Loading branch information
JT00y committed Aug 14, 2024
1 parent 815bda7 commit 051eae1
Showing 1 changed file with 151 additions and 108 deletions.
259 changes: 151 additions & 108 deletions packages/editor/src/components/dialogs/CreatePrefabPanelDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
removeEntity,
setComponent
} from '@etherealengine/ecs'
import { updateModelResource } from '@etherealengine/engine/src/assets/functions/resourceLoaderFunctions'
import { GLTFDocumentState } from '@etherealengine/engine/src/gltf/GLTFDocumentState'
import { ModelComponent } from '@etherealengine/engine/src/scene/components/ModelComponent'
import { SourceComponent } from '@etherealengine/engine/src/scene/components/SourceComponent'
Expand All @@ -60,130 +61,172 @@ export default function CreatePrefabPanel({ entity }: { entity: Entity }) {
const prefabName = useHookstate<string>('prefab')
const prefabTag = useHookstate<string[]>([])
const { t } = useTranslation()

const isOverwriteModalVisible = useHookstate(false)
const isOverwriteConfirmed = useHookstate(false)
const onExportPrefab = async () => {
const editorState = getState(EditorState)
const fileName = defaultPrefabFolder.value + '/' + prefabName.value + '.gltf'
const srcProject = editorState.projectName!
const fileURL = pathJoin(config.client.fileServer, 'projects', srcProject, fileName)
try {
const parentEntity = getComponent(entity, EntityTreeComponent).parentEntity
const prefabEntity = createEntity()
const obj = new Scene()
addObjectToGroup(prefabEntity, obj)
proxifyParentChildRelationships(obj)
setComponent(prefabEntity, EntityTreeComponent, { parentEntity })
setComponent(prefabEntity, NameComponent, prefabName.value)
const entityTransform = getComponent(entity, TransformComponent)
const position = entityTransform.position.clone()
const rotation = entityTransform.rotation.clone()
const scale = entityTransform.scale.clone()
setComponent(prefabEntity, TransformComponent, {
position,
rotation,
scale
})
setComponent(entity, TransformComponent, {
position: new Vector3(0, 0, 0),
rotation: new Quaternion().identity(),
scale: new Vector3(1, 1, 1)
})
setComponent(entity, EntityTreeComponent, { parentEntity: prefabEntity })
getMutableState(SelectionState).selectedEntities.set([])
await exportRelativeGLTF(prefabEntity, srcProject, fileName)

const resources = await Engine.instance.api.service(staticResourcePath).find({
const resourcesold = await Engine.instance.api.service(staticResourcePath).find({
query: { key: 'projects/' + srcProject + '/' + fileName }
})
if (resources.data.length === 0) {
throw new Error('User not found')
}
const resource = resources.data[0]
const tags = [...prefabTag.value]
await Engine.instance.api.service(staticResourcePath).patch(resource.id, { tags: tags, project: srcProject })
if (resourcesold.data.length !== 0 && !isOverwriteConfirmed.value) {
//throw new Error('Duplicate file')
console.log('this name already exist, click confirm to overwrite the prefab')
await isOverwriteModalVisible.set(true)
} else {
const prefabEntity = createEntity()
const obj = new Scene()
addObjectToGroup(prefabEntity, obj)
proxifyParentChildRelationships(obj)
setComponent(prefabEntity, EntityTreeComponent, { parentEntity })
setComponent(prefabEntity, NameComponent, prefabName.value)
const entityTransform = getComponent(entity, TransformComponent)
const position = entityTransform.position.clone()
const rotation = entityTransform.rotation.clone()
const scale = entityTransform.scale.clone()
setComponent(prefabEntity, TransformComponent, {
position,
rotation,
scale
})
setComponent(entity, TransformComponent, {
position: new Vector3(0, 0, 0),
rotation: new Quaternion().identity(),
scale: new Vector3(1, 1, 1)
})
setComponent(entity, EntityTreeComponent, { parentEntity: prefabEntity })

removeEntity(prefabEntity)
EditorControlFunctions.removeObject([entity])
const sceneID = getComponent(parentEntity, SourceComponent)
const reactor = startReactor(() => {
const documentState = useHookstate(getMutableState(GLTFDocumentState))
const nodes = documentState[sceneID].nodes
useEffect(() => {
if (!entityExists(entity)) {
const { entityUUID } = EditorControlFunctions.createObjectFromSceneElement(
[
{ name: ModelComponent.jsonID, props: { src: fileURL } },
{ name: TransformComponent.jsonID, props: { position, rotation, scale } }
],
parentEntity
)
getMutableState(SelectionState).selectedEntities.set([entityUUID])
reactor.stop()
} else {
console.log('Entity not removed')
}
}, [nodes])
return null
})
PopoverState.hidePopupover()
defaultPrefabFolder.set('assets/custom-prefabs')
prefabName.set('prefab')
prefabTag.set([])
await exportRelativeGLTF(prefabEntity, srcProject, fileName).then(() => {
updateModelResource(fileURL)
})

const resources = await Engine.instance.api.service(staticResourcePath).find({
query: { key: 'projects/' + srcProject + '/' + fileName }
})
if (resources.data.length === 0) {
throw new Error('User not found')
}
const resource = resources.data[0]
const tags = [...prefabTag.value]
await Engine.instance.api.service(staticResourcePath).patch(resource.id, { tags: tags, project: srcProject })

removeEntity(prefabEntity)
await EditorControlFunctions.removeObject([entity])
//await EditorControlFunctions.removeObject([prefabEntity])
const sceneID = getComponent(parentEntity, SourceComponent)
const reactor = startReactor(() => {
const documentState = useHookstate(getMutableState(GLTFDocumentState))
const nodes = documentState[sceneID].nodes
useEffect(() => {
if (!entityExists(entity)) {
const { entityUUID } = EditorControlFunctions.createObjectFromSceneElement(
[
{ name: ModelComponent.jsonID, props: { src: fileURL } },
{ name: TransformComponent.jsonID, props: { position, rotation, scale } }
],
parentEntity
)

updateModelResource(fileURL)
getMutableState(SelectionState).selectedEntities.set([entityUUID])
reactor.stop()
} else {
console.log('Entity not removed')
}
}, [nodes])

return null
})

PopoverState.hidePopupover()
defaultPrefabFolder.set('assets/custom-prefabs')
prefabName.set('prefab')
prefabTag.set([])
isOverwriteModalVisible.set(false)
isOverwriteConfirmed.set(false)
}
} catch (e) {
console.error(e)
}
}
return (
<Modal
title="Create Prefab"
onSubmit={onExportPrefab}
className="w-[50vw] max-w-2xl"
onClose={PopoverState.hidePopupover}
>
<Input
value={defaultPrefabFolder.value}
onChange={(event) => defaultPrefabFolder.set(event.target.value)}
label="Default Save Folder"
/>
<Input value={prefabName.value} onChange={(event) => prefabName.set(event.target.value)} label="Name" />
<>
{!isOverwriteModalVisible.value && !isOverwriteConfirmed.value && (
<Modal
title="Create Prefab"
onSubmit={onExportPrefab}
className="w-[50vw] max-w-2xl"
onClose={PopoverState.hidePopupover}
>
<Input
value={defaultPrefabFolder.value}
onChange={(event) => defaultPrefabFolder.set(event.target.value)}
label="Default Save Folder"
/>
<Input value={prefabName.value} onChange={(event) => prefabName.set(event.target.value)} label="Name" />

<Button
size="small"
variant="outline"
className="text-left text-xs"
onClick={() => {
prefabTag.set([...(prefabTag.value ?? []), ''])
}}
>
{t('editor:layout.filebrowser.fileProperties.addTag')}
</Button>
<div>
{(prefabTag.value ?? []).map((tag, index) => (
<div style={{ display: 'flex', flexDirection: 'row', margin: '0, 16px 0 0' }}>
<Input
key={index}
label={t('editor:layout.filebrowser.fileProperties.tag')}
onChange={(event) => {
const tags = [...prefabTag.value]
tags[index] = event.target.value
prefabTag.set(tags)
}}
value={prefabTag.value[index]}
/>
<Button
onClick={() => {
prefabTag.set(prefabTag.value.filter((_, i) => i !== index))
}}
size="small"
variant="outline"
className="text-left text-xs"
>
{' '}
x{' '}
</Button>
<Button
size="small"
variant="outline"
className="text-left text-xs"
onClick={() => {
prefabTag.set([...(prefabTag.value ?? []), ''])
}}
>
{t('editor:layout.filebrowser.fileProperties.addTag')}
</Button>
<div>
{(prefabTag.value ?? []).map((tag, index) => (
<div style={{ display: 'flex', flexDirection: 'row', margin: '0, 16px 0 0' }}>
<Input
key={index}
label={t('editor:layout.filebrowser.fileProperties.tag')}
onChange={(event) => {
const tags = [...prefabTag.value]
tags[index] = event.target.value
prefabTag.set(tags)
}}
value={prefabTag.value[index]}
/>
<Button
onClick={() => {
prefabTag.set(prefabTag.value.filter((_, i) => i !== index))
}}
size="small"
variant="outline"
className="text-left text-xs"
>
{' '}
x{' '}
</Button>
</div>
))}
</div>
</Modal>
)}
{/* Overwrite Confirmation Modal */}
{isOverwriteModalVisible.value && (
<Modal
title="Overwrite Prefab"
onSubmit={() => {
isOverwriteConfirmed.set(true)
isOverwriteModalVisible.set(false)
onExportPrefab()
}}
onClose={() => {
isOverwriteConfirmed.set(false)
isOverwriteModalVisible.set(false)
}}
>
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
<p>Prefab with this name already exists. You will overwrite it.</p>
</div>
))}
</div>
</Modal>
</Modal>
)}
</>
)
}

0 comments on commit 051eae1

Please sign in to comment.