Forráskód Böngészése

Support for templated level creation (#17633)

Signed-off-by: Yaakuro <[email protected]>
Yaakuro 1 éve
szülő
commit
7d7fbb43bd

+ 3 - 0
Assets/Editor/Prefabs/Basic.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2f5c619a11b07935d87063ed253e2a15b83ecaa3a87f07a5e350b2ce89187c51
+size 26878

+ 387 - 0
Assets/Editor/Prefabs/Basic.prefab

@@ -0,0 +1,387 @@
+{
+    "ContainerEntity": {
+        "Id": "ContainerEntity",
+        "Name": "Basic",
+        "Components": {
+            "EditorDisabledCompositionComponent": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 10593268821715458406
+            },
+            "EditorEntityIconComponent": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 7904397583211057659
+            },
+            "EditorEntitySortComponent": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 15097443382011872719,
+                "Child Entity Order": [
+                    "Entity_[1379449802595]"
+                ]
+            },
+            "EditorInspectorComponent": {
+                "$type": "EditorInspectorComponent",
+                "Id": 9028208142210445783
+            },
+            "EditorLockComponent": {
+                "$type": "EditorLockComponent",
+                "Id": 18150128499906753747
+            },
+            "EditorOnlyEntityComponent": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 7216229212231741030
+            },
+            "EditorPendingCompositionComponent": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 5166675226912254616
+            },
+            "EditorPrefabComponent": {
+                "$type": "EditorPrefabComponent",
+                "Id": 17348824920491302694
+            },
+            "EditorVisibilityComponent": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 3716381488483090297
+            },
+            "TransformComponent": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 2964698134789647987,
+                "Parent Entity": ""
+            }
+        }
+    },
+    "Entities": {
+        "Entity_[1362269933411]": {
+            "Id": "Entity_[1362269933411]",
+            "Name": "Global Sky",
+            "Components": {
+                "Component_[1428633914413949476]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 1428633914413949476
+                },
+                "Component_[14936200426671614999]": {
+                    "$type": "AZ::Render::EditorImageBasedLightComponent",
+                    "Id": 14936200426671614999,
+                    "Controller": {
+                        "Configuration": {
+                            "diffuseImageAsset": {
+                                "assetId": {
+                                    "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+                                    "subId": 3000
+                                },
+                                "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage"
+                            },
+                            "specularImageAsset": {
+                                "assetId": {
+                                    "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+                                    "subId": 2000
+                                },
+                                "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage"
+                            }
+                        }
+                    },
+                    "diffuseImageAsset": {
+                        "assetId": {
+                            "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+                            "subId": 3000
+                        },
+                        "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage"
+                    },
+                    "specularImageAsset": {
+                        "assetId": {
+                            "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+                            "subId": 2000
+                        },
+                        "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage"
+                    }
+                },
+                "Component_[14994774102579326069]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 14994774102579326069
+                },
+                "Component_[15417479889044493340]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 15417479889044493340
+                },
+                "Component_[15826613364991382688]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 15826613364991382688
+                },
+                "Component_[1665003113283562343]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 1665003113283562343
+                },
+                "Component_[3704934735944502280]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 3704934735944502280
+                },
+                "Component_[5698542331457326479]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 5698542331457326479
+                },
+                "Component_[6644513399057217122]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 6644513399057217122,
+                    "Parent Entity": "Entity_[1379449802595]"
+                },
+                "Component_[931091830724002070]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 931091830724002070
+                }
+            }
+        },
+        "Entity_[1366564900707]": {
+            "Id": "Entity_[1366564900707]",
+            "Name": "Grid",
+            "Components": {
+                "Component_[11443347433215807130]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11443347433215807130
+                },
+                "Component_[14249419413039427459]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14249419413039427459
+                },
+                "Component_[15448581635946161318]": {
+                    "$type": "AZ::Render::EditorGridComponent",
+                    "Id": 15448581635946161318,
+                    "Controller": {
+                        "Configuration": {
+                            "primarySpacing": 4.0,
+                            "primaryColor": [
+                                0.501960813999176,
+                                0.501960813999176,
+                                0.501960813999176
+                            ],
+                            "secondarySpacing": 0.5,
+                            "secondaryColor": [
+                                0.250980406999588,
+                                0.250980406999588,
+                                0.250980406999588
+                            ]
+                        }
+                    }
+                },
+                "Component_[1843303322527297409]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 1843303322527297409
+                },
+                "Component_[380249072065273654]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 380249072065273654,
+                    "Parent Entity": "Entity_[1379449802595]"
+                },
+                "Component_[7476660583684339787]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 7476660583684339787
+                },
+                "Component_[7557626501215118375]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 7557626501215118375
+                },
+                "Component_[7984048488947365511]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 7984048488947365511
+                },
+                "Component_[8118181039276487398]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 8118181039276487398
+                },
+                "Component_[9189909764215270515]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 9189909764215270515
+                }
+            }
+        },
+        "Entity_[1370859868003]": {
+            "Id": "Entity_[1370859868003]",
+            "Name": "Camera",
+            "Components": {
+                "Component_[11895140916889160460]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11895140916889160460
+                },
+                "Component_[16880285896855930892]": {
+                    "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
+                    "Id": 16880285896855930892,
+                    "Controller": {
+                        "Configuration": {
+                            "Field of View": 55.0
+                        }
+                    }
+                },
+                "Component_[17187464423780271193]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 17187464423780271193
+                },
+                "Component_[17495696818315413311]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 17495696818315413311
+                },
+                "Component_[18086214374043522055]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 18086214374043522055,
+                    "Parent Entity": "Entity_[1379449802595]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            -12.883666038513184,
+                            5.73760986328125
+                        ],
+                        "Rotate": [
+                            -25.0,
+                            0.0,
+                            0.0
+                        ]
+                    }
+                },
+                "Component_[2654521436129313160]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 2654521436129313160
+                },
+                "Component_[5265045084611556958]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5265045084611556958
+                },
+                "Component_[7169798125182238623]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 7169798125182238623
+                },
+                "Component_[7255796294953281766]": {
+                    "$type": "GenericComponentWrapper",
+                    "Id": 7255796294953281766,
+                    "m_template": {
+                        "$type": "FlyCameraInputComponent"
+                    }
+                },
+                "Component_[8866210352157164042]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 8866210352157164042
+                },
+                "Component_[9129253381063760879]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 9129253381063760879
+                }
+            }
+        },
+        "Entity_[1375154835299]": {
+            "Id": "Entity_[1375154835299]",
+            "Name": "Sun",
+            "Components": {
+                "Component_[13620450453324765907]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 13620450453324765907
+                },
+                "Component_[2134313378593666258]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 2134313378593666258
+                },
+                "Component_[234010807770404186]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 234010807770404186
+                },
+                "Component_[2970359110423865725]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 2970359110423865725
+                },
+                "Component_[3722854130373041803]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 3722854130373041803
+                },
+                "Component_[5992533738676323195]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5992533738676323195
+                },
+                "Component_[7378860763541895402]": {
+                    "$type": "AZ::Render::EditorDirectionalLightComponent",
+                    "Id": 7378860763541895402,
+                    "Controller": {
+                        "Configuration": {
+                            "Intensity": 1.0,
+                            "CameraEntityId": "",
+                            "ShadowFilterMethod": 1
+                        }
+                    }
+                },
+                "Component_[7892834440890947578]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 7892834440890947578,
+                    "Parent Entity": "Entity_[1379449802595]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            0.0,
+                            13.487043380737305
+                        ],
+                        "Rotate": [
+                            -76.13099670410156,
+                            -0.847000002861023,
+                            -15.8100004196167
+                        ]
+                    }
+                },
+                "Component_[8599729549570828259]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 8599729549570828259
+                },
+                "Component_[952797371922080273]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 952797371922080273
+                }
+            }
+        },
+        "Entity_[1379449802595]": {
+            "Id": "Entity_[1379449802595]",
+            "Name": "Basic",
+            "Components": {
+                "Component_[10757302973393310045]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 10757302973393310045,
+                    "Parent Entity": "ContainerEntity"
+                },
+                "Component_[14505817420424255464]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14505817420424255464,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 10757302973393310045
+                        }
+                    ]
+                },
+                "Component_[14988041764659020032]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 14988041764659020032
+                },
+                "Component_[15900837685796817138]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 15900837685796817138
+                },
+                "Component_[3298767348226484884]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 3298767348226484884
+                },
+                "Component_[4076975109609220594]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 4076975109609220594
+                },
+                "Component_[5679760548946028854]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5679760548946028854
+                },
+                "Component_[5855590796136709437]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 5855590796136709437,
+                    "Child Entity Order": [
+                        "Entity_[1375154835299]",
+                        "Entity_[1362269933411]",
+                        "Entity_[1366564900707]",
+                        "Entity_[1370859868003]"
+                    ]
+                },
+                "Component_[9277695270015777859]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 9277695270015777859
+                }
+            }
+        }
+    }
+}

