- 最后登录
- 2018-6-29
- 注册时间
- 2011-7-1
- 阅读权限
- 20
- 积分
- 359
- 纳金币
- 335582
- 精华
- 0
|
什么是骨骼权重:
骨骼权重在蒙皮网格中使用,举个例子来说,手腕关节运动时,受到2块主要骨骼的影响,手腕关节可以看作蒙皮网格中的顶点,在Unity中一个顶点最多受4块骨骼的影响,每块骨骼的影响程度有一个百分比,即骨骼权重,所有骨骼权重相加为1. 每个顶点会保存一个影响该顶点的变换数组,这些变换是当前骨骼相对于父对象的变换。利用递归的方式来得到每块骨骼在世界坐标系下的位置,详细关于这些变换的原理,还望从网上找找资料看。
下面这个脚本代码来自官方手册,这里做一下解析,明白了这个代码,以后使用蒙皮网格,操作骨骼权重就不成问题了
using UnityEngine;
using System.Collections;
public class UseMeshBoneWeight : MonoBehaviour {
public Texture2D tex2D;
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, 5, 0), new Vector3(1, 5, 0)};//该平面在xy所在的平面
mesh.uv = new Vector2[] {new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1)};//纹理坐标的左下角为(0,0)
mesh.triangles = new int[] {0, 1, 2, 1, 3, 2};//右手螺旋,判断面的朝向
mesh.RecalculateNormals();//重新计算法向量,
renderer.material = new Material(Shader.Find(" Diffuse"));
BoneWeight[] weights = new BoneWeight[4];
//这里只用到了2块骨骼,也就是说网格的所有顶点最多受2块骨骼的影响
weights[0].boneIndex0 = 0;//顶点0 使用的骨骼变换索引为0 可见每个顶点只受到一块骨骼的影响
//所以 当这块影响它的骨骼 的变换发生变化,该顶点将受到影响,这是只有一块骨骼,所以,骨骼变换到
//什么地方,该顶点就从原来的位置×(骨骼变换所使用的矩阵)=现在的位置
weights[0].weight0 = 1;//权重为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;
Transform[] bones = new Transform[2];//这里的变换就是上面的变换索引指向的地方
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, 5, 0);
bindPoses[1] = bones[1].worldToLocalMatrix * transform.localToWorldMatrix;
mesh.bindposes = bindPoses;//绑定姿势数组是BoneWeight指定的索引的变换矩阵
renderer.bones = bones;//这个用来渲染蒙皮网格的Bone用 当骨骼移动的时候 受该骨骼影响的顶点就会应用bindPoses中设定的变换矩阵,这个变换矩阵会和顶点原来的变换位置做乘积
renderer.sharedMesh = mesh;
renderer.material.SetTexture("_MainTex", tex2D);
AnimationCurve curve = new AnimationCurve();
curve.keys = new Keyframe[] {new Keyframe(0, 0, 0, 0), new Keyframe(1, 3, 0, 0), new Keyframe(2, 0.0F, 0, 0)};//Keyframe的4个参数为,时间点,该时间点位置的曲线
//值 进切线 出切线
AnimationClip clip = new AnimationClip();
clip.SetCurve("Lower", typeof(Transform), "m_LocalPosition.z", curve);
animation.AddClip(clip, "test");
animation["test"].wrapMode = WrapMode.PingPong;
animation.Play("test");
}
}
使用 新建一个GameObject 空的 将该代码附加到该GameObject上,运行 ,可以 在代码中添加材质的纹理
效果如下:附件是场景文件 请重命名 |
|