Example #1
0
        /// <summary>
        /// Prints relevant info about this node to the console including:
        /// <br/>
        ///
        /// </summary>
        /// <param name="node"></param>
        public static void PrintInfo(this UnityDisplayNode node)
        {
            var start = $"-------------Information about UnityDisplayNode {node.name}-------------";

            MelonLogger.Msg(start);

            MelonLogger.Msg("Generic Renderers:");
            for (var i = 0; i < node.genericRenderers.Count; i++)
            {
                var renderer = node.genericRenderers[i];
                MelonLogger.Msg($"   {i}. {renderer.name} ({renderer.GetIl2CppType().Name})");
            }

            MelonLogger.Msg("");

            MelonLogger.Msg("Generic Render Layers:");
            for (var i = 0; i < node.genericRendererLayers.Count; i++)
            {
                var layer = node.genericRendererLayers[i];
                MelonLogger.Msg($"   {i}. {layer}");
            }

            MelonLogger.Msg("");

            MelonLogger.Msg("Component Hierarchy:");
            node.gameObject.RecursivelyLog();

            MelonLogger.Msg(new string('-', start.Length));
        }
        private static void SetupUDN(UnityDisplayNode udn, ModDisplay modDisplay, Action <UnityDisplayNode> onComplete)
        {
            udn.name = modDisplay.Id + "(Clone)";
            udn.RecalculateGenericRenderers();
            try
            {
                modDisplay.ModifyDisplayNode(udn);
            }
            catch (Exception e)
            {
                MelonLogger.Error($"Failed to modify DisplayNode for {modDisplay.Name}");
                MelonLogger.Error(e);
            }

            try
            {
                if (modDisplay.Scale < 1f || modDisplay.Scale > 1f)
                {
                    udn.transform.GetChild(0).transform.localScale = new Vector3(modDisplay.Scale,
                                                                                 modDisplay.Scale, modDisplay.Scale);
                }
            }
            catch (Exception e)
            {
                MelonLogger.Error($"Failed to change scale for {modDisplay.Name}");
                MelonLogger.Error(e);
            }

            udn.RecalculateGenericRenderers();

            onComplete.Invoke(udn);

            ResourceHandler.Prefabs[modDisplay.Id] = udn;
        }
Example #3
0
        /// <summary>
        /// Gets all generic renderers of the specified type, recalculating the renderers if need be
        /// </summary>
        /// <param name="node">The UnityDisplayNode</param>
        /// <param name="recalculate">Whether to recalculate renderers</param>
        /// <typeparam name="T">The type of Renderer you're looking for</typeparam>
        /// <returns></returns>
        public static List <T> GetRenderers <T>(this UnityDisplayNode node, bool recalculate = true) where T : Renderer
        {
            if (node.genericRenderers == null)
            {
                return(new List <T>());
            }

            if (recalculate && node.genericRenderers[0] == null)
            {
                node.RecalculateGenericRenderers();
            }

            return(node.genericRenderers.GetItemsOfType <Renderer, T>().ToList());
        }
Example #4
0
        /// <summary>
        /// Gets all renderers that are of type SkinnedMeshRenderer or MeshRenderer
        /// </summary>
        /// <param name="node"></param>
        /// <param name="recalculate"></param>
        /// <returns></returns>
        public static List <Renderer> GetMeshRenderers(this UnityDisplayNode node, bool recalculate = true)
        {
            if (node.genericRenderers == null)
            {
                return(new List <Renderer>());
            }

            if (recalculate && node.genericRenderers[0] == null)
            {
                node.RecalculateGenericRenderers();
            }

            return(node.genericRenderers.Where(nodeGenericRenderer =>
                                               nodeGenericRenderer.IsType <SkinnedMeshRenderer>() || nodeGenericRenderer.IsType <MeshRenderer>())
                   .ToList());
        }
