Hello Guest

Author Topic: Create SpriteCollection(s) via code  (Read 5834 times)

HankTurbo

  • Newbie
  • *
  • Posts: 9
    • View Profile
Create SpriteCollection(s) via code
« on: October 29, 2014, 06:13:28 am »
Hiya,

I'm trying to set up an automated system for creating SpriteCollection(s). I'm creating a book, and each book has one large image. So what I'm trying to do is to create one SpriteCollection per page using an EditorWindow. The problem I'm having is that I run into an issue where tk2dSpriteCollectionBuilder.Rebuild runs, but the SpriteCollection doesn't keep its reference to the Data Object (SpriteCollectionData), and because of that I get the error: "Sprite collection (xxx) has no sprites" when I try to set a tk2dSprite to the given SpriteCollection.

Code: [Select]
string basepath = SPRITE_COLLECTION_BASEPATH + _bookID + "/";
string filename = _bookID + "_" + "Page" + pageNum + ".prefab";
string prefabPath = basepath + filename;

if (new FileInfo(prefabPath).Exists) {
D.Log("Ignoring to create a SpriteCollection as it already exists: '" + filename + "'.");
return;
}

// create game object with sprite collection
GameObject go = new GameObject("TempSpriteCollection");
tk2dSpriteCollection collection = go.AddComponent<tk2dSpriteCollection>();
collection.version = tk2dSpriteCollection.CURRENT_VERSION;
tk2dEditorUtility.SetGameObjectActive(go, false);

// create potential target folder
DirectoryInfo targetFolder = new DirectoryInfo(basepath);
if (!targetFolder.Exists) Directory.CreateDirectory(basepath);

// create prefab
UnityEngine.Object p = PrefabUtility.CreateEmptyPrefab(prefabPath);
GameObject collectionPrefabGo = PrefabUtility.ReplacePrefab(go, p, ReplacePrefabOptions.ConnectToPrefab);
tk2dSpriteCollection collectionFromPrefab = collectionPrefabGo.GetComponent<tk2dSpriteCollection>();
GameObject.DestroyImmediate(go);

// adjust SpriteCollection settings
collectionFromPrefab.sizeDef.type = tk2dSpriteCollectionSize.Type.PixelsPerMeter;
collectionFromPrefab.sizeDef.pixelsPerMeter = 1;
collectionFromPrefab.maxTextureSize = 4096;
tk2dSpriteCollectionPlatform platform2x = new tk2dSpriteCollectionPlatform();
platform2x.name = tk2dSystem.GetAssetPlatform("2x").name;
tk2dSpriteCollectionPlatform platform1x = new tk2dSpriteCollectionPlatform();
platform1x.name = tk2dSystem.GetAssetPlatform("1x").name;
collectionFromPrefab.platforms = new List<tk2dSpriteCollectionPlatform>(new tk2dSpriteCollectionPlatform[] { platform2x, platform1x } );

// create defintion for sprite/texture page
tk2dSpriteCollectionDefinition def = new tk2dSpriteCollectionDefinition();
def.name = "Page" + pageNum;
def.colliderType = tk2dSpriteCollectionDefinition.ColliderType.UserDefined;
def.texture = (Texture2D)AssetDatabase.LoadAssetAtPath(SPRITE_BASEPATH + _bookID + "/" + "Page" + pageNum + "@2x.jpg", typeof(Texture2D));
def.dice = true;
def.diceUnitX = def.diceUnitY = 256;

// add sprite/texture page defintion to SpriteCollection
List<tk2dSpriteCollectionDefinition> list = new List<tk2dSpriteCollectionDefinition>();
list.Add(def);
collectionFromPrefab.textureParams = list.ToArray();

// build SpriteCollection
tk2dSpriteCollectionBuilder.Rebuild(collectionFromPrefab);
Debug.Log("collectionFromPrefab.spriteCollection = " + collectionFromPrefab.spriteCollection);

AssetDatabase.Refresh();

At the end I log the data object and it's correct there, and then when I check the SpriteCollection in the Editor it is missing.

This doesn't happen all the time. I would initially run this code for X number of pages. And it would happen sometimes after one page has been completed, and sometimes straight away. I don't think I have seen it run more that two times before failing (texture size at 2x: 2732x1931). If I run it doing one page at a time, it will still fail after one, two or three runs.

The SpriteCollectionData prefab is generated correctly and sits in its Data folder. If I then try and run a "Commit" from the Editor it will start creating new Data objects that don't work. Probably because all the names get all haywired.

Hope you can give me a hint on how to solve this. I was hoping to avoid doing a lot of manual work for this.

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Create SpriteCollection(s) via code
« Reply #1 on: October 29, 2014, 03:56:53 pm »
It looks like your'e recreating the prefab every time...

I think its worth looking at the data driven sprite collections feature from 2.4 beta (that was removed from the final release). I've reposted it separately here -
http://2dtoolkit.com/forum/index.php/topic,4546.0.html

HankTurbo

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Create SpriteCollection(s) via code
« Reply #2 on: October 29, 2014, 10:17:58 pm »
Thanks.

I'll have a look at it.

What do you mean?
Quote
It looks like your'e recreating the prefab every time...

For my own sake I would like to know what I'm doing wrong. I hate not getting stuff working. So any help would be much appreciated.

This code snippet will generate a SpriteCollection for one page in the book. If a SpriteCollection already exists, it will not try and create it. Otherwise it will need to create it. This snippet of code will run XX amount of times. The SpriteCollection only holds one Sprite, and as far as I can tell, don't I then need to:
1. create a temp gameobject to add a new SpriteCollection
2. create the new sprite collection prefab
3. set sprite collections settings
4. add textures/sprites
5. build sprite collection

HankTurbo

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Create SpriteCollection(s) via code
« Reply #3 on: October 29, 2014, 11:17:22 pm »
And then I figured it out...

Quote
GameObject.DestroyImmediate(go);

Had to be done after the rebuild.

Thanks for your help!

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Create SpriteCollection(s) via code
« Reply #4 on: October 30, 2014, 11:58:16 am »
Hmmm I think I may have misunderstood your question, but glad you've resolved it.
Definitely look at that sample though - it will do what you need and is (imo) a really clean way of tackling this problem

HankTurbo

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Create SpriteCollection(s) via code
« Reply #5 on: October 30, 2014, 11:36:19 pm »
Thanks for the reply.

I agree that the "data driven sprite collections" looks a lot better than my approach, and if I get time I will update the code to make use of that much better framework.

Again, thanks for your help.