Hello,
I’m currently working on a modding system for my game and I’m having a little bit of trouble. I’m trying to reduce the memory usage by making use of dependencies within asset bundles, but the method that I’m trying to utilize doesn’t seem to work. In the documentation page (http://docs.unity3d.com/Manual/managingassetdependencies.html) it shows a method of building shader dependencies using a temp object, and I’m wondering if there’s a way to do the same for other types of objects. The code I’m using is:
// iterate over all of the objects
GameObject goObject = null;
foreach (GameObject go in gameobjects)
{
// don't allow standard assets to be added
// we do this because they are already part of Unity
if (go.IsStandardAsset())
continue;
// try to get the prefab
goObject = (GameObject)PrefabUtility.GetPrefabParent(go);
// if no prefab was found, assume that this is either not a prefab, or is already a prefab
if (goObject == null)
goObject = go;
// get all of the mesh filters and renderers
SkinnedMeshRenderer[] skinrenderers = goObject.transform.GetInactiveComponentsInObjectAndChildren<SkinnedMeshRenderer>();
MeshRenderer[] renderers = goObject.transform.GetInactiveComponentsInObjectAndChildren<MeshRenderer>();
MeshFilter[] filters = goObject.transform.GetInactiveComponentsInObjectAndChildren<MeshFilter>();
// iterate over all of each type and add the proper sub-objects to the correct assets
foreach (SkinnedMeshRenderer skinrenderer in skinrenderers)
{
foreach (Material material in skinrenderer.sharedMaterials)
{
shaders.AddAsset(material.shader);
materials.AddAsset(material);
}
}
foreach (MeshRenderer renderer in renderers)
{
foreach (Material material in renderer.sharedMaterials)
{
shaders.AddAsset(material.shader);
materials.AddAsset(material);
}
}
foreach (MeshFilter mesh in filters)
meshes.AddAsset(mesh);
}
The object I am attempting to serialize them to is:
#if GAME_TOOLS
using System;
using UnityEngine;
using System.Collections.Generic;
using Game.Modding.Shared;
#if UNITY_EDITOR
using UnityEditor;
using Game.Modding.Editor;
#endif
namespace Game.Modding.Shared
{
public class ModPrerequisites : ScriptableObject
{
[SerializeField]
private List<UnityEngine.Object> m_lAssets = new List<UnityEngine.Object>();
public IEnumerable<UnityEngine.Object> Assets { get { return m_lAssets; } }
#if UNITY_EDITOR
public void AddAsset(UnityEngine.Object scene)
{
// don't allow standard assets to be added
if (scene.IsStandardAsset())
return;
// add it
m_lAssets.Add(scene);
EditorUtility.SetDirty(this);
AssetDatabase.SaveAssets();
}
public void RemoveAsset(UnityEngine.Object scene)
{
m_lAssets.Remove(scene);
EditorUtility.SetDirty(this);
AssetDatabase.SaveAssets();
}
#endif
}
}
#endif
Unfortunately, EditorUtility.SetDirty(); returns an exception on the object (the ModPrerequisite object, not the object that is being added to it), stating that it has been destroyed. I have checked thoroughly, and neither the object itself nor any of the components listed inside are null, and the asset I’m working on shows up fine in the scene view. My first thought was that this is impossible, but attempting to put the prefab gameobject itself into my object caused the same exception. Of note, I AM able to drag/drop these assets into the list in the inspector for the asset.
To further assist, the end goal is to create an asset bundle dependency chain that looks like:
Shaders > Materials > Meshes > Mod Asset. The largest reason for this is that one of the mod assets are world modules, complete with artwork and lighting. I’m making use of scenes as prefabs for these, that way I can load the lightmaps additively and make use of GI with the world module. I’d like to set aside the materials and meshes that way I don’t have to include them in every single bundle. (It will also allow for artless variants in the case of distributing a dedicated server!)
Any thoughts?