Tiled2Unity icon indicating copy to clipboard operation
Tiled2Unity copied to clipboard

Better way to create objects from prefabs already available in the project

Open rraallvv opened this issue 8 years ago • 4 comments

I wonder if there is a better way to add a custom property to some objects in an objects layer to get Tiled2Unity to creater the GameObjects from some already createrd prefabs.

Say we have the property prefab with the value Cannon.

screen shot 2016-09-24 at 12 36 43 pm

I modified the script ImportTiled2Unity.Mesh.cs where it creates the GameObject to look for the value in the property prefab, then create the GameObject from the prefabs already available in my Assets/Prefabs folder. Something like follows:

string prefabName = (from p in goXml.Elements("Property") where p.Attribute("name").Value == "prefab" select p.Attribute("value").Value).FirstOrDefault();

if (prefabName != null) {
    string prefabPath = "Assets/Prefabs/" + prefabName + ".prefab";
    UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));
    if (prefab != null) {
        GameObject prefabInstance = (GameObject)GameObject.Instantiate(prefab);
        prefabInstance.name = prefab.name;
        child = prefabInstance;
    }
}

if (child == null) {
    child = new GameObject();
}

I wonder if there is a beter way to do it. Something that doesn't imply modifieng the scripts in TiledToUnity

Keep up the good word,

Regards.

rraallvv avatar Sep 24 '16 16:09 rraallvv

I would love to have this as well. @rraallvv I think you should send a pull request!

andreesteve avatar Dec 11 '16 20:12 andreesteve

I think this, or a flavor of it, is a good idea. I wonder how we can resolve the prefab path though so that it is more general? Or maybe I can have unity just find the first prefab that matches a given name and use that?

Seanba avatar Dec 13 '16 00:12 Seanba

My code may be horrible but at least I made an general way to search the prefab from all /Assets/Prefabs directions.

var prefabList = new DirectoryInfo("Assets/Prefabs").GetFiles("*.prefab", SearchOption.AllDirectories); //Make sure to Update once

string prefabName = (from p in goXml.Elements("Property") where p.Attribute("name").Value == "prefab" select p.Attribute("value").Value).FirstOrDefault();

if (prefabName != null) { 
string prefabPath = "";
prefabName = prefabName + ".prefab";

foreach (var item in prefabList) {
    
    if(item.Name.Equals(prefabName))
    {
        prefabPath =  "Assets" + BuildRelativePath(item.Directory.FullName, Application.dataPath) + "/" + item.Name;
        break;
    }
}

UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));
...

as for BuildRelativePath Method:

private string BuildRelativePath(string absolutePath, string basePath){
    return absolutePath.Substring(basePath.Length).Replace(@"\", @"/");
}

Sinecos avatar Mar 29 '17 00:03 Sinecos

Instead of requiring all prefabs to be in a pre-defined directory, it could use labels instead, to be more project-agnostic: Unity label example

You can use AssetDatabase.FindAssets to search labels instead of just names, using the "l:" prefix (i.e. "l:Tiled2UnityPrefabs"). Could search the database once at the start of import, and create a dictionary of names/prefabs to pull from.

Er, that said, dunno how useful this feature would be, since the GameObjects wouldn't be linked (they'd be baked into the map prefab, right?), and so wouldn't update with their prefab. Guess we could hold out hope that Unity implements nested prefabs sometime soon?

skslucher avatar May 07 '17 21:05 skslucher