1- import os from "os" ;
21import fs from "fs-extra" ;
32import path from "path" ;
43import { ProjectInfo , TestMode , UnityBuildTarget , UnityEditorInfo } from "./types/unity.js" ;
54import { CommandOptions , CommandResult , executeCommand } from "./utils/commandExecutor.js" ;
65import { redactSensitiveArgs } from "./utils/security.js" ;
6+ import { UnityConfig , UnityEditorPaths } from "./configs/unityConfig.ts" ;
77
88/**
99 * UnityEditor class provides a comprehensive interface for interacting with the Unity game engine editor
@@ -14,30 +14,10 @@ import { redactSensitiveArgs } from "./utils/security.js";
1414 */
1515class UnityEditor {
1616 /**
17- * Configuration paths for Unity Editor executables across different operating systems.
18- * The structure provides base installation directories and relative paths to the
19- * executable for each supported platform (Windows, macOS, Linux).
20- *
21- * @private
22- * @static
23- * @type {Object<string, {base: string, executable: string}> }
24- *
17+ * Platform-specific configuration for Unity Editor paths.
2518 * @internal
2619 */
27- private static UNITY_PATHS = {
28- win32 : {
29- base : "C:/Program Files/Unity/Hub/Editor" ,
30- executable : "Editor/Unity.exe" ,
31- } ,
32- darwin : {
33- base : "/Applications/Unity/Hub/Editor" ,
34- executable : "Unity.app/Contents/MacOS/Unity" ,
35- } ,
36- linux : {
37- base : "/opt/unity/editor" ,
38- executable : "Editor/Unity" ,
39- } ,
40- } ;
20+ private static unityConfig : UnityEditorPaths = UnityConfig . getPlatformConfig ( ) . editor ;
4121
4222 /**
4323 * Resolves the platform-specific path to the Unity executable for a given version.
@@ -54,10 +34,23 @@ class UnityEditor {
5434 * const unityPath = UnityEditor.getUnityExecutablePath("2022.3.15f1");
5535 */
5636 public static getUnityExecutablePath ( version : string ) : string {
57- const platform = os . platform ( ) as keyof typeof UnityEditor . UNITY_PATHS ;
58- const unityConfig = UnityEditor . UNITY_PATHS [ platform ] ;
37+ const unityPath = path . join ( this . unityConfig . base , version , this . unityConfig . executable ) ;
38+ return unityPath ;
39+ }
5940
60- const unityPath = path . join ( unityConfig . base , version , unityConfig . executable ) ;
41+ /**
42+ * Resolves the platform-specific path to the Unity templates directory for a given version.
43+ * This function detects the current operating system and combines the appropriate
44+ * base path with the version-specific subdirectory and templates location.
45+ *
46+ * @public
47+ * @static
48+ * @param {string } version - Unity editor version in the format "YYYY.N.XfN" (e.g., "2023.3.0f1")
49+ * @returns {string } Absolute path to the Unity templates directory for the specified version
50+ * @throws {Error } If the current platform is not supported (not win32, darwin, or linux)
51+ */
52+ public static getUnityTemplatesPath ( version : string ) : string {
53+ const unityPath = path . join ( this . unityConfig . base , version , this . unityConfig . projectTemplates ) ;
6154 return unityPath ;
6255 }
6356
@@ -518,8 +511,9 @@ class UnityEditor {
518511 * @param {ProjectInfo } projectInfo - Information about the project to create, including:
519512 * - path: Where to create the project
520513 * - editorVersion: Which Unity version to use
521- * @param {boolean } [waitForExit=true ] - Whether to wait for Unity to exit after creating the project
514+ * @param {boolean } [quit=false ] - Whether to wait for Unity to exit after creating the project
522515 * Set to false to keep Unity open after project creation
516+ * @param {boolean } [useHub=true] - Whether to use Unity Hub for creating the project
523517 * @returns {Promise<boolean> } - Promise resolving to true if project creation was successful, false otherwise
524518 * @example
525519 * // Create a new project using Unity 2022.3.15f1
@@ -536,18 +530,21 @@ class UnityEditor {
536530 * console.error("Project creation failed");
537531 * }
538532 */
539- public static async createProject ( projectInfo : ProjectInfo , waitForExit : boolean = true ) : Promise < boolean > {
533+ public static async createProject (
534+ projectInfo : ProjectInfo ,
535+ quit : boolean = false ,
536+ useHub : boolean = true
537+ ) : Promise < boolean > {
540538 try {
541539 console . debug ( `Creating new project at ${ projectInfo . projectPath } ` ) ;
542540
543541 const parentDir = path . dirname ( projectInfo . projectPath ) ;
544542 await fs . ensureDir ( parentDir ) ;
545543
546544 const args = [ "-createProject" , projectInfo . projectPath ] ;
545+ if ( useHub ) args . push ( "-useHub" , "-hubIPC" ) ;
547546
548- if ( waitForExit ) {
549- args . push ( "-quit" ) ;
550- }
547+ if ( quit ) args . push ( "-quit" ) ;
551548
552549 const editorInfo = { version : projectInfo . editorVersion } ;
553550 const { stdout, stderr } = await this . execUnityEditorCommand ( editorInfo , args , {
@@ -570,6 +567,75 @@ class UnityEditor {
570567 }
571568 }
572569
570+ /**
571+ * Creates a new Unity project from a specified template.
572+ * This function initializes a Unity project using an existing template,
573+ * allowing for rapid project setup with predefined assets and settings.
574+ *
575+ * @public
576+ * @static
577+ * @param {ProjectInfo } projectInfo - Information about the project to create, including:
578+ * - path: Where to create the project
579+ * - editorVersion: Which Unity version to use
580+ * @param {string } templatePath - The path to the template to use for the project, you can get templates path with unityTemplates.ts
581+ * @param {boolean } [quit=false] - Whether to wait for Unity to exit after creating the project
582+ * Set to false to keep Unity open after project creation
583+ * @param {boolean } [useHub=true] - Whether to use Unity Hub for creating the project
584+ * @returns {Promise<boolean> } - Promise resolving to true if project creation was successful, false otherwise
585+ * @example
586+ *
587+ * const success = await UnityEditor.createProjectFromTemplate(
588+ * {
589+ * path: "/path/to/new/MyAwesomeGame",
590+ * editorVersion: "2022.3.15f1"
591+ * },
592+ * "/path/to/template"
593+ * );
594+ *
595+ * if (success) {
596+ * console.log("Project created from template successfully");
597+ * } else {
598+ * console.error("Project creation from template failed");
599+ * }
600+ */
601+ public static async createProjectFromTemplate (
602+ projectInfo : ProjectInfo ,
603+ templatePath : string ,
604+ quit : boolean = false ,
605+ useHub : boolean = true
606+ ) : Promise < boolean > {
607+ try {
608+ console . debug ( `Creating new project from template at ${ projectInfo . projectPath } ` ) ;
609+
610+ const parentDir = path . dirname ( projectInfo . projectPath ) ;
611+ await fs . ensureDir ( parentDir ) ;
612+
613+ const args = [ "-createProject" , projectInfo . projectPath , "-cloneFromTemplate" , templatePath ] ;
614+
615+ if ( quit ) args . push ( "-quit" ) ;
616+ if ( useHub ) args . push ( "-useHub" , "-hubIPC" ) ;
617+
618+ const editorInfo = { version : projectInfo . editorVersion } ;
619+ const { stdout, stderr } = await this . execUnityEditorCommand ( editorInfo , args , {
620+ reject : false ,
621+ } ) ;
622+
623+ const creationSuccessful =
624+ ! stdout . includes ( "Failed to create project" ) && ! stderr . includes ( "Failed to create project" ) ;
625+
626+ if ( creationSuccessful ) {
627+ console . debug ( `Successfully created project from template at ${ projectInfo . projectPath } ` ) ;
628+ return true ;
629+ } else {
630+ console . error ( `Failed to create project from template: ${ stderr || stdout } ` ) ;
631+ return false ;
632+ }
633+ } catch ( error ) {
634+ console . error ( "Error creating project from template:" , error ) ;
635+ return false ;
636+ }
637+ }
638+
573639 /**
574640 * Opens an existing Unity project with the specified editor version.
575641 * This function can launch Unity with various options, either in batch mode
@@ -610,17 +676,9 @@ class UnityEditor {
610676
611677 const args = [ "-projectPath" , projectInfo . projectPath ] ;
612678
613- if ( waitForExit ) {
614- args . push ( "-quit" ) ;
615- }
616-
617- if ( batchmode ) {
618- args . push ( "-batchmode" ) ;
619- }
620-
621- if ( useHub ) {
622- args . push ( ...[ "-useHub" , "-hubIPC" ] ) ;
623- }
679+ if ( waitForExit ) args . push ( "-quit" ) ;
680+ if ( batchmode ) args . push ( "-batchmode" ) ;
681+ if ( useHub ) args . push ( ...[ "-useHub" , "-hubIPC" ] ) ;
624682
625683 const editorInfo = { version : projectInfo . editorVersion } ;
626684 const options = { reject : false } ;
0 commit comments