+ 3 - 0
Assets/Editor/Prefabs/Default_Level.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c8fa9cb2cf60a98ca88e2f5b299be4f459101aec2be1ddd2deb5e716e06bd96a
+size 96788

+ 3 - 0
Assets/Editor/Prefabs/Empty.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5dfad8c6f5bde570ef574d6daf4f68a39507ad9d0a5193bdc75816b62528de4f
+size 5973

+ 49 - 0
Assets/Editor/Prefabs/Empty.prefab

@@ -0,0 +1,49 @@
+{
+    "ContainerEntity": {
+        "Id": "ContainerEntity",
+        "Name": "Empty",
+        "Components": {
+            "EditorDisabledCompositionComponent": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 16616931740997949210
+            },
+            "EditorEntityIconComponent": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 2778716686621881360
+            },
+            "EditorEntitySortComponent": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 1069995033707506449
+            },
+            "EditorInspectorComponent": {
+                "$type": "EditorInspectorComponent",
+                "Id": 4185413252280323606
+            },
+            "EditorLockComponent": {
+                "$type": "EditorLockComponent",
+                "Id": 4068240492793213930
+            },
+            "EditorOnlyEntityComponent": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 1499221618774487829
+            },
+            "EditorPendingCompositionComponent": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 10852705643903064770
+            },
+            "EditorPrefabComponent": {
+                "$type": "EditorPrefabComponent",
+                "Id": 12239744644494076517
+            },
+            "EditorVisibilityComponent": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 17437522806552955660
+            },
+            "TransformComponent": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 4584354821622104079,
+                "Parent Entity": ""
+            }
+        }
+    }
+}

+ 4 - 3
Code/Editor/CryEdit.cpp

