Animated Tile brushes and grouping

fregas
New Member
Registered: 2017-05-11
Posts: 8

Topic

Just started with Rotorz Tiles and I'm really liking it so far.  Was wondering if I could get help with this issue.

When I make a normal tileset and paint it with the brush, the end result is a single game object with about 50 or so tiles clustered in it.  The tiles themselves are not separate game objects.  However, I followed a tutorial to make an animated tileset, which required me making an animated prefab and then an "orientation."  When I paint the animated tile, every single tile is a separate game object, which seems memory intensive and harder to manage if I need to update something. 

Is there a way to make an animated tileset w/o each one becoming a separate game object in the hierarchy?  Also, does it change how I interact with the tile through the scripting API?

Lea Hayes
Rotorz Limited
From: United Kingdom
Registered: 2014-03-04
Posts: 638

Response 1

In many ways the concept of a tile is very similar to that of a sprite; except tiles are generally much more static in nature whilst sprites are much more dynamic.

Sure one way to animate your tiles would be to have very large quantities of sprites; but as you have found, this is not an efficient solution.

What you could do, however, is create an animated shader for your shared tileset material which offsets the UV coordinates of all the tiles in one go or loops through a bunch of texture slots on the material. Since the adjustment only occurs in one central place (the shared material) you get a super effective way to animate a large number of tiles. And... the tile mesh does not need to be touched.

If your tiles are not animated; but, let's say, dissolve when they are destroyed. You could swap the tile for an animated sprite. That way the tiles only become dynamic when they are destroyed and animate.

There are a lot of ways to address tile animation; I hope that this is of some help!

fregas
New Member
Registered: 2017-05-11
Posts: 8

Response 2

So let me see if I understand.   

I'm trying to make animated water.  I need to make an animated shader with the tileset material and i can loop the image to get the animated effect I'm looking for.  Then I can use that in a normal tileset instead of an orientation, so the tiles will get churned out as a  single game object sharing the same material.  But I could still use your scripting API to know that there is water at a certain x/y coordinate. 

Do you have a tutorial you recommend that could at least get me to the animated shader part?  I've never done that.

Thanks for your help with this and getting registered on the forums the other day Lea!

Lea Hayes
Rotorz Limited
From: United Kingdom
Registered: 2014-03-04
Posts: 638

Response 3

fregas wrote:

I'm trying to make animated water.  I need to make an animated shader with the tileset material and i can loop the image to get the animated effect I'm looking for.  Then I can use that in a normal tileset instead of an orientation, so the tiles will get churned out as a  single game object sharing the same material.  But I could still use your scripting API to know that there is water at a certain x/y coordinate.

That is one solution yes. You could also animate the property of your shared material from a script.

For information on accessing tile information at runtime see the Accessing Tiles section of the docs and the TileData class.

fregas wrote:

Do you have a tutorial you recommend that could at least get me to the animated shader part?  I've never done that.

Unfortunately I do not but the Unity documentation has information regarding their ShaderLab syntax and there are a lot of resources on the web regarding shader implementation.

fregas wrote:

Thanks for your help with this and getting registered on the forums the other day Lea!

No problem!! :)

fregas
New Member
Registered: 2017-05-11
Posts: 8

Response 4

Lea Hayes wrote:

That is one solution yes. You could also animate the property of your shared material from a script.

You're saying I could make a normal tileset, access the tile via your api and animate the material that way?  Any idea what this would look like in code?  It sounds simpler.

Lea Hayes
Rotorz Limited
From: United Kingdom
Registered: 2014-03-04
Posts: 638

Response 5

I think the simplest way to access the tileset material is to just reference the material asset directly from the script that you have animate it.

But if you want to add animation into the shader itself; it's just a case of using the special time properties (see "Various" at bottom of https://docs.unity3d.com/460/Documentat … lues.html).

fregas
New Member
Registered: 2017-05-11
Posts: 8

Response 6

So I think I have this pretty close.  I've found a script that shows how to change the offset of a material to animate it:

http://answers.unity3d.com/questions/95 … ial-1.html

And from my script I can easily get the Tile I want to animate:

        var tileSystem = GameObject.Find("WorldTiles").GetComponent<TileSystem>();
        var tile = tileSystem.GetTile(61, 74);

This all works great. However, I can't seem to get the correct material from the TileData class the way you described:

        var material = tile.TilesetBrush.GetNthMaterial(0);
        var material = tile.brush.GetNthMaterial(0);

Both return null.  I also tried tile.gameObject but it was null. 

Am I missing something?

Lea Hayes
Rotorz Limited
From: United Kingdom
Registered: 2014-03-04
Posts: 638

Response 7

You can provide your script with direct access to the tileset material asset.

Alternatively, you can access the tileset material via the tileset itself (see Tileset.AtlasMaterial). The tileset itself can be accessed via TilesetBrush.Tileset.

So:

var material = tile.tileset.AtlasMaterial;
// or
var material = tile.TilesetBrush.Tileset.AtlasMaterial;

I hope that this helps!

Last edited by Lea Hayes (2017-05-21 03:07:56)

fregas
New Member
Registered: 2017-05-11
Posts: 8

Response 8

Well, no errors, but changing the AtlastMaterial doesn't seem to affect any of the tiles on the screen:

	void Update ()
	{
		var tileSystem = GameObject.Find("WorldTiles").GetComponent<TileSystem>();
		var tile = tileSystem.GetTile(61, 74);


		Debug.Log(tile.tileset); // shows "water"
		Debug.Log(tile.tileset.AtlasMaterial);
		var material = tile.tileset.AtlasMaterial;

		uvOffset += uvAnimationRate * Time.deltaTime;
		Debug.Log("x: " + uvOffset.x + ", " + uvOffset.y);
		material.mainTextureOffset = uvOffset;
		material.SetTextureOffset("_MainTex", uvOffset);
	}

Last edited by fregas (2017-05-21 03:44:03)

Lea Hayes
Rotorz Limited
From: United Kingdom
Registered: 2014-03-04
Posts: 638

Response 9

The tileset shader is a derivation of the sprite shader the Unity provide which doesn't appear to take the texture offset into consideration.

You could tweak that shader to add that functionality or you could just change the shader used on the tileset material to something else like "Unlit/Transparent".

For animating your material you may want to consider using the built-in _Time variable

I hope that this helps!

fregas
New Member
Registered: 2017-05-11
Posts: 8

Response 10

Took some experimentation but I think I have it almost working.  I changed the material to Unlit/Transparent in unity and now it seems when I increment or decrement the offset on the AtlasMaterial, it jumps to a different point in the list of sprites.  I think I can use that to move the water up or down if I put it in its own sprite sheet.  I'll play with a bit further but I think this gets me almost there.

Thanks for your help Lea!