Exemplo n.º 1
0
    /// <summary>
    /// Builds the mod. Assumes that the mod def state is valid (name and all that).
    /// </summary>
    public void Build(bool zip)
    {
        var watch = new System.Diagnostics.Stopwatch();

        watch.Start();

        Debug.Log($"Building mod {Name} ({ID})...");

        // Step 0: Clear the output.
        string modDir    = Path.Combine(new DirectoryInfo(Application.dataPath).Parent.FullName, "Mod Builds");
        string outputDir = Path.Combine(modDir, ID);

        if (zip)
        {
            if (File.Exists(Path.Combine(modDir, ID + ".zip")))
            {
                File.Delete(Path.Combine(modDir, ID + ".zip"));
            }
        }
        if (Directory.Exists(outputDir))
        {
            Debug.Log("Clearing output dir.");
            Directory.Delete(outputDir, true);
        }

        // Step 1: Assign all assets in the Content folder to the asset bundle.
        // TODO get all assets in subfolders too.
        string[] guids = UnityEditor.AssetDatabase.FindAssets("", new string[] { "Assets/Mods/" + ID + "/Content" });

        // TODO aparently scenes and assets can't be in the same bundle, so create more than one bundle per mod.
        int count = 0;

        foreach (var guid in guids)
        {
            string path = UnityEditor.AssetDatabase.GUIDToAssetPath(guid);
            UnityEditor.AssetImporter.GetAtPath(path).assetBundleName = ID;
            count++;
        }
        Debug.Log($"Assigned {count} assets to the bundle.");

        // Step 2: Create mod info.
        ModInfo info = new ModInfo
        {
            ID          = ID,
            Name        = Name,
            Author      = Author,
            Version     = Version,
            Description = Description,
            HasBundle   = count != 0,
            Assemblies  = new string[] { ID + ".dll" } // TODO allow more that one assembly to exist. Such as packaging Json.NET.
        };

        // Step 3: Write info file to the output directory.
        string infoPath       = Path.Combine(outputDir, "Info.txt");
        string tempBundle     = Path.Combine(outputDir, "TempBundleDir");
        string assembliesPath = Path.Combine(outputDir, "Assemblies");

        string json = JsonUtility.ToJson(info, true);

        GameIO.EnsureParentDir(infoPath);
        File.WriteAllText(infoPath, json);
        Debug.Log("Written mod info.");

        // Step 4: Write asset bundle. Can take ages.
        BuildBundleTo(tempBundle);
        File.Copy(Path.Combine(tempBundle, ID), Path.Combine(outputDir, "Bundle"));
        File.Copy(Path.Combine(tempBundle, ID + ".manifest"), Path.Combine(outputDir, "Bundle.manifest"));
        Directory.Delete(tempBundle, true);
        Debug.Log("Built asset bundle.");

        // Step 5: Write assemblies. They just need to be copied, they are automatically compiled by unity.
        if (!Directory.Exists(assembliesPath))
        {
            Directory.CreateDirectory(assembliesPath);
        }

        // TODO allow custom assemblies.
        CopyAssembliesTo(assembliesPath, new string[] { ID });
        Debug.Log("Copied assemblies to output.");

        if (zip)
        {
            Debug.Log("Zipping...");
            System.IO.Compression.ZipFile.CreateFromDirectory(outputDir, Path.Combine(modDir, ID + ".zip"));
            Debug.Log("Deleting uncompressed directory...");
            Directory.Delete(outputDir, true);
        }

        watch.Stop();
        Debug.Log($"Finished build in {watch.Elapsed.TotalMilliseconds:n1} ms.");
        Debug.Log($"Path: {outputDir}");
    }