@@ -2596,7 +2596,7 @@ void CCryEditApp::OnUpdatePlayGame(QAction* action)
 }
 }
 
 
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
-CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& levelName, QString& fullyQualifiedLevelName /* ={} */)
+CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& templateName, const QString& levelName, QString& fullyQualifiedLevelName /* ={} */)
 {
 {
     // If we are creating a new level and we're in simulate mode, then switch it off before we do anything else
     // If we are creating a new level and we're in simulate mode, then switch it off before we do anything else
     if (GetIEditor()->GetGameEngine() && GetIEditor()->GetGameEngine()->GetSimulationMode())
     if (GetIEditor()->GetGameEngine() && GetIEditor()->GetGameEngine()->GetSimulationMode())
@@ -2672,7 +2672,8 @@ CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& levelNam
     auto* service = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
     auto* service = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
     if (service)
     if (service)
     {
     {
-        service->CreateNewLevelPrefab(fullyQualifiedLevelName.toUtf8().constData(), DefaultLevelTemplateName);
+        const AZStd::string templateNameString(templateName.toUtf8().constData());
+        service->CreateNewLevelPrefab(fullyQualifiedLevelName.toUtf8().constData(), templateNameString);
     }
     }
 
 
     if (GetIEditor()->GetDocument()->Save())
     if (GetIEditor()->GetDocument()->Save())
@@ -2792,7 +2793,7 @@ bool CCryEditApp::CreateLevel(bool& wasCreateLevelOperationCancelled)
     GetIEditor()->StartLevelErrorReportRecording();
     GetIEditor()->StartLevelErrorReportRecording();
 
 
     QString fullyQualifiedLevelName;
     QString fullyQualifiedLevelName;
-    ECreateLevelResult result = CreateLevel(levelNameWithPath, fullyQualifiedLevelName);
+    ECreateLevelResult result = CreateLevel(dlg.GetTemplateName(), levelNameWithPath, fullyQualifiedLevelName);
 
 
     if (result == ECLR_ALREADY_EXISTS)
     if (result == ECLR_ALREADY_EXISTS)
     {
     {

+ 1 - 3
Code/Editor/CryEdit.h

@@ -131,7 +131,7 @@ public:
     void SetEditorWindowTitle(QString sTitleStr = QString(), QString sPreTitleStr = QString(), QString sPostTitleStr = QString());
     void SetEditorWindowTitle(QString sTitleStr = QString(), QString sPreTitleStr = QString(), QString sPostTitleStr = QString());
     RecentFileList* GetRecentFileList();
     RecentFileList* GetRecentFileList();
     virtual void AddToRecentFileList(const QString& lpszPathName);
     virtual void AddToRecentFileList(const QString& lpszPathName);
-    ECreateLevelResult CreateLevel(const QString& levelName, QString& fullyQualifiedLevelName);
+    ECreateLevelResult CreateLevel(const QString& templateName, const QString& levelName, QString& fullyQualifiedLevelName);
     bool FirstInstance(bool bForceNewInstance = false);
     bool FirstInstance(bool bForceNewInstance = false);
     void InitFromCommandLine(CEditCommandLineInfo& cmdInfo);
     void InitFromCommandLine(CEditCommandLineInfo& cmdInfo);
     bool CheckIfAlreadyRunning();
     bool CheckIfAlreadyRunning();
@@ -334,8 +334,6 @@ AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
 AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
 AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
 
 
 private:
 private:
-    static inline constexpr const char* DefaultLevelTemplateName = "Prefabs/Default_Level.prefab";
-
     // Optional Uri to start an external lua debugger. If not specified,
     // Optional Uri to start an external lua debugger. If not specified,
     // then the Editor will open LuaIDE.exe.
     // then the Editor will open LuaIDE.exe.
     // For example, if using The Visual Studio Debugger Extension provided by lumbermixalot
     // For example, if using The Visual Studio Debugger Extension provided by lumbermixalot

+ 6 - 6
Code/Editor/CryEditPy.cpp

@@ -178,13 +178,13 @@ namespace
         return false;
         return false;
     }
     }
 
 
-    int PyCreateLevel(const char* levelName, [[maybe_unused]] int resolution, [[maybe_unused]] int unitSize, [[maybe_unused]] bool bUseTerrain)
+    int PyCreateLevel(const char* templateName, const char* levelName, [[maybe_unused]] int resolution, [[maybe_unused]] int unitSize, [[maybe_unused]] bool bUseTerrain)
     {
     {
         QString qualifiedName;
         QString qualifiedName;
-        return CCryEditApp::instance()->CreateLevel(levelName, qualifiedName);
+        return CCryEditApp::instance()->CreateLevel(templateName, levelName, qualifiedName);
     }
     }
 
 
-    int PyCreateLevelNoPrompt(const char* levelName, [[maybe_unused]] int heightmapResolution, [[maybe_unused]] int heightmapUnitSize,
+    int PyCreateLevelNoPrompt(const char* templateName, const char* levelName, [[maybe_unused]] int heightmapResolution, [[maybe_unused]] int heightmapUnitSize,
         [[maybe_unused]] int terrainExportTextureSize, [[maybe_unused]] bool useTerrain)
         [[maybe_unused]] int terrainExportTextureSize, [[maybe_unused]] bool useTerrain)
     {
     {
         // If a level was open, ignore any unsaved changes if it had been modified
         // If a level was open, ignore any unsaved changes if it had been modified
@@ -194,7 +194,7 @@ namespace
         }
         }
 
 
         QString qualifiedName;
         QString qualifiedName;
-        return CCryEditApp::instance()->CreateLevel(levelName, qualifiedName);
+        return CCryEditApp::instance()->CreateLevel(templateName, levelName, qualifiedName);
     }
     }
 
 
     const char* PyGetCurrentLevelName()
     const char* PyGetCurrentLevelName()
@@ -407,8 +407,8 @@ namespace AzToolsFramework
             addLegacyGeneral(behaviorContext->Method("open_level", ::PyOpenLevel, nullptr, "Opens a level."));
             addLegacyGeneral(behaviorContext->Method("open_level", ::PyOpenLevel, nullptr, "Opens a level."));
             addLegacyGeneral(behaviorContext->Method("open_level_no_prompt", ::PyOpenLevelNoPrompt, nullptr, "Opens a level. Doesn't prompt user about saving a modified level."));
             addLegacyGeneral(behaviorContext->Method("open_level_no_prompt", ::PyOpenLevelNoPrompt, nullptr, "Opens a level. Doesn't prompt user about saving a modified level."));
             addLegacyGeneral(behaviorContext->Method("reload_current_level", ::PyReloadCurrentLevel, nullptr, "Re-loads the current level. If no level is loaded, then does nothing."));
             addLegacyGeneral(behaviorContext->Method("reload_current_level", ::PyReloadCurrentLevel, nullptr, "Re-loads the current level. If no level is loaded, then does nothing."));
