4
\$\begingroup\$

So I have modified a texture in C# by removing all of its white pixels, now I want to render it on the screen in unity so that later I can use it as a terrain where I can make my sprite walk. So far, I have tried using Graphics.DrawTexture, GUI.DrawTexture, I have tried setting it equal to the main texture of a sprite, but so far, I have not been able to display it on the screen. Is there a way to do this? Basically, I want to use the following code (Processing based on Java) but in C# in Unity.

// Provides methods for determining solid/empty pixels, and for removing/adding solid pixels 
class Terrain {
  PImage img; // the terrain image

  int destructionRes; // how wide is a static pixel

  // Constructor
  Terrain(PImage pic, int destructionRes) {
    this.destructionRes = destructionRes;

    // Copy pic over to img, replacing all pink (RGB: 255,0,255) pixels with transparent pixels
    img = createImage(pic.width, pic.height, ARGB);
    img.loadPixels();
    pic.loadPixels();
    for (int i = 0; i < img.width * img.height; i++) {
      if (red(pic.pixels[i]) == 255 && green(pic.pixels[i]) == 0 && blue(pic.pixels[i]) == 255) 
        img.pixels[i] = color(0,0);
      else
        img.pixels[i] = pic.pixels[i];
    }
    img.updatePixels();
  } 

  // Render terrain onto the main screen
  void draw(float x, float y) {
    image(img, x,y);  
  }

  // Return the terrain's width and height
  public int width() {
    return img.width;  
  }
  public int height() {
    return img.height; 
  }

  // Update - apply pixels[]'s changes onto the image
  void update() {
    img.updatePixels(); 
  }

  // Determine if a pixel is solid based on whether or not it's transparent
  boolean isPixelSolid(int x, int y) {
    if (x > 0 && x < img.width && y > 0 && y < img.height)
      return img.pixels[x + y * img.width] != color(0,0);
    return false; // border is not solid
  }

  // Color in a pixel, making it solid
  void addPixel(color c, int x, int y) {
    if (x > 0 && x < img.width && y > 0 && y < img.height)
      img.pixels[x + y * img.width] = c;
  }
  // Make a pixel solid
  void removePixel(int x, int y) {
    if (x > 0 && x < img.width && y > 0 && y < img.height)
      img.pixels[x + y * img.width] = color(0,0);
  }
  // Get a pixel's color
  color getColor(int x, int y) {
    if (x > 0 && x < img.width && y > 0 && y < img.height)
      return img.pixels[x + y * img.width];
    return 0;
  }

  // Find a normal at a position
  float[] getNormal(int x, int y) {
    // First find all nearby solid pixels, and create a vector to the average solid pixel from (x,y)
    float avgX = 0;
    float avgY = 0;
    for (int w = -3; w <= 3; w++) {
      for (int h = -3; h <= 3; h++) {
        if (isPixelSolid(x + w, y + h)) {
          avgX -= w;
          avgY -= h;
        }
      }
    }
    float len = sqrt(avgX * avgX + avgY * avgY); // get the distance from (x,y)
    return new float[]{avgX/len, avgY/len}; // normalize the vector by dividing by that distance
  }
}

Basically I want to implement that code (in Processing) in C# in Unity. I want to code it so that Unity does the same thing. I only need help with displaying the Texture2D on the scene, but if the whole code I am trying to apply helps, then I am posting it here. Also, this is what I have done so far:

using UnityEngine;
using System.Collections;

public class ImageBring : MonoBehaviour
{
    public Texture2D Layout;
    void Start()
    {
        Texture2D Ground = new Texture2D(Layout.width,Layout.height);
        for (int x = 0; x < Layout.width; x++)
        {
            for (int y = 0; y < Layout.height; y ++)
            {
                if (Layout.GetPixel(x, y) == Color.white)
                {
                    Color color = new Color();
                    color.a = 0f;
                    Ground.SetPixel(x, y, color);

                }
                else
                {
                    Ground.SetPixel(x, y, Layout.GetPixel(x, y));
                }
            }
        }
        Ground.Apply();

    }
}
\$\endgroup\$
  • \$\begingroup\$ Little bit more details in terms of code and requirements would be appreciated. \$\endgroup\$ – Hamza Hasan Feb 10 '16 at 16:08
  • \$\begingroup\$ @HamzaHasan I have added all of the details that I can :). \$\endgroup\$ – Guacho Perez Feb 10 '16 at 16:17
  • \$\begingroup\$ I said LITTLE BIT :P, well good enough \$\endgroup\$ – Hamza Hasan Feb 10 '16 at 16:21
1
\$\begingroup\$

Well, you are on the right track. You can do this with keep in minds something. You must have a texture with read/write permission. You can do it easily by selecting it and change its Texture Type to Advance.

enter image description here

Don't forget to mark check on Read/Write Enabled

Second thing is you must have a Material in your script on which you'd modify its texture so the models having that material attached will get effected.

Note that material must have a shader that supports Transparency. For example you can set Unlit/Transparent.

Now you can execute your code and apply the modified texture in that material.

Here is the code,

using UnityEngine;
using System.Collections;

public class ModifyTexture : MonoBehaviour
{
    public Texture2D _layout; // Your current texture
    public Material _mat; // Material attached to your Gameobject (Terrain, quad or anything else)

    void Start ()
    {
        // Your operation
        Texture2D ground = new Texture2D (_layout.width, _layout.height);
        for (int x = 0; x < _layout.width; x++) {
            for (int y = 0; y < _layout.height; y++) {
                if (_layout.GetPixel (x, y) == Color.white) {
                    Color color = new Color ();
                    color.a = 0f;
                    ground.SetPixel (x, y, color);

                } else {
                    ground.SetPixel (x, y, _layout.GetPixel (x, y));
                }
            }
        }
        ground.Apply ();

        // Applying modified texture to the material
        _mat.mainTexture = ground;
    }

    // Update is called once per frame
    void Update ()
    {

    }
}

Hope this helps.

\$\endgroup\$
  • 2
    \$\begingroup\$ Your naming is all over the place Hamza! ;) \$\endgroup\$ – Savlon Feb 10 '16 at 21:43
  • \$\begingroup\$ @Savlon Actually I didn't touch his code and added my code in my style :D \$\endgroup\$ – Hamza Hasan Feb 11 '16 at 5:50
  • 1
    \$\begingroup\$ Well, you are right, I'll edit it when I get on my pc \$\endgroup\$ – Hamza Hasan Feb 11 '16 at 5:52
  • \$\begingroup\$ haha I know... You've usually got a clear style but this one is just random! :D \$\endgroup\$ – Savlon Feb 11 '16 at 5:54
  • 1
    \$\begingroup\$ @Savlon :D... Thanks for pointing it out. Now it is ok :) \$\endgroup\$ – Hamza Hasan Feb 11 '16 at 6:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.