11package backend .tools .tasks ;
22
3+ import haxe .Json ;
34import haxe .io .Path ;
45import sys .FileSystem ;
6+ import sys .io .File ;
7+ import tools .Equal ;
8+ import tools .Files ;
59import tools .Helpers .* ;
610import tools .InstanceManager ;
711
@@ -93,6 +97,10 @@ class UnityBuild extends tools.Task {
9397 cmdArgs .push (' haxe_server= $haxeServerPort ' );
9498 }
9599
100+ // Haxe shaders detection
101+ cmdArgs .push (' --macro' );
102+ cmdArgs .push (' shade.macros.ShadeMacro.initRegister(' + Json .stringify (hxmlProjectPath ) + ' )' );
103+
96104 if (haxeServerPort != - 1 ) {
97105 print (' Run haxe compiler (server on port $haxeServerPort )' );
98106 }
@@ -109,6 +117,76 @@ class UnityBuild extends tools.Task {
109117 }
110118 else {
111119 if (action == ' run' || action == ' build' ) {
120+ // Compile Unity shaders from Haxe shaders
121+ final shadersJsonPath = Path .join ([hxmlProjectPath , ' shade' , ' info.json' ]);
122+ final prevShadersJsonPath = Path .join ([hxmlProjectPath , ' shade' , ' prev-info.json' ]);
123+
124+ if (FileSystem .exists (shadersJsonPath )) {
125+ var shaders : Dynamic = Json .parse (File .getContent (shadersJsonPath ));
126+
127+ // Read previous shade/info.json for comparison
128+ var prevShaders : Dynamic = null ;
129+ if (FileSystem .exists (prevShadersJsonPath )) {
130+ prevShaders = Json .parse (File .getContent (prevShadersJsonPath ));
131+ }
132+
133+ if (shaders != null && shaders .shaders != null ) {
134+ final shaderReferences : Array <{
135+ pack : Array <String >,
136+ name : String ,
137+ filePath : String ,
138+ hash : String
139+ }> = shaders .shaders ;
140+
141+ if (shaderReferences .length > 0 ) {
142+ // Check if shaders changed (skip if identical)
143+ var shouldSkipShaderCompilation = false ;
144+ if (prevShaders != null && Equal .equal (prevShaders , shaders )) {
145+ shouldSkipShaderCompilation = true ;
146+ }
147+
148+ if (! shouldSkipShaderCompilation ) {
149+ // Collect unique shader files (by hash to avoid duplicates)
150+ var uniqueShaders : Map <String , String > = new Map ();
151+ for (ref in shaderReferences ) {
152+ if (! uniqueShaders .exists (ref .hash )) {
153+ uniqueShaders .set (ref .hash , ref .filePath );
154+ }
155+ }
156+
157+ // Build shade task arguments for Unity target
158+ var unityOutputPath = Path .join ([hxmlProjectPath , ' shade' , ' unity' ]);
159+
160+ // Delete existing unity shader folder if any
161+ if (FileSystem .exists (unityOutputPath )) {
162+ Files .deleteRecursive (unityOutputPath );
163+ }
164+
165+ // Build args for shade task
166+ var shadeArgs : Array <String > = [];
167+ for (filePath in uniqueShaders ) {
168+ shadeArgs .push (' --in' );
169+ shadeArgs .push (filePath );
170+ }
171+ shadeArgs .push (' --target' );
172+ shadeArgs .push (' unity' );
173+ shadeArgs .push (' --out' );
174+ shadeArgs .push (unityOutputPath );
175+
176+ // Run shade task
177+ print (' Transpile shaders to Unity ShaderLab' );
178+ runTask (' shade' , shadeArgs );
179+
180+ // Copy shaders to Unity project
181+ copyGeneratedShadersToUnity (cwd , unityOutputPath , project );
182+
183+ // Save current info for next comparison
184+ File .saveContent (prevShadersJsonPath , File .getContent (shadersJsonPath ));
185+ }
186+ }
187+ }
188+ }
189+
112190 runHooks (cwd , args , project .app .hooks , ' end build' );
113191 }
114192 else if (action == ' clean' ) {
@@ -125,4 +203,32 @@ class UnityBuild extends tools.Task {
125203
126204 }
127205
206+ /**
207+ * Copies generated Unity ShaderLab files to the Unity project assets folder.
208+ * @param cwd Current working directory
209+ * @param sourcePath Path to generated shader files
210+ * @param project Ceramic project configuration
211+ */
212+ function copyGeneratedShadersToUnity (cwd : String , sourcePath : String , project : tools. Project ): Void {
213+ if (! FileSystem .exists (sourcePath )) return ;
214+
215+ // Unity shaders go to same assets folder as other ceramic assets
216+ var dstAssetsPath = Path .join ([cwd , ' project' , ' unity' , project .app .name , ' Assets' , ' Ceramic' , ' Resources' , ' assets' ]);
217+
218+ // Ensure assets directory exists
219+ if (! FileSystem .exists (dstAssetsPath )) {
220+ FileSystem .createDirectory (dstAssetsPath );
221+ }
222+
223+ // Copy all .shader files
224+ for (file in FileSystem .readDirectory (sourcePath )) {
225+ if (file .endsWith (' .shader' )) {
226+ File .copy (
227+ Path .join ([sourcePath , file ]),
228+ Path .join ([dstAssetsPath , file ])
229+ );
230+ }
231+ }
232+ }
233+
128234}
0 commit comments