纳金网

标题: 蒙皮网格中的骨骼权重 [打印本页]

作者: 晃晃    时间: 2011-9-19 08:03
标题: 蒙皮网格中的骨骼权重
什么是骨骼权重:
骨骼权重在蒙皮网格中使用,举个例子来说,手腕关节运动时,受到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  可见每个顶点只受到一块骨骼的影响
//所以 当这块影响它的骨骼 的变换发生变化,该顶点将受到影响,这是只有一块骨骼,所以,骨骼变换到
//什么地方,该顶点就从原来的位置&times;(骨骼变换所使用的矩阵)=现在的位置

  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上,运行 ,可以 在代码中添加材质的纹理

效果如下:附件是场景文件 请重命名

UseMeshBoneWeight.unitypackage.zip

0 Bytes, 下载次数: 21


作者: Asen    时间: 2011-9-19 08:45

作者: C.R.CAN    时间: 2011-12-23 14:42
先垫一块,再说鸟

作者: 菜刀吻电线    时间: 2012-1-6 19:31
我来顶个

作者: 彬彬    时间: 2012-2-7 14:15

作者: 彬彬    时间: 2012-2-7 14:15

作者: 奇    时间: 2012-3-10 23:22
再次路过……

作者: 晃晃    时间: 2012-4-20 23:18
佩服,好多阿 ,哈哈

作者: C.R.CAN    时间: 2012-4-30 23:22
好可爱的字,学习了

作者: 晃晃    时间: 2012-6-22 23:20
其实楼主所说的这些,俺支很少用!

作者: C.R.CAN    时间: 2012-6-25 23:27
水……生命之源……灌……

作者: 菜刀吻电线    时间: 2012-8-8 23:51
跑着去顶朋友滴铁

作者: 奇    时间: 2012-8-28 23:38
先顶上去,偶要高亮加精鸟!

作者: 菜刀吻电线    时间: 2013-2-7 00:18
跑着去顶朋友滴铁

作者: 菜刀吻电线    时间: 2013-3-17 23:19
呵呵,很好,方便罗。





欢迎光临 纳金网 (http://go.narkii.com/club/) Powered by Discuz! X2.5