Search code examples
c#unity-game-engineautomationunity3d-native-plugins

In Unity BuildPostProcessor, how exactly do you, simply, "copy over" one file?


in Unity I simply have a file, afile.ts, sitting in Assets/

enter image description here

In the built Xcode, I simply want it to be sitting in the project folder (really, anywhere is fine) included in the project.

enter image description here

You do this using

    project.AddFileToBuild(g, something something something);

But I plain can not figure it out.

(Obviously it is totally undocumented at Unity.)

How is it done? Just the one simple file - actually copy it from Assets/filename to the Xcode project (and it will have target membership and be in the main bundle).

Here is a perfect Unity build post script BuildPostProcessor.cs, which is amazing and does everything else:

https://stackoverflow.com/a/54370793/294884

but I cannot copy over a damned file! How to?


Note - alternative

Note. If you very simply put a file in Unity's badly-named magic folder:

/StreamingAssets

in fact it does exactly what is under discussion in this QA.

  1. Unity .. have a file music.mp4 or mesh.txt in /StreamingAssets
  2. build to Xcode
  3. you'll have music.mp4 or mesh.txt, in the Xcode project, included in the Target
  4. and the iOS location will be ...

the folder name on iOS for whatever reason becomes: /Data/Raw

Thus your low-level iOS side code would be:

instead of, for example:

CFURLRef imageURL = CFBundleCopyResourceURL(
  mainBundle, CFSTR("music"), CFSTR("mp4"), NULL);

you will have:

CFURLRef imageURL = CFBundleCopyResourceURL(
  mainBundle, CFSTR("Data/Raw/music"), CFSTR("mp4"), NULL);

That works fine. But surely we can learn how to use '.AddFileToBuild` which seems to exist for the purpose.


Solution

  • FTR I did stumble on to some Unity example code (in an unrelated example project) which may help ..

    public class MyBuildPostprocessor
    {
        // Build postprocessor. Currently only needed on:
        // - iOS: no dynamic libraries, so plugin source files have to be copied into Xcode project
        [PostProcessBuild]
        public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
        {
            if (target == BuildTarget.iOS)
                OnPostprocessBuildIOS(pathToBuiltProject);
        }
    
        private static void OnPostprocessBuildIOS(string pathToBuiltProject)
        {
            // We use UnityEditor.iOS.Xcode API which only exists in iOS editor module
            #if UNITY_IOS
    
            string projPath = pathToBuiltProject + "/Unity-iPhone.xcodeproj/project.pbxproj";
    
            UnityEditor.iOS.Xcode.PBXProject proj = new UnityEditor.iOS.Xcode.PBXProject();
            proj.ReadFromString(File.ReadAllText(projPath));
            string target = proj.TargetGuidByName("Unity-iPhone");
    
            Directory.CreateDirectory(Path.Combine(pathToBuiltProject, "Libraries/Unity"));
    
            string[] filesToCopy = new string[]
            {
                "PlatformBase.h",
                "RenderAPI_Metal.mm",
                "RenderAPI_OpenGLCoreES.cpp",
                "RenderAPI.cpp",
                "RenderAPI.h",
                "RenderingPlugin.cpp",
            };
    
            for(int i = 0 ; i < filesToCopy.Length ; ++i)
            {
                var srcPath = Path.Combine("../PluginSource/source", filesToCopy[i]);
                var dstLocalPath = "Libraries/" + filesToCopy[i];
                var dstPath = Path.Combine(pathToBuiltProject, dstLocalPath);
                File.Copy(srcPath, dstPath, true);
                proj.AddFileToBuild(target, proj.AddFile(dstLocalPath, dstLocalPath));
            }
    
            File.WriteAllText(projPath, proj.WriteToString());
            #endif // #if UNITY_IOS
        }
    }