unity-game-engineruntimepngalpha-transparencyvertices

Generate mesh from one-color texture


I make a code to be able to draw and generate a sprite of this drawing. So I get a sprite with white background and my drawing (which is in a different color).

My question : How could I remove the white background at runtime ?(with C# code)

My problem is : I want to generated mesh using the drawing, but with white background I have 4 vertices (the fourth corners of the sprite) and I want to get all the vertices from the real shape I draw on my sprite (so much more than 4 vertices)

My current idea is to convert the drawing into having a transparent background and then use unity's sprite packer to generate a mesh from that.

My project: It’s a game, where we can create his own game circuit : user draw a black and white sprite —> I convert it to a mesh with collider and generated the new game circuit.

I already thin to clean all white pixels, but I don't think I will get many vertices with that technic.

Thanks for help, Axel the real shape


Solution

  • using System.IO;
    using UnityEngine.UI;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEditor;
    using UnityEngine.Networking;
    public class scri : MonoBehaviour
    {
        // For saving the mesh------------------------ 
        public KeyCode saveKey = KeyCode.F12;
        public string saveName = "SavedMesh";
    
        // Concerning mesher--------------------------
        public GameObject mesher; //require
    
        public List<Vector3> vertices;
        public  List<int> triangles;
    
        public Vector3 point0;
        public Vector3 point1;
        public Vector3 point2;
        public Vector3 point3;
        
        public int loop;
        public float size;
    
        public Mesh meshFilterMesh;
        public Mesh meshColliderMesh;
    
        // Sprite work
        public Color[] pixels;
    
        public Texture2D newTexture;  
        public Texture2D oldTexture;  //require
    
        private Sprite mySprite;
        private SpriteRenderer spriteRenderer;
    
        public int pathCount;
    
        public GameObject displayerComponent; //require
    
        public PolygonCollider2D polygonColliderAdded; //require
    
        void Start()
        {
            // Mesher
            vertices = new List<Vector3> (); 
            triangles = new List<int> (); 
            meshFilterMesh= mesher.GetComponent<MeshFilter>().mesh;
            meshColliderMesh= mesher.GetComponent<MeshCollider>().sharedMesh;
            size = 10; // lenght of the mesh in Z direction
            loop=0;
    
            // Sprite
            pixels = oldTexture.GetPixels();
            newTexture =new Texture2D(oldTexture.width,oldTexture.height,TextureFormat.ARGB32, false);
            spriteRenderer = gameObject.AddComponent<SpriteRenderer>();
            
            ConvertSpriteAndCreateCollider (pixels);
            BrowseColliderToCreateMesh (polygonColliderAdded);
            
        }
    
        void Update()
        {
            // Save if F12 press
            if (Input.GetKeyDown(saveKey)){SaveAsset();}
        }
    
        public void ConvertSpriteAndCreateCollider (Color[] pixels) {
            for (int i = 0 ; i < pixels.Length ; i++ ) 
            { 
                // delete all black pixel (black is the circuit, white is the walls)
                if ((pixels[i].r==0 && pixels[i].g==0 && pixels[i].b==0 && pixels[i].a==1)) {
                    pixels[i] = Color.clear;
                }
            }
            // Set a new texture with this pixel list
            newTexture.SetPixels(pixels);
            newTexture.Apply();
    
            // Create a sprite from this texture
            mySprite = Sprite.Create(newTexture, new Rect(0, 0, newTexture.width, newTexture.height), new Vector2(10.0f,10.0f), 10.0f, 0, SpriteMeshType.Tight,new Vector4(0,0,0,0),false);
    
            // Add it to our displayerComponent
            displayerComponent.GetComponent<SpriteRenderer>().sprite=mySprite;
    
            // Add the polygon collider to our displayer Component and get his path count
            polygonColliderAdded = displayerComponent.AddComponent<PolygonCollider2D>();
    
        }
    
        // Method to browse the collider and launch makemesh
        public void BrowseColliderToCreateMesh (PolygonCollider2D polygonColliderAdded){
            //browse all path from collider
            pathCount=polygonColliderAdded.pathCount;
            for (int i = 0; i < pathCount; i++)
            {
                Vector2[] path = polygonColliderAdded.GetPath(i);
    
                // browse all path point
                for (int j = 1; j < path.Length; j++)
                {
                    if (j != (path.Length - 1)) // if we aren't at the last point
                    {
                    point0 = new Vector3(path[j-1].x ,path[j-1].y ,0);
                    point1 = new Vector3(path[j-1].x ,path[j-1].y ,size);
                    point2 = new Vector3(path[j].x ,path[j].y ,size);
                    point3 = new Vector3(path[j].x ,path[j].y ,0);
                        MakeMesh(point0,point1,point2,point3);
    
                    } 
                    else if(j == (path.Length - 1))// if we are at the last point, we need to close the loop with the first point
                    {
                    point0 = new Vector3(path[j-1].x ,path[j-1].y ,0);
                    point1 = new Vector3(path[j-1].x ,path[j-1].y ,size);
                    point2 = new Vector3(path[j].x ,path[j].y ,size);
                    point3 = new Vector3(path[j].x ,path[j].y ,0);
                        MakeMesh(point0,point1,point2,point3);
                    point0 = new Vector3(path[j].x ,path[j].y ,0);
                    point1 = new Vector3(path[j].x ,path[j].y ,size);
                    point2 = new Vector3(path[0].x ,path[0].y ,size); // First point
                    point3 = new Vector3(path[0].x ,path[0].y ,0); // First point
                        MakeMesh(point0,point1,point2,point3);
                    }
                }
            }
        }
    
    
        //Method to generate 2 triangles mesh from the 4 points 0 1 2 3 and add it to the collider
        public void MakeMesh (Vector3 point0,Vector3 point1,Vector3 point2, Vector3 point3){
            
            // Vertice add
            vertices.Add(point0);
            vertices.Add(point1);
            vertices.Add(point2);
            vertices.Add(point3);
    
            //Triangle order
            triangles.Add(0+loop*4);
            triangles.Add(2+loop*4);
            triangles.Add(1+loop*4);
            triangles.Add(0+loop*4);
            triangles.Add(3+loop*4);
            triangles.Add(2+loop*4);
            loop = loop + 1; 
    
            // create mesh 
            meshFilterMesh.vertices=vertices.ToArray();
            meshFilterMesh.triangles=triangles.ToArray();
    
            // add this mesh to the MeshCollider
            mesher.GetComponent<MeshCollider>().sharedMesh=meshFilterMesh;
        }
    
        // Save if F12 press
        public void SaveAsset() 
        {
            var mf = mesher.GetComponent<MeshFilter>();
            if (mf)
            {
                var savePath = "Assets/" + saveName + ".asset";
                Debug.Log("Saved Mesh to:" + savePath);
                AssetDatabase.CreateAsset(mf.mesh, savePath);
            }
        }
    }
    

    enter image description here