Example #5
0
        /// <summary>
        /// Saves the texture used for this node's mesh renderer
        /// <br/>
        /// By default, this saves to local files, aka "C:\Users\...\AppData\LocalLow\Ninja Kiwi\BloonsTD6"
        /// </summary>
        /// <param name="node">The UnityDisplayNode</param>
        /// <param name="index"></param>
        /// <param name="path">Optional path to save to instead</param>
        public static void SaveMeshTexture(this UnityDisplayNode node, int index = 0, string path = null)
        {
            if (path == null)
            {
                path = FileIOUtil.GetSandboxPath() + node.name + index + ".png";
            }

            var meshRenderers = node.GetMeshRenderers();

            if (meshRenderers.Count == 0)
            {
                MelonLogger.Error("Can't save mesh texture because the node doesn't have any MeshRenderers or SkinnedMeshRenderers, you might want to call node.PrintInfo()");
            }
            else if (meshRenderers.Count <= index)
            {
                MelonLogger.Error($"The node doesn't have {index} total mesh renderers, you might want to call node.PrintInfo()");
            }
            else
            {
                meshRenderers[index].material.mainTexture.TrySaveToPNG(path);
            }
        }
Example #6
0
        public static void RemoveBone(this UnityDisplayNode unityDisplayNode, string boneName,
                                      bool alreadyUnbound = false)
        {
            var skinnedMeshRenderer = unityDisplayNode.GetRenderer <SkinnedMeshRenderer>();

            if (!alreadyUnbound)
            {
                // Unbind the mesh so we can change it without affecting the original
                skinnedMeshRenderer.UnbindMesh();
            }

            // Get the bone index that controls the Boomerang
            var boomerang = skinnedMeshRenderer.GetBoneIndex(boneName);

            // Get all vertices that the bone controls
            var badVertices = skinnedMeshRenderer.GetVerticesConnectedToBoneArray(boomerang);

            // Remove all triangles that contain any of those vertices
            var triangles = skinnedMeshRenderer.GetTrianglesAsArrays();

            triangles.RemoveAll(triangle => triangle.Any(v => badVertices[v]));
            skinnedMeshRenderer.SetTriangles(triangles);
        }
Example #7
0
 /// <summary>
 /// Gets the first generic renderer of the specified type, recalculating the renderers if need be
 /// </summary>
 /// <param name="node">The UnityDisplayNode</param>
 /// <param name="recalculate">Whether to recalculate renderers</param>
 /// <typeparam name="T">The type of Renderer you're looking for</typeparam>
 public static T GetRenderer <T>(this UnityDisplayNode node, bool recalculate = true) where T : Renderer
 {
     return(node.GetRenderers <T>(recalculate)
            .OrderBy(renderer => renderer.name.StartsWith("FlatSkin") ? 0 : 1)
            .FirstOrDefault());
 }
Example #8
0
 public static Transform GetBone(this UnityDisplayNode unityDisplayNode, string boneName)
 {
     return(unityDisplayNode.gameObject.GetComponentInChildrenByName <Transform>(boneName));
 }
Example #9
0
 /// <summary>
 /// Alters the UnityDisplayNode that was copied from the one used by <see cref="ModDisplay.BaseDisplay"/>
 /// <br/>
 /// By default, this will change the main texture of the first SkinnedMeshRenderer of the node to that of a
 /// png with the same name as the class
 /// </summary>
 /// <param name="node">The UnityDisplayNode</param>
 public override void ModifyDisplayNode(UnityDisplayNode node)
 {
     SetMeshTexture(node, Name);
 }
