bonesPerVertex | 网格中每个顶点的骨骼数量。 |
weights | 每个顶点的 BoneWeight1 结构(按顶点索引进行排序)。 |
设置网格的骨骼权重。
Supports up to 255 bone weights per vertex. The bone weights for each vertex must be sorted with the most significant weights first. Zero weights will be ignored.
权重的存储精度可能低于传入的浮点值,因此不要期望使用 Mesh.GetAllBoneWeights 获取完全相同的值。使用的最低精度当前为 16 位标准化整数。
另请参阅:Mesh.GetAllBoneWeights、Mesh.GetBonesPerVertex、Mesh.boneWeights、Mesh.GetBoneWeights ModelImporter.maxBonesPerVertex、QualitySettings.skinWeights、SkinnedMeshRenderer.quality。
using UnityEngine; using Unity.Collections;
public class MeshSetBoneWeights : MonoBehaviour { void Start() { Animation animation = gameObject.AddComponent<Animation>(); SkinnedMeshRenderer renderer = gameObject.AddComponent<SkinnedMeshRenderer>();
// Build a rectangular mesh using four vertices and two triangles, and assign a material to the renderer Mesh mesh = new Mesh(); mesh.vertices = new Vector3[] { new Vector3(0, 0, 0), new Vector3(5, 0, 0), new Vector3(0, 5, 0), new Vector3(5, 5, 0) }; mesh.triangles = new int[] { 0, 1, 2, 1, 3, 2 }; mesh.RecalculateNormals(); renderer.material = new Material(Shader.Find("Standard"));
// Create a Transform and bind pose for two bones Transform[] bones = new Transform[2]; Matrix4x4[] bindPoses = new Matrix4x4[2];
// Create a bottom-left bone as a child of this GameObject bones[0] = new GameObject("BottomLeftBone").transform; bones[0].parent = transform; bones[0].localRotation = Quaternion.identity; bones[0].localPosition = Vector3.zero; // Set the bind pose to the bone's inverse transformation matrix, relative to the root bindPoses[0] = bones[0].worldToLocalMatrix * transform.localToWorldMatrix;
// Create a top-right bone bones[1] = new GameObject("TopRightBone").transform; bones[1].parent = transform; bones[1].localRotation = Quaternion.identity; bones[1].localPosition = new Vector3(5, 5, 0); bindPoses[1] = bones[1].worldToLocalMatrix * transform.localToWorldMatrix;
// Create an array that describes the number of bone weights per vertex // The array assigns 1 bone weight to vertex 0, 2 bone weights to vertex 1, and so on. byte[] bonesPerVertex = new byte[4] { 1, 2, 2, 1 };
// Create a array with one BoneWeight1 struct for each of the 6 bone weights BoneWeight1[] weights = new BoneWeight1[6];
// Assign the bottom-left bone to vertex 0 (the bottom-left corner) weights[0].boneIndex = 0; weights[0].weight = 1;
// Assign both bones to vertex 1 (the bottom-right corner) weights[1].boneIndex = 0; weights[1].weight = 0.5f;
weights[2].boneIndex = 1; weights[2].weight = 0.5f;
// Assign both bones to vertex 2 (the top-left corner) weights[3].boneIndex = 0; weights[3].weight = 0.5f;
weights[4].boneIndex = 1; weights[4].weight = 0.5f;
// Assign the top-right bone to vertex 3 (the top-right corner) weights[5].boneIndex = 1; weights[5].weight = 1;
// Create NativeArray versions of the two arrays var bonesPerVertexArray = new NativeArray<byte>(bonesPerVertex, Allocator.Temp); var weightsArray = new NativeArray<BoneWeight1>(weights, Allocator.Temp);
// Set the bone weights on the mesh mesh.SetBoneWeights(bonesPerVertexArray, weightsArray); bonesPerVertexArray.Dispose(); weightsArray.Dispose();
// Assign the bind poses to the mesh mesh.bindposes = bindPoses;
// Assign the bones and the mesh to the renderer renderer.bones = bones; renderer.sharedMesh = mesh;
// Assign a simple back-and-forth animation to the bottom-left bone, and play the animation // Vertex 0 moves directly with the bone // Vertex 1 and 2 also move, but there's less movement because the vertices are also weighted to the top-right bone // Vertex 3 doesn't move, because the top-right bone doesn't move AnimationCurve curve = new AnimationCurve(); curve.keys = new Keyframe[] { new Keyframe(0f, 0f, 0f, 0f), new Keyframe(1f, 3f, 0f, 0f), new Keyframe(2f, 0f, 0f, 0f) }; AnimationClip clip = new AnimationClip(); clip.legacy = true; clip.SetCurve("BottomLeftBone", typeof(Transform), "m_LocalPosition.z", curve); clip.wrapMode = WrapMode.Loop; animation.AddClip(clip, "test"); animation.Play("test");
} }
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.