Hi
I don’t know if I’m posting my problem to the correct Community, but here it goes. My apologies if I’m doing wrong.
-
I’m using Unity 2021.1.22f1
-
My idea for a game is to create static models of spaceships parent of bones in Blender, and control those bones inside Unity, to generate space ships with pseudo-randomand symmetric shapes
-
Inside Unity, there is a gameObject called Library, with SkinnedMeshRenderers components on GameObjects, which are the spaceships created on Blender
-
I started with a simple prototype to change randomly the ORIGINAL SkinnedMeshRenderer objects, with success
-
But when I copy the SkinnedMeshRenderer object to another GameObject through Instantiate() method, and try to change the bone transform which controls the SkinnedMeshRenderer shape in the new copyed GameObject, nothing happens
-
My code is down below:
//-----------------------------------------------------------------------------------------------
using System.Collections.Generic;
using UnityEngine;
public class CopyShips : MonoBehaviour
{
public Transform library;
Transform ship00T;
Transform ships;
Mesh copyMesh(SkinnedMeshRenderer smr)
{
Mesh mesh = smr.sharedMesh;
Mesh newmesh = new Mesh();
newmesh.name = mesh.name + “_copy”;
int i;
List vertices = new List();
for (i = 0; i < mesh.vertices.Length; i++)
{
vertices.Add(mesh.vertices*);*
}
newmesh.vertices = vertices.ToArray();
List triangles = new List();
for (i = 0; i < mesh.triangles.Length; i++)
{
triangles.Add(mesh.triangles*);*
}
newmesh.triangles = triangles.ToArray();
List uv = new List();
for (i = 0; i < mesh.uv.Length; i++)
{
uv.Add(mesh.uv*);*
}
newmesh.uv = uv.ToArray();
List normals = new List();
for (i = 0; i < mesh.normals.Length; i++)
{
normals.Add(mesh.normals*);*
}
newmesh.normals = normals.ToArray();
List colors = new List();
for (i = 0; i < mesh.colors.Length; i++)
{
colors.Add(mesh.colors*);*
}
newmesh.colors = colors.ToArray();
List tangents = new List();
for (i = 0; i < mesh.tangents.Length; i++)
{
tangents.Add(mesh.tangents*);*
}
newmesh.tangents = tangents.ToArray();
List bindposes = new List();
for (i = 0; i < mesh.bindposes.Length; i++)
{
bindposes.Add(mesh.bindposes*);*
}
newmesh.bindposes = bindposes.ToArray();
List boneWeights = new List();
for (i = 0; i < mesh.boneWeights.Length; i++)
{
boneWeights.Add(mesh.boneWeights*);*
}
newmesh.boneWeights = boneWeights.ToArray();
return newmesh;
}
void Start()
{
ship00T = library.Find(“Ship00T”);
ships = library.Find(“Ships”);
int i, t = ships.childCount / 2;
for (i = 0; i < t; i++)
{
Transform armature = ships.Find(“Armature_Ship” + i.ToString(“00”));
Transform ship = ships.Find(“Ship” + i.ToString(“00”));
SkinnedMeshRenderer smrShip = ship.gameObject.GetComponent();
Transform rootBone = smrShip.rootBone;
GameObject ship00T_copy = Instantiate(ship00T.gameObject);
ship00T_copy.transform.parent = transform;
ship00T_copy.transform.name = “ship” + i.ToString(“00”) + “T”;
GameObject armature_copy = Instantiate(armature.gameObject);
armature_copy.transform.parent = ship00T_copy.transform;
armature_copy.transform.name = armature.name;
GameObject ship_copy = Instantiate(ship.gameObject);
ship_copy.transform.parent = ship00T_copy.transform;
ship_copy.transform.name = ship.name;
SkinnedMeshRenderer smrCopy = ship_copy.gameObject.GetComponent();
smrCopy.rootBone = armature_copy.transform.Find(rootBone.name);
DeformShipBones dsb = ship00T_copy.GetComponent();
dsb.deformShips();
Mesh mesh = copyMesh(smrCopy);
smrCopy.BakeMesh(mesh, true);
smrCopy.sharedMesh = mesh;
}
}
}
//-----------------------------------------------------------------------------------------------
7) Executing the code, the copies are created, and when I click on the copyed GameObject with the SkinnedMeshRenderer in it, there is a message about the lack of the object blend shape, as written below:
The assigned mesh is missing either bone weights with bind pode, or blend shapes. This might cause the mesh no to render in the Player. If your mesh does not have either bone weights with bind pose, or blend shapes, use a mesh renderer instead of SkinnedMeshRenderer.
8) I also posted an image [UnityBlendShapesInSkinnedMeshRenderer.png] about the problem
9) The question I have is:
As we can program the copy of almost all properties of one mesh to another, as shown in the code above, like vertices, triangles, uvs, normals, colors, tangents, bindPoses and boneWeights, how can I copy BlendShapes, as this type of structure is not only a list of basic types, like Vector3 in vertices, or like int in triangles?
10) I also have look for some solution or thread on discussion forums, through Google, but with no success, and also tried to find the solution programming experimentally the copy of mesh.BlendShape objects (using auto-complete code from Visual Studio 2019), also with no success
11) Unity help on the subject Mesh (Unity - Scripting API: Mesh) present the list of methods about BlendShapes, but none of them have a complete example, as they - as told before - are complex objects
12) The first time I had programmed the deformation of SkinnedMeshRenderer was five years ago (2016), and I believe that Unity have make some structural changes into Mesh classes, since then.
13) Is it possible for someone to answer with a complete sample code about how to do that, please?
14) If you are interested into my prototype project, to help me on this matter, please let me know in your answer to this post, please. So, as this project is still at its start, it is very small, and I can put it exported and zipped in here, as an answer.
Cordially, and thanks in advance
César R. K. Stradiotto
Biguaçú - SC - Brazil