Example #10
0
        public static void Process(string towername, UnityDisplayNode node)
        {
            var parent = node.transform;

            //make sure it only runs once
            if (parent.FindChild("processed") == null)
            {
                var proc = new GameObject("processed");
                proc.transform.parent = parent;
                var towerlocation = towername + ".png";
                var orig          = filePath + "original/" + towerlocation;
                var custom        = filePath + "custom/" + towerlocation;
                //Console.WriteLine("processing: " + towername);

                //create orig
                try
                {
                    bool fileExists = true;
                    if (!origFiles.TryGetValue(orig, out fileExists))
                    {
                        origFiles.Add(orig, File.Exists(orig));
                        origFiles.TryGetValue(orig, out fileExists);
                    }

                    if (!fileExists)
                    {
                        //string counter = "";
                        foreach (Renderer renderer in node.genericRenderers)
                        {
                            try
                            {
                                var texture = renderer.material.mainTexture;

                                File.WriteAllBytes(filePath + "original/" + towerlocation, ImageConversion.EncodeToPNG(makeReadable(texture)));
                                break;
                            }
                            catch
                            {
                            }
                            //counter += "_";
                            //renderer.material.mainTexture = FlipTexture(makeReadable(texture));
                        }
                        //Console.WriteLine("dumped texture for: " + towername);
                    }
                }
                catch (Exception e)
                {
                    //Console.WriteLine("could not create orig: " + e.Message);
                }

                //read custom
                try
                {
                    bool fileExists = true;
                    if (!customFiles.TryGetValue(custom, out fileExists))
                    {
                        customFiles.Add(custom, File.Exists(custom));
                        customFiles.TryGetValue(custom, out fileExists);
                    }


                    //Console.WriteLine("file for " + towername + "exists: " + fileExists);
                    if (fileExists)
                    {
                        Texture2D tex;
                        if (!customTexture.TryGetValue(custom, out tex))
                        {
                            tex = new Texture2D(2, 2);
                            //Console.WriteLine("loading custom texture for " + towername);
                            ImageConversion.LoadImage(tex, File.ReadAllBytes(filePath + "custom/" + towerlocation));
                            //Console.WriteLine("adding to dict");
                            customTexture.Add(custom, tex);
                            //Console.WriteLine("found custom texture for " + towername);
                        }
                        else
                        {
                            //Console.WriteLine("texture was cached");
                        }
                        foreach (Renderer renderer in node.genericRenderers)
                        {
                            //Texture2D tex = new Texture2D(2, 2);
                            //ImageConversion.LoadImage(tex, File.ReadAllBytes(filePath + "custom/" + towerlocation));
                            //Console.WriteLine("loaded custom texture for " + towername);

                            renderer.material.mainTexture = tex;
                        }
                    }
                }
                catch (Exception e)
                {
                    //Console.WriteLine("could not read custom texture: " + e.Message);
                }
            }
        }
 /// <summary>
 /// (Cross-Game compatible) Get all 3D models attached to this UnityDisplayNode.
 /// </summary>
 /// <param name="unityDisplayNode"></param>
 /// <returns></returns>
 public static List <Transform> Get3DModels(this UnityDisplayNode unityDisplayNode)
 {
     return(unityDisplayNode.transform.parent.GetComponentsInChildren <Transform>().ToList());
 }
Example #12
0
 /// <summary>
 /// Sets the sprite texture to that of a named png
 /// </summary>
 /// <param name="node">The UnityDisplayNode</param>
 /// <param name="textureName">The name of the texture, without .png</param>
 protected void Set2DTexture(UnityDisplayNode node, string textureName)
 {
     node.GetRenderer <SpriteRenderer>().sprite = GetSprite(textureName, PixelsPerUnit);
 }
Example #13
0
 /// <summary>
 /// Sets the mesh texture to that of a named png
 /// </summary>
 /// <param name="node">The UnityDisplayNode</param>
 /// <param name="textureName">The name of the texture, without .png</param>
 protected void SetMeshTexture(UnityDisplayNode node, string textureName, int index)
 {
     node.GetMeshRenderer(index).SetMainTexture(GetTexture(textureName));
 }
Example #14
0
 /// <summary>
 /// Alters the UnityDisplayNode that was copied from the one used by <see cref="BaseDisplay"/>
 /// </summary>
 /// <param name="node"></param>
 public abstract void ModifyDisplayNode(UnityDisplayNode node);
Example #15
0
 /// <summary>
 /// Gets the first (or an indexed) SkinnedMeshRenderer/MeshRenderer
 /// </summary>
 /// <param name="node"></param>
 /// <param name="index"></param>
 /// <param name="recalculate"></param>
 /// <returns></returns>
 public static Renderer GetMeshRenderer(this UnityDisplayNode node, int index = 0, bool recalculate = true)
 {
     return(node.GetMeshRenderers()[index]);
 }
Example #16
0
 public override void ModifyDisplayNode(UnityDisplayNode node)
 {
     Set2DTexture(node, "boss");
 }
 /// <summary>
 /// Performs alterations to the unity display node when it is created
 /// </summary>
 /// <param name="node"></param>
 public override void ModifyDisplayNode(UnityDisplayNode node)
 {
 }