-            addLegacyGeneral(behaviorContext->Method("create_level", ::PyCreateLevel, nullptr, "Creates a level with the parameters of 'levelName', 'resolution', 'unitSize' and 'bUseTerrain'."));
-            addLegacyGeneral(behaviorContext->Method("create_level_no_prompt", ::PyCreateLevelNoPrompt, nullptr, "Creates a level with the parameters of 'levelName', 'resolution', 'unitSize' and 'bUseTerrain'."));
+            addLegacyGeneral(behaviorContext->Method("create_level", ::PyCreateLevel, nullptr, "Creates a level with the parameters of 'templateName', 'levelName', 'resolution', 'unitSize' and 'bUseTerrain'."));
+            addLegacyGeneral(behaviorContext->Method("create_level_no_prompt", ::PyCreateLevelNoPrompt, nullptr, "Creates a level with the parameters of 'templateName','levelName', 'resolution', 'unitSize' and 'bUseTerrain'."));
             addLegacyGeneral(behaviorContext->Method("get_game_folder", PyGetGameFolderAsString, nullptr, "Gets the path to the Game folder of current project."));
             addLegacyGeneral(behaviorContext->Method("get_game_folder", PyGetGameFolderAsString, nullptr, "Gets the path to the Game folder of current project."));
             addLegacyGeneral(behaviorContext->Method("get_build_folder", PyGetBuildFolderAsString, nullptr, "Gets the build folder path of current project."));
             addLegacyGeneral(behaviorContext->Method("get_build_folder", PyGetBuildFolderAsString, nullptr, "Gets the build folder path of current project."));
             addLegacyGeneral(behaviorContext->Method("get_current_level_name", PyGetCurrentLevelName, nullptr, "Gets the name of the current level."));
             addLegacyGeneral(behaviorContext->Method("get_current_level_name", PyGetCurrentLevelName, nullptr, "Gets the name of the current level."));

+ 8 - 4
Code/Editor/EditorToolsApplication.cpp

@@ -227,14 +227,16 @@ namespace EditorInternal
         return OpenLevel(levelName);
         return OpenLevel(levelName);
     }
     }
 
 
-    int EditorToolsApplication::CreateLevel(AZStd::string_view levelName, bool /*bUseTerrain*/)
+    int EditorToolsApplication::CreateLevel(AZStd::string_view templateName, AZStd::string_view levelName, bool /*bUseTerrain*/)
     {
     {
         // Clang warns about a temporary being created in a function's argument list, so fullyQualifiedLevelName before the call
         // Clang warns about a temporary being created in a function's argument list, so fullyQualifiedLevelName before the call
         QString fullyQualifiedLevelName;
         QString fullyQualifiedLevelName;
-        return CCryEditApp::instance()->CreateLevel(QString::fromUtf8(levelName.data(), static_cast<int>(levelName.size())), fullyQualifiedLevelName);
+        return CCryEditApp::instance()->CreateLevel(QString::fromUtf8(templateName.data(), static_cast<int>(templateName.size())),
+                                                    QString::fromUtf8(levelName.data(), static_cast<int>(levelName.size())),
+                                                    fullyQualifiedLevelName);
     }
     }
 
 
-    int EditorToolsApplication::CreateLevelNoPrompt(AZStd::string_view levelName, int /*terrainExportTextureSize*/, bool /*useTerrain*/)
+    int EditorToolsApplication::CreateLevelNoPrompt(AZStd::string_view templateName, AZStd::string_view levelName, int /*terrainExportTextureSize*/, bool /*useTerrain*/)
     {
     {
         // If a level was open, ignore any unsaved changes if it had been modified
         // If a level was open, ignore any unsaved changes if it had been modified
         if (GetIEditor()->IsLevelLoaded())
         if (GetIEditor()->IsLevelLoaded())
@@ -244,7 +246,9 @@ namespace EditorInternal
 
 
         // Clang warns about a temporary being created in a function's argument list, so fullyQualifiedLevelName before the call
         // Clang warns about a temporary being created in a function's argument list, so fullyQualifiedLevelName before the call
         QString fullyQualifiedLevelName;
         QString fullyQualifiedLevelName;
-        return CCryEditApp::instance()->CreateLevel(QString::fromUtf8(levelName.data(), static_cast<int>(levelName.size())), fullyQualifiedLevelName);
+        return CCryEditApp::instance()->CreateLevel(QString::fromUtf8(templateName.data(), static_cast<int>(templateName.size())),
+                                                    QString::fromUtf8(levelName.data(), static_cast<int>(levelName.size())),
+                                                    fullyQualifiedLevelName);
     }
     }
 
 
     AZStd::string EditorToolsApplication::GetCurrentLevelName() const
     AZStd::string EditorToolsApplication::GetCurrentLevelName() const

+ 2 - 2
Code/Editor/EditorToolsApplication.h

@@ -62,8 +62,8 @@ namespace EditorInternal
         bool OpenLevel(AZStd::string_view levelName) override;
         bool OpenLevel(AZStd::string_view levelName) override;
         bool OpenLevelNoPrompt(AZStd::string_view levelName) override;
         bool OpenLevelNoPrompt(AZStd::string_view levelName) override;
 
 
