Hello, I have 27 bones (x, y, z). But how do you put them inside BoneWeights []? Since it only supports 4 bones?
One vertex can only be influenced by four bones but each vertex should only have weights for bones that are close to that vertex and can effect it's movement (i.e vertices in the foot should only have weights for maybe the foot bone, the lower leg bone, and the toe bone, but not have any weights for the neck bone etc.). Four should be enough for most purposes.
https://docs.unity3d.com/ScriptReference/Mesh-boneWeights.html There's an example and full explanation in the documentation, although I'd imagine it would just be easier to rig your model in a 3D modeling app like Blender or something.
Code (CSharp): // Assign bone weights to mesh // We use 2 bones. One for the lower vertices, one for the upper vertices. BoneWeight[] weights = new BoneWeight[4]; weights[0].boneIndex0 = 0; weights[0].weight0 = 1; weights[1].boneIndex0 = 0; weights[1].weight0 = 1; weights[2].boneIndex0 = 1; weights[2].weight0 = 1; weights[3].boneIndex0 = 1; weights[3].weight0 = 1; This is for 4 bones, the problem is that I have 27 bones (X, Y, Z). Do not have any method of positioning the bones automatically?
Not that I know of. You'd need to have some method to determine what bones are most likely to effect a vertex. A naive approach would be to find four the closest bones for a given vertex. For each vertex, to loop through every bone and record the distance between the bone and the vertex, then sort the distances and choose the smallest 4. You would probably want to have a distance threshold too, because some vertexes would only need the one, two or three closest bones. I don't think that would really work though. For example the, a vertex on the right leg may be close to the left knee bone, but obviously you don't want to make that connection. You'd need some way to tell if the bone is inside or outside that particular part of the surface. Maybe you could use a mesh collider and raycasts. What are you trying to do exactly? Is there some reason you really need to rig this model through code?
It all depends on which bone(s) you want to influence the vertex's movement and how much. All the vertex weights for a specific vertex must add-up to one, so think of the weight as a percentage. The specific values for each vertex all depend on your model and how want it to move. For example, If you have e vertex on the top of the head, then you probably want that vertex to be only moved by the head bone, so set the bone index to the head bone and the weight to 1. If you have a vertex between two bones and you want the vertex position to smoothly blend between the two bones, then set boneIndex0 and boneIndex1 to each of those bones and set both weights to 0.5.
The problem is to calculate this automatically, because I have several Mesh's that are created right at runtime.
That's what I was alluding to in my third post. Those were my ideas on how to calculate this, but it really seems like an advanced topic. Just googling "3d character automatic rigging algorithm" there are several academic papers written on the subject. Maybe these will give you some ideas. Are you sure you really need to rig the model at run-time, though? For example, if you are creating the model at run-time because you have a custom character editor- most games with customizable characters have a pre-made, already-rigged character model and the model is deformed at run-time. It does not need to be built from scratch.
That's why this is for an old game, I'm reading a custom file that contains all information, bones, vertices, faces, uvs. This file contains the co-ordinates x / y / z of each bone. I have already been able to position the bones, the problem is to make the bones work.
That's interesting. Are you sure the weights are not already in the file? If this game is really old (i.e. from the PS1 era) the model may never have had weights to begin with. In that case, you'd just have identify one bone to attach to each vertex and set the weight to 1.
No, it only contains x/z/y and 12 bytes of "child" Code: Code (CSharp): BoneWeight[] weights = new BoneWeight[this.vertices.Length]; for (int i = 0; i < this.bones.Length; i++) { weights[i].boneIndex0 = i; weights[i].weight0 = 1; } and??
Is there any documentation about this file format anywhere online? Even if the old game does not use vertex weights, presumably the file must contain enough information to recreate whatever rig it had. By the way, the code you posted above does not make sense. I assume you intend to assign mesh.boneWeights = weights;, as per the example. You are looping through your bones, but for weights[i] you need a vertex index, not a bone index. Also, you're not going to simply be able to assign your bone indexes in a loop like that, because the vertex index and bone index are almost certainly not going to correspond one-to-one like that.
So is the file you are trying to read a *.x file that is text encoded? Edit: And if it were a *.x file, wouldn't it be much easier to simply use some 3D modeling package to convert the *.x into a *.fbx and just import itinto the editor? Well, you'd want to loop from 0 to weights.length instead of bones.length. the length of weights should be equal to the number of vertexes in your mesh. As for what values to assign to boneIndex0 and weight0, well we still have to figure that out. I really think it could be inferred somehow from the data in the file that you are reading.
The file has information about the Index, and weights values. Thanks! However, the bones are not in the correct position. I left them as the son of the object, and they do not stand in the position they should be. Do I have to do a multiplication before positioning them?
Since it's a custom proprietary file, it's hard to say what they might have been thinking. Is the armature the correct shape? Is it the correct size compared to the object? It sounds like you have the object as the parent of the armature. Usually when I import an FBX character into Unity, the armature and the mesh are both siblings of a parent object.
I'm reading a binary file, reading the bytes (vertices, uvs, etc). However, the position of the bones is in the range of 0-1, and they are not in the wrong positions when the object is loaded.