Version: 2020.1

Mesh.SetBoneWeights

切换到手册
public void SetBoneWeights (NativeArray<byte> bonesPerVertex, NativeArray<BoneWeight1> weights);

参数

bonesPerVertex 网格中每个顶点的骨骼数量。
weights 每个顶点的 BoneWeight1 结构(按顶点索引进行排序)。

描述

设置网格的骨骼权重。

支持每个顶点具有可变数量的骨骼。每个顶点的骨骼权重排序时必须使最重要的权重在最前。零权重会被忽略。

权重的存储精度可能低于传入的浮点值,因此不要期望使用 Mesh.GetAllBoneWeights 获取完全相同的值。使用的最低精度当前为 16 位标准化整数。

另请参阅:Mesh.GetAllBoneWeightsMesh.GetBonesPerVertexMesh.boneWeightsMesh.GetBoneWeights ModelImporter.maxBonesPerVertexQualitySettings.skinWeightsSkinnedMeshRenderer.quality

using UnityEngine;
using System.Collections;
using Unity.Collections;

public class ExampleClass : MonoBehaviour { void Start() { gameObject.AddComponent<Animation>(); gameObject.AddComponent<SkinnedMeshRenderer>(); SkinnedMeshRenderer rend = GetComponent<SkinnedMeshRenderer>(); Animation anim = GetComponent<Animation>();

// Build basic mesh 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) }; 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();

// Assign mesh to mesh filter &amp; renderer rend.material = new Material(Shader.Find("Diffuse"));

// Assign bone weights to mesh byte[] bonesPerVertex = new byte[4] { 1, 2, 2, 1 }; BoneWeight1[] weights = new BoneWeight1[6];

// Vertex 0 weights[0].boneIndex = 0; weights[0].weight = 1;

// Vertex 1 weights[1].boneIndex = 0; weights[1].weight = 0.5f;

weights[2].boneIndex = 1; weights[2].weight = 0.5f;

// Vertex 2 weights[3].boneIndex = 0; weights[3].weight = 0.5f;

weights[4].boneIndex = 1; weights[4].weight = 0.5f;

// Vertex 3 weights[5].boneIndex = 1; weights[5].weight = 1;

var bonesPerVertexArray = new NativeArray<byte>(bonesPerVertex, Allocator.Temp); var weightsArray = new NativeArray<BoneWeight1>(weights, Allocator.Temp);

mesh.SetBoneWeights(bonesPerVertexArray, weightsArray);

// Create Bone Transforms and Bind poses // One bone at the bottom and one at the top Transform[] bones = new Transform[2]; Matrix4x4[] bindPoses = new Matrix4x4[2];

bones[0] = new GameObject("Lower").transform; bones[0].parent = transform; // Set the position relative to the parent bones[0].localRotation = Quaternion.identity; bones[0].localPosition = Vector3.zero;

// The bind pose is bone's inverse transformation matrix // In this case the matrix we also make this matrix relative to the root // So that we can move the root game object around freely bindPoses[0] = bones[0].worldToLocalMatrix * transform.localToWorldMatrix;

bones[1] = new GameObject("Upper").transform; bones[1].parent = transform; // Set the position relative to the parent bones[1].localRotation = Quaternion.identity; bones[1].localPosition = new Vector3(0, 5, 0); // The bind pose is bone's inverse transformation matrix // In this case the matrix we also make this matrix relative to the root // So that we can move the root game object around freely bindPoses[1] = bones[1].worldToLocalMatrix * transform.localToWorldMatrix;

// assign the bindPoses array to the bindposes array which is part of the mesh. mesh.bindposes = bindPoses;

// Assign bones and bind poses rend.bones = bones; rend.sharedMesh = mesh;

// Assign a simple waving animation to the bottom bone 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) };

// Create the clip with the curve AnimationClip clip = new AnimationClip(); clip.legacy = true; clip.SetCurve("Lower", typeof(Transform), "m_LocalPosition.z", curve);

// Add and play the clip anim.AddClip(clip, "test"); anim.Play("test"); } }