-        int CreateLevel(AZStd::string_view levelName, bool bUseTerrain) override;
-        int CreateLevelNoPrompt(AZStd::string_view levelName, int terrainExportTextureSize, bool useTerrain) override;
+        int CreateLevel(AZStd::string_view templateName, AZStd::string_view levelName, bool bUseTerrain) override;
+        int CreateLevelNoPrompt(AZStd::string_view templateName, AZStd::string_view levelName, int terrainExportTextureSize, bool useTerrain) override;
 
 
         void Exit() override;
         void Exit() override;
         void ExitNoPrompt() override;
         void ExitNoPrompt() override;

+ 2 - 2
Code/Editor/EditorToolsApplicationAPI.h

@@ -30,8 +30,8 @@ namespace EditorInternal
         virtual bool OpenLevel(AZStd::string_view levelName) = 0;
         virtual bool OpenLevel(AZStd::string_view levelName) = 0;
         virtual bool OpenLevelNoPrompt(AZStd::string_view levelName) = 0;
         virtual bool OpenLevelNoPrompt(AZStd::string_view levelName) = 0;
 
 
-        virtual int CreateLevel(AZStd::string_view levelName, bool bUseTerrain) = 0;
-        virtual int CreateLevelNoPrompt(AZStd::string_view levelName, int terrainExportTextureSize, bool useTerrain) = 0;
+        virtual int CreateLevel(AZStd::string_view templateName, AZStd::string_view levelName, bool bUseTerrain) = 0;
+        virtual int CreateLevelNoPrompt(AZStd::string_view templateName, AZStd::string_view levelName, int terrainExportTextureSize, bool useTerrain) = 0;
 
 
         virtual AZStd::string GetGameFolder() const = 0;
         virtual AZStd::string GetGameFolder() const = 0;
         virtual AZStd::string GetCurrentLevelName() const = 0;
         virtual AZStd::string GetCurrentLevelName() const = 0;

+ 79 - 19
Code/Editor/NewLevelDialog.cpp

@@ -8,7 +8,8 @@
 
 
 
 
 #include "EditorDefs.h"
 #include "EditorDefs.h"
-
+#include <AzCore/Utils/Utils.h>
+#include <AzCore/Settings/SettingsRegistryVisitorUtils.h>
 #include "NewLevelDialog.h"
 #include "NewLevelDialog.h"
 
 
 // Qt
 // Qt
@@ -17,6 +18,7 @@
 #include <QMessageBox>
 #include <QMessageBox>
 #include <QTimer>
 #include <QTimer>
 #include <QToolButton>
 #include <QToolButton>
+#include <QListWidgetItem>
 
 
 AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
 AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
 #include <ui_NewLevelDialog.h>
 #include <ui_NewLevelDialog.h>
@@ -25,6 +27,7 @@ AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
 
 
 // Folder in which levels are stored
 // Folder in which levels are stored
 static const char kNewLevelDialog_LevelsFolder[] = "Levels";
 static const char kNewLevelDialog_LevelsFolder[] = "Levels";
+static constexpr const char* RegistryKey_CustomTemplatePaths = "/O3DE/Preferences/Prefab/CustomTemplatePaths";
 
 
 class LevelFolderValidator : public QValidator
 class LevelFolderValidator : public QValidator
 {
 {
@@ -49,11 +52,17 @@ private:
     CNewLevelDialog* m_parentDialog;
     CNewLevelDialog* m_parentDialog;
 };
 };
 
 
+static QString ChangeFileExtension(const QString& filePath, const QString& newExtension)
+{
+    QFileInfo fileInfo(filePath);
+    QString newFilePath = fileInfo.absolutePath() + QDir::separator() + fileInfo.baseName() + "." + newExtension;
+    return newFilePath;
+}
+
 // CNewLevelDialog dialog
 // CNewLevelDialog dialog
 
 
 CNewLevelDialog::CNewLevelDialog(QWidget* pParent /*=nullptr*/)
 CNewLevelDialog::CNewLevelDialog(QWidget* pParent /*=nullptr*/)
     : QDialog(pParent)
     : QDialog(pParent)
-    , m_bUpdate(false)
     , ui(new Ui::CNewLevelDialog)
     , ui(new Ui::CNewLevelDialog)
     , m_initialized(false)
     , m_initialized(false)
 {
 {
@@ -61,15 +70,8 @@ CNewLevelDialog::CNewLevelDialog(QWidget* pParent /*=nullptr*/)
 
 
     setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
     setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
     setWindowTitle(tr("New Level"));
     setWindowTitle(tr("New Level"));
-    setMaximumSize(QSize(320, 180));
-    adjustSize();
-
-    m_bIsResize = false;
-
-
-    ui->TITLE->setText(tr("Assign a name and location to the new level."));
-    ui->STATIC1->setText(tr("Location:"));
-    ui->STATIC2->setText(tr("Name:"));
+    setStyleSheet("QListWidget::item {height: 148px; padding-left: 0px; padding-right: 0px; background-color: transparent;}");
+    InitTemplateListWidget();
 
 
     // Level name only supports ASCII characters
     // Level name only supports ASCII characters
     QRegExp rx("[_a-zA-Z0-9-]+");
     QRegExp rx("[_a-zA-Z0-9-]+");
@@ -90,7 +92,6 @@ CNewLevelDialog::CNewLevelDialog(QWidget* pParent /*=nullptr*/)
 
 
     connect(ui->LEVEL_FOLDERS->lineEdit(), &QLineEdit::textEdited, this, &CNewLevelDialog::OnLevelNameChange);
     connect(ui->LEVEL_FOLDERS->lineEdit(), &QLineEdit::textEdited, this, &CNewLevelDialog::OnLevelNameChange);
     connect(ui->LEVEL_FOLDERS, &AzQtComponents::BrowseEdit::attachedButtonTriggered, this, &CNewLevelDialog::PopupAssetPicker);
     connect(ui->LEVEL_FOLDERS, &AzQtComponents::BrowseEdit::attachedButtonTriggered, this, &CNewLevelDialog::PopupAssetPicker);
-
     connect(ui->LEVEL, &QLineEdit::textChanged, this, &CNewLevelDialog::OnLevelNameChange);
     connect(ui->LEVEL, &QLineEdit::textChanged, this, &CNewLevelDialog::OnLevelNameChange);
 
 
     m_levelFolders = GetLevelsFolder();
     m_levelFolders = GetLevelsFolder();
@@ -105,10 +106,76 @@ CNewLevelDialog::CNewLevelDialog(QWidget* pParent /*=nullptr*/)
     ReloadLevelFolder();
     ReloadLevelFolder();
 }
 }
 
 
