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\$
3
  • \$\begingroup\$ Little bit more details in terms of code and requirements would be appreciated. \$\endgroup\$ Feb 10, 2016 at 16:08
  • \$\begingroup\$ @HamzaHasan I have added all of the details that I can :). \$\endgroup\$
    – GuPe
    Feb 10, 2016 at 16:17
  • \$\begingroup\$ I said LITTLE BIT :P, well good enough \$\endgroup\$ Feb 10, 2016 at 16:21

1 Answer 1

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\$
5
  • 2
    \$\begingroup\$ Your naming is all over the place Hamza! ;) \$\endgroup\$
    – Savlon
    Feb 10, 2016 at 21:43
  • \$\begingroup\$ @Savlon Actually I didn't touch his code and added my code in my style :D \$\endgroup\$ Feb 11, 2016 at 5:50
  • 1
    \$\begingroup\$ Well, you are right, I'll edit it when I get on my pc \$\endgroup\$ Feb 11, 2016 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, 2016 at 5:54
  • 1
    \$\begingroup\$ @Savlon :D... Thanks for pointing it out. Now it is ok :) \$\endgroup\$ Feb 11, 2016 at 6:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .