I have a script that makes a GameObject and Meshcollider of 65k vertices.
Is it possible to save generated GameObject including MeshCollider, and even Shader and MeshRenderer?
I have a script that makes a GameObject and Meshcollider of 65k vertices.
Is it possible to save generated GameObject including MeshCollider, and even Shader and MeshRenderer?
I have found an answer to save the gameobject as prefab, with generated mesh and collider:
Using two C# codes: CreatePrefabFromSelected and saveMesh
First, saveMesh, it will automatically replace the generated mesh and meshcollider of the prefab with the mesh on disk
After, CreatePrefabFromSelected, saves the prefab with the saved mesh.
On the prefab, untick the mesh generator script.
it loads alot faster than making in game, about 1 second to load the prefab and collider, and 3 seconds to create the collider from scratch.
Something veeri strange happens though. I saved 2 mesh prefabs both of 65k, one of them loads to the game with physics in 0.05 seconds, and the other takes 1.2 seconds. I think it is the time the game write it to memory. one object was in the memory when i stop and play the game, the other one has to be loaded. So for fast running a game, i think you have to load the objects, and put the player in front of the objects for a frame at start of game, so the pc has already in memory the gameobjects.
EDIT: so here is a editor code that 1/saves procedural mesh to disk 2/ saves it’s entire prefab including scripts. shader settings, etc to a prefab, it’s also on unify wiki:
using UnityEditor;
using UnityEngine;
/// <summary>
/// saves mesh and entire prefab from gameview, your procedural mesh prefab is saved.
/// </summary>
class CreatePrefabFromSelected
{
const string menuName = "GameObject/Create Prefab From Selected";
/// <summary>
/// Adds a menu named "Create Prefab From Selected" to the GameObject menu.
/// </summary>
[MenuItem(menuName)]
static void CreatePrefabMenu ()
{
var go = Selection.activeGameObject;
Mesh m1 = go.GetComponent<MeshFilter>().mesh;//update line1
AssetDatabase.CreateAsset(m1, "Assets/savedMesh/" + go.name +"_M" + ".asset"); // update line2
var prefab = EditorUtility.CreateEmptyPrefab("Assets/savedMesh/" + go.name + ".prefab");
EditorUtility.ReplacePrefab(go, prefab);
AssetDatabase.Refresh();
}
/// <summary>
/// Validates the menu.
/// The item will be disabled if no game object is selected.
/// </summary>
/// <returns>True if the menu item is valid.</returns>
[MenuItem(menuName, true)]
static bool ValidateCreatePrefabMenu ()
{
return Selection.activeGameObject != null;
}
}
For the record, another way of creating a prefab with generated objects as meshes, is storing the object inside of the prefab itself. Here is a sample how to create a prefab with generated meshes inside of it:
/// <summary>
/// Create a prefab with an array of procedural generated meshes
/// </summary>
private GameObject CreatePrefab(Mesh[] meshes, Material[] materials, string prefabName, string outputPath)
{
// Create container
var gameObject = new GameObject(prefabName);
// Create an actual meshfilter for every mesh
for (int i = 0; i < meshes.Length; i++)
{
var mesh = meshes*;*
_ var material = materials*;*_
* // Create mesh container*
* var subGO = new GameObject(mesh.name);*
* subGO.transform.SetParent(gameObject.transform, false);*
* // Set Mesh and Material*
* subGO.AddComponent().sharedMesh = mesh;*
* subGO.AddComponent().sharedMaterial = material;*
* }*
* // Create a prefab to store the gameobject*
* var filename = gameObject.name + “.prefab”;*
* var filepath = Path.Combine(outputPath, filename);*
* filepath = AssetDatabase.GenerateUniqueAssetPath(filepath);*
* GameObject rootPrefab = null;*
* try*
* {*
* // Create prefab*
* rootPrefab = PrefabUtility.CreatePrefab(filepath, gameObject);*
* // Set prefab meshes*
* for (int i = 0; i < meshes.Length; i++)*
* {*
* var childPrefab = rootPrefab.transform.GetChild(i);*
* var filter = childPrefab.GetComponent();*
* if (filter != null)*
* {*
_ filter.sharedMesh = meshes*;
filter.sharedMesh.RecalculateBounds();*_
* // Store the mesh inside the prefab*
_ AssetDatabase.AddObjectToAsset(meshes*, rootPrefab);
}
}
AssetDatabase.SaveAssets();
}
catch*
* {
Debug.LogError(string.Format(“Error creating prefab ‘{0}’ at path ‘{1}’”, filename, outputPath));
}*_
* // Destroy temporal go*
* DestroyImmediate(gameObject);*
* return rootPrefab;*
}
You cannot serialize GameObjects and therefore you cannot save them to a file. But what you can do is to get the transform of the gameObject and save each and every x,y,z to float variables and recall them from file when you load.
If you are generating mesh at runtime, you can save the inputs to generate the mesh and write them to a file and when recalled on load, you can use the same inputs on the mesh generating script to generate the same mesh?