+
+
 CNewLevelDialog::~CNewLevelDialog()
 CNewLevelDialog::~CNewLevelDialog()
 {
 {
 }
 }
 
 
+void CNewLevelDialog::InitTemplateListWidget() const
+{
+    ui->listTemplates->clear();
+
+    QStringList templatePaths;
+    if (AZ::SettingsRegistryInterface* settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry)
+    {
+        auto AppendCustomTemplatePath = [&templatePaths](const AZ::SettingsRegistryInterface::VisitArgs& visitArgs)
+        {
+            AZ::IO::FixedMaxPath customTemplatePath;
+            if (visitArgs.m_registry.Get(customTemplatePath.Native(), visitArgs.m_jsonKeyPath))
+            {
+                if (AZ::IO::FileIOBase::GetInstance()->ResolvePath(customTemplatePath, customTemplatePath))
+                {
+                    templatePaths.push_back(QString::fromUtf8(customTemplatePath.c_str(), int(customTemplatePath.Native().size())));
+                }
+            }
+
+            return AZ::SettingsRegistryInterface::VisitResponse::Skip;
+        };
+
+        AZ::SettingsRegistryVisitorUtils::VisitObject(*settingsRegistry, AppendCustomTemplatePath, RegistryKey_CustomTemplatePaths);
+    }
+
+    // Get all prefab files.
+    const QStringList fileFilter = {"*.prefab"};
+    QStringList allTemplateFiles;
+    for(const QString& path: templatePaths)
+    {
+        QDir projectTemplateDirectory(path);
+        projectTemplateDirectory.setNameFilters(fileFilter);
+
+        const QStringList projectTemplateFiles = projectTemplateDirectory.entryList(QDir::Files);
+        for (const QString& fileName: projectTemplateFiles)
+        {
+            allTemplateFiles.push_back(projectTemplateDirectory.filePath(fileName));
+        }
+    }
+
+    // Create the item with its icons to the QListWidget.
+    const QIcon defaultIcon(":/NewLevel/res/Prefab_80.svg");
+    for (const QString& fileName: allTemplateFiles)
+    {
+        QFileInfo info(fileName);
+        auto* item = new QListWidgetItem(info.baseName());
+        const QString iconPath = ChangeFileExtension(fileName, "png");
+        const QIcon itemIcon = QFile::exists(iconPath) ? QIcon(iconPath) : defaultIcon;
+        item->setIcon(itemIcon);
+        item->setData(Qt::UserRole, fileName);
+        ui->listTemplates->addItem(item);
+    }
+
+    const QSize iconSize(128, 128);
+    ui->listTemplates->setViewMode(QListWidget::IconMode);
+    ui->listTemplates->setIconSize(iconSize);
+    ui->listTemplates->setDragDropMode(QAbstractItemView::NoDragDrop);
+}
+
+QString CNewLevelDialog::GetTemplateName() const
+{
+    const QString name = ui->listTemplates->currentItem()->data(Qt::UserRole).toString();
+    return name;
+}
+
 void CNewLevelDialog::OnStartup()
 void CNewLevelDialog::OnStartup()
 {
 {
     UpdateData(false);
     UpdateData(false);
@@ -148,7 +215,6 @@ void CNewLevelDialog::OnInitDialog()
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 void CNewLevelDialog::ReloadLevelFolder()
 void CNewLevelDialog::ReloadLevelFolder()
 {
 {
-    m_itemFolders.clear();
     ui->LEVEL_FOLDERS->lineEdit()->clear();
     ui->LEVEL_FOLDERS->lineEdit()->clear();
     ui->LEVEL_FOLDERS->setText(QString(kNewLevelDialog_LevelsFolder) + '/');
     ui->LEVEL_FOLDERS->setText(QString(kNewLevelDialog_LevelsFolder) + '/');
 }
 }
@@ -233,12 +299,6 @@ void CNewLevelDialog::PopupAssetPicker()
     }
     }
 }
 }
 
 
