Version: 2019.1 (switch to 2018.3 or 2017.4)
LanguageEnglish
  • C#

Mesh.SetBoneWeights

Suggest a change

Success!

Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.

Close

Submission failed

For some reason your suggested change could not be submitted. Please <a>try again</a> in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.

Close

Cancel

Switch to Manual
public void SetBoneWeights(NativeArray<byte> bonesPerVertex, NativeArray<BoneWeight1> weights);

Parameters

bonesPerVertexBone count for each vertex in the Mesh.
weightsBone weights sorted by vertex index and then by descending weight for each vertex.

Description

Sets the bone weights for the Mesh.

Supports a variable number of bones per vertex. The bone weights for each vertex must be sorted with the most significant weights first. Zero weights will be ignored.

The weights may be stored with less precision than the floating point values passed in, so do not expect to get the exact same values back using GetAllBoneWeights. The minimum precision used is currently 16-bit normalized integers.

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 & 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.SetCurve("Lower", typeof(Transform), "m_LocalPosition.z", curve);

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

Did you find this page useful? Please give it a rating: