Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity 2D: dynamically create a hole in a image

Tags:

unity3d

2d

I am using Unity 2D and I am trying to achieve this simple effect. I am making a Candy Crush Saga - like game.

I have a grid with all the items. In every level the grid field can have different shapes, created at runtime (a dark grey area in the middle of the background). The background is a still image (blue sky and green hills). When the pieces (for example a blue pentagon) fall down from the top they must be hidden until they enter the grid field area (dark grey); so in practice the background image (sky and hills) is no more a background, but is a foreground with a hole that is represented by the grey area. The grey field is composed as well by tiles from a sprite sheet.

I have prepared a picture, but I cannot load it here unfortunately yet.

I have no idea about how to achieve this effect in Unity. Do You have any idea?

The most simple solution would be to create all the static levels graphics already with the hole, but I do not want to create them because it is a waste of time and also a waste of memory, I want to be able to create this effect at runtime.

I was thinking about creating a dynamic bitmap mask for the hole shape using a sprite sheet. Then using this bitmap mask as a material for example to be applied to the image in the foreground and make a hole.

I hope it is clear enough.

Thank you! Camillo

like image 428
camillo777 Avatar asked Sep 27 '22 14:09

camillo777


1 Answers

click on your texture in the unity editor

change "texture type" from "texture" to "advanced"

check the "read/write enabled" checkbox

change "format" form "automatic compressed" to "RGBA 32 bit"

i attached this component to a raw image (you can attach it to something else, just change the "RawImage image" part)

this will create a hole with dimensions 100x100 at position 10,10 of the image, so make sure that your texture is at least 110x110 large.

using UnityEngine;
using UnityEngine.UI;

public class HoleInImage : MonoBehaviour
{
   public RawImage image;

   void Start()
   {
      // this will change the original:
      Texture2D texture = image.texture as Texture2D;

      // use this to change a copy (and not the original)
      //Texture2D texture = Instantiate(image.mainTexture) as Texture2D;
      //image.mainTexture = texture;

      Color[] colors = new Color[100*100];

      for( int i = 0; i < 100*100; ++i )
         colors[i] = Color.clear;

      texture.SetPixels( 10, 10, 100, 100, colors );

      texture.Apply(false);
   }
}

EDIT:

hole defined by one or more sprites:

do the same for these sprites: (advanced, read/write enabled, RGBA 32 bit)

for example: if sprite is white and the hole is defined with black:

      for( int i = 0; i < 100*100; ++i )
         colors[i] = Color.clear;

change to:

      Texture2D holeTex; // set this in editor, it must have same dimensions (100x100 in my example)
      Color[] hole = holeTex.GetPixels();
      for( int i = 0; i < 100*100; ++i )
      {
         if( hole[i] == Color.black ) // where sprite is black, there will be a hole
             colors[i] = Color.clear;
      }
like image 110
Jinjinov Avatar answered Oct 06 '22 01:10

Jinjinov