-//////////////////////////////////////////////////////////////////////////
-void CNewLevelDialog::IsResize(bool bIsResize)
-{
-    m_bIsResize = bIsResize;
-}
-
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 void CNewLevelDialog::showEvent(QShowEvent* event)
 void CNewLevelDialog::showEvent(QShowEvent* event)
 {
 {

+ 4 - 17
Code/Editor/NewLevelDialog.h

@@ -8,14 +8,9 @@
 
 
 
 
 #pragma once
 #pragma once
-#ifndef CRYINCLUDE_EDITOR_NEWLEVELDIALOG_H
-#define CRYINCLUDE_EDITOR_NEWLEVELDIALOG_H
 
 
 #if !defined(Q_MOC_RUN)
 #if !defined(Q_MOC_RUN)
 #include <QScopedPointer>
 #include <QScopedPointer>
-
-#include <vector>
-
 #include <QAbstractButton>
 #include <QAbstractButton>
 #include <QDialog>
 #include <QDialog>
 #endif
 #endif
@@ -30,22 +25,20 @@ class CNewLevelDialog
     Q_OBJECT
     Q_OBJECT
 
 
 public:
 public:
-    CNewLevelDialog(QWidget* pParent = nullptr);   // standard constructor
+    CNewLevelDialog(QWidget* pParent = nullptr);
     ~CNewLevelDialog();
     ~CNewLevelDialog();
 
 
     QString GetLevel() const;
     QString GetLevel() const;
-    void IsResize(bool bIsResize);
     bool ValidateLevel();
     bool ValidateLevel();
+    QString GetTemplateName() const;
 
 
 protected:
 protected:
     void UpdateData(bool fromUi = true);
     void UpdateData(bool fromUi = true);
     void OnInitDialog();
     void OnInitDialog();
-
     void ReloadLevelFolder();
     void ReloadLevelFolder();
-
-    void showEvent(QShowEvent* event);
-
+    void showEvent(QShowEvent* event) override;
     QString GetLevelsFolder() const;
     QString GetLevelsFolder() const;
+    void InitTemplateListWidget() const;
 
 
 protected slots:
 protected slots:
     void OnLevelNameChange();
     void OnLevelNameChange();
@@ -56,12 +49,6 @@ protected slots:
 public:
 public:
     QString         m_level;
     QString         m_level;
     QString         m_levelFolders;
     QString         m_levelFolders;
-    bool                m_bIsResize;
-    bool                m_bUpdate;
-
-    std::vector<QString>    m_itemFolders;
-
     QScopedPointer<Ui::CNewLevelDialog> ui;
     QScopedPointer<Ui::CNewLevelDialog> ui;
     bool m_initialized;
     bool m_initialized;
 };
 };
-#endif // CRYINCLUDE_EDITOR_NEWLEVELDIALOG_H

+ 6 - 0
Code/Editor/NewLevelDialog.qrc

@@ -0,0 +1,6 @@
+<RCC>
+  <qresource prefix="/NewLevel">
+    <file>res/folder.png</file>
+    <file>res/Prefab_80.svg</file>
+  </qresource>
+</RCC>

+ 89 - 115
Code/Editor/NewLevelDialog.ui

@@ -6,124 +6,96 @@
    <rect>
    <rect>
     <x>0</x>
     <x>0</x>
     <y>0</y>
     <y>0</y>
-    <width>430</width>
-    <height>180</height>
+    <width>471</width>
+    <height>371</height>
    </rect>
    </rect>
   </property>
   </property>
-   <layout class="QVBoxLayout" name="verticalLayout">
-     <item>
-       <spacer name="topVerticalSpacer">
-         <property name="orientation">
-           <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-           <size>
-             <width>20</width>
-             <height>10</height>
-           </size>
-         </property>
-       </spacer>
-     </item>
-     <item>
-       <widget class="QLabel" name="TITLE">
-         <property name="text">
-           <string>Assign a name and location to the new level.</string>
-         </property>
-         <property name="alignment">
-           <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
-         </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QListWidget" name="listTemplates">
+     <property name="movement">
+      <enum>QListView::Static</enum>
+     </property>
+     <property name="resizeMode">
+      <enum>QListView::Adjust</enum>
+     </property>
+     <property name="spacing">
+      <number>4</number>
+     </property>
+     <property name="viewMode">
+      <enum>QListView::IconMode</enum>
+     </property>
+     <property name="uniformItemSizes">
+      <bool>true</bool>
+     </property>
+     <property name="selectionRectVisible">
+      <bool>false</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="STATIC_GROUP1">
+     <layout class="QFormLayout" name="formLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="STATIC2">
+        <property name="text">
+         <string>Name</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+        </property>
+        <property name="buddy">
+         <cstring>LEVEL</cstring>
+        </property>
        </widget>
        </widget>
-     </item>
-     <item>
-       <spacer name="verticalSpacer">
-         <property name="orientation">
-           <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-           <size>
-             <width>20</width>
-             <height>20</height>
-           </size>
-         </property>
-       </spacer>
-     </item>
-     <item>
-       <layout class="QGridLayout" name="gridLayout">
-         <item row="0" column="0" colspan="2">
-           <widget class="QGroupBox" name="STATIC_GROUP1">
-             <property name="styleSheet">
-               <string notr="true">border: 0px;</string>
-             </property>
-             <layout class="QFormLayout" name="formLayout">
-               <item row="0" column="0">
-                 <widget class="QLabel" name="STATIC2">
-                   <property name="text">
-                     <string>Name</string>
-                   </property>
-                   <property name="alignment">
-                     <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
-                   </property>
-                   <property name="buddy">
-                     <cstring>LEVEL</cstring>
-                   </property>
-                 </widget>
-               </item>
-               <item row="0" column="1">
-                 <widget class="QLineEdit" name="LEVEL">
-                   <property name="alignment">
-                     <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-                   </property>
-                 </widget>
-               </item>
-               <item row="1" column="0">
-                 <widget class="QLabel" name="STATIC1">
-                   <property name="minimumSize">
-                     <size>
-                       <width>100</width>
-                       <height>0</height>
-                     </size>
-                   </property>
-                   <property name="text">
-                     <string>Location</string>
-                   </property>
-                   <property name="alignment">
-                     <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
-                   </property>
-                   <property name="buddy">
-                     <cstring>LEVEL_FOLDERS</cstring>
-                   </property>
-                 </widget>
-               </item>
-               <item row="1" column="1">
-                 <widget class="AzQtComponents::BrowseEdit" name="LEVEL_FOLDERS" native="true">
-                   <property name="sizePolicy">
-                     <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
-                       <horstretch>0</horstretch>
-                       <verstretch>0</verstretch>
-                     </sizepolicy>
-                   </property>
-                 </widget>
-               </item>
-             </layout>
-           </widget>
-         </item>
-       </layout>
-     </item>
-     <item>
-       <spacer name="verticalSpacer2">
-         <property name="orientation">
-           <enum>Qt::Vertical</enum>
-         </property>
-       </spacer>
-     </item>
-     <item row="1" column="0" colspan="2">
-       <widget class="QDialogButtonBox" name="buttonBox">
-         <property name="standardButtons">
-           <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-         </property>
+      </item>
+      <item row="0" column="1">
+       <widget class="QLineEdit" name="LEVEL">
+        <property name="alignment">
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+        </property>
        </widget>
        </widget>
