- Home /
How to deform a game object using a skinned mesh and bones?
So I have a 2D game object, going off of this example script from the docs: http://docs.unity3d.com/Documentation/ScriptReference/Mesh-bindposes.html?from=SkinnedMeshRenderer
I modified it a bit by making the top bone rotate, so now upon playing the mesh will start deforming like the picture on the left below. But what I need it to do is make it deform like the one on the right.
I really have no idea what I'm doing. Can I even do what I'm aiming for this way? If I can, what do I have to do differently? I thought it would have something to do with bone weights but that doesn't make it curve at all. Any help would be appreciated...
Here's the revised script I have, main difference being the boneOrigin variable and the RotateAround in Update:
using UnityEngine;
using System.Collections;
public class example : MonoBehaviour {
public Material red;
Transform[] bones = new Transform[2];
Vector3 boneOrigin;
void Start() {
gameObject.AddComponent<Animation>();
gameObject.AddComponent<SkinnedMeshRenderer>();
SkinnedMeshRenderer renderer = GetComponent<SkinnedMeshRenderer>();
Mesh mesh = new Mesh();
mesh.vertices = new Vector3[] {new Vector3(-1, 0, 0), new Vector3(1, 0, 0), new Vector3(-1, 1.5f, 0), new Vector3(1, 1.5f, 0)};
mesh.uv = new Vector2[] {new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1)};
mesh.triangles = new int[] {0, 1, 2, 1, 3, 2};
mesh.RecalculateNormals();
renderer.material = red;
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;
mesh.boneWeights = weights;
Matrix4x4[] bindPoses = new Matrix4x4[2];
bones[0] = new GameObject("Lower").transform;
bones[0].parent = transform;
bones[0].localRotation = Quaternion.identity;
bones[0].localPosition = Vector3.zero;
bindPoses[0] = bones[0].worldToLocalMatrix * transform.localToWorldMatrix;
bones[1] = new GameObject("Upper").transform;
bones[1].parent = transform;
bones[1].localRotation = Quaternion.identity;
bones[1].localPosition = new Vector3(0, 1.5f, 0);
boneOrigin = new Vector3(bones[1].position.x-1f, bones[1].position.y, bones[1].position.z);
bindPoses[1] = bones[1].worldToLocalMatrix * transform.localToWorldMatrix;
mesh.bindposes = bindPoses;
renderer.bones = bones;
renderer.sharedMesh = mesh;
}
void Update(){
bones[1].RotateAround(boneOrigin, new Vector3(0, 0, 1), 20*Time.deltaTime);
}
}
Answer by Eric5h5 · Jun 04, 2013 at 06:55 PM
You'd need a lot more vertices, and they'd have to be weighted appropriately. There are no curves in 3D graphics; everything is straight lines, so if you want the illusion of something being curved, you have to break it up into many small straight lines.