-     </item>
-   </layout>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="STATIC1">
+        <property name="minimumSize">
+         <size>
+          <width>100</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>Location</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+        </property>
+        <property name="buddy">
+         <cstring>LEVEL_FOLDERS</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="AzQtComponents::BrowseEdit" name="LEVEL_FOLDERS" native="true">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
  </widget>
  </widget>
  <customwidgets>
  <customwidgets>
   <customwidget>
   <customwidget>
@@ -136,7 +108,9 @@
  <tabstops>
  <tabstops>
   <tabstop>LEVEL</tabstop>
   <tabstop>LEVEL</tabstop>
  </tabstops>
  </tabstops>
- <resources/>
+ <resources>
+  <include location="NewLevelDialog.qrc"/>
+ </resources>
  <connections>
  <connections>
   <connection>
   <connection>
    <sender>buttonBox</sender>
    <sender>buttonBox</sender>

+ 2 - 0
Code/Editor/editor_lib_files.cmake

@@ -222,6 +222,7 @@ set(FILES
     res/veed_tree.bmp
     res/veed_tree.bmp
     res/vegetati.bmp
     res/vegetati.bmp
     res/vegtree.bmp
     res/vegtree.bmp
+    res/Prefab_80.svg
     res/video_record.ico
     res/video_record.ico
     res/warning16x16.ico
     res/warning16x16.ico
     res/water.bmp
     res/water.bmp
@@ -382,6 +383,7 @@ set(FILES
     NewLevelDialog.cpp
     NewLevelDialog.cpp
     NewLevelDialog.h
     NewLevelDialog.h
     NewLevelDialog.ui
     NewLevelDialog.ui
+    NewLevelDialog.qrc
     Dialogs/PythonScriptsDialog.cpp
     Dialogs/PythonScriptsDialog.cpp
     Dialogs/PythonScriptsDialog.h
     Dialogs/PythonScriptsDialog.h
     Dialogs/PythonScriptsDialog.ui
     Dialogs/PythonScriptsDialog.ui

+ 3 - 0
Code/Editor/res/Prefab_80.svg

@@ -0,0 +1,3 @@
+<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M66.5521 56.4173C67.6477 55.8373 68.3333 54.7018 68.3333 53.4673V26.7354C68.3333 25.5349 67.6845 24.4298 66.6354 23.8436L43.3726 10.8459C41.3553 9.71877 38.8921 9.71625 36.864 10.8393L13.3922 23.8368C12.3277 24.4263 11.6667 25.5448 11.6667 26.7566L11.6667 53.4761C11.6667 54.7059 12.3472 55.833 13.4365 56.4069L38.5039 69.6154C39.4808 70.1301 40.6518 70.128 41.6307 69.6099L66.5521 56.4173ZM41.6732 24.9691V15.5861L63.1725 27.4054V50.7711L54.6523 46.3625V33.5544L41.6732 40.9791V54.6525L53.2689 48.8595L62.0294 53.1073L40.06 64.8887L17.9082 53.1073L26.7317 48.8595L38.7801 54.6525V40.9791L25.3812 33.5544V46.3625L16.9475 50.7711V27.4054L38.7801 15.5861V24.9691L26.7317 31.6915L40.4377 38.4731L53.2689 31.6915L41.6732 24.9691Z" fill="white"/>
+</svg>

+ 3 - 1
Code/Framework/AzQtComponents/AzQtComponents/Components/Style.cpp

@@ -75,6 +75,7 @@ AZ_POP_DISABLE_WARNING
 #include <QtWidgets/private/qstylehelper_p.h>
 #include <QtWidgets/private/qstylehelper_p.h>
 
 
 #include <limits>
 #include <limits>
+#include <QListWidget>
 
 
 namespace AzQtComponents
 namespace AzQtComponents
 {
 {
@@ -789,7 +790,8 @@ namespace AzQtComponents
 
 
     QPixmap Style::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap& pixmap, const QStyleOption* option) const
     QPixmap Style::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap& pixmap, const QStyleOption* option) const
     {
     {
-        if (qobject_cast<const TableView*>(m_drawControlWidget) && iconMode == QIcon::Mode::Selected)
+        if ((qobject_cast<const TableView*>(m_drawControlWidget) ||
+            qobject_cast<const QListWidget*>(m_drawControlWidget)) && iconMode == QIcon::Mode::Selected)
         {
         {
             return QProxyStyle::generatedIconPixmap(QIcon::Mode::Active, pixmap, option);
             return QProxyStyle::generatedIconPixmap(QIcon::Mode::Active, pixmap, option);
         }
         }

+ 11 - 0
Registry/level_template.setreg

@@ -0,0 +1,11 @@
+{
+  "O3DE": {
+    "Preferences": {
+      "Prefab": {
+        "CustomTemplatePaths": {
+          "EngineTemplatePathKey1": "@engroot@/Assets/Editor/Prefabs"
+        }
+      }
+    }
+  }
+}