Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Unity Bone Constraint implementation sample
/**
[BoneConstraintSystem]
Copyright (c) https://twitter.com/izm
This software is released under the MIT License.
http://opensource.org/licenses/mit-license.php
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BoneConstraintSystem
{
/// <summary>
/// 3dsMaxで言うところのボーンコンストレイントっぽい挙動を実装したやつ
/// parentsに指定した骨の姿勢移動量を、このスクリプトを貼り付けたTransformの姿勢変化量と、反映度合い(coefficient)に合わせて反映します。
/// 複数個の親を指定することで、割合を混ぜることが出来ます。
/// スカート破綻を防ぐために太ももの移動量をスカートボーンに反映したり、揺れモノのめり込みを抑制するようなシチュエーションを想定しています。
///
/// 複数個の親を指定出来るのは、例えばスカート中央の骨はLeftUpperLegとRightUpperLegの割合を0.5づつにする、などの調整を想定しています。
/// 揺れモノとの処理順が必要であればUpdate()をLateUpdate()にするなど対処して下さい。
///
/// TODO:角度制限、特定方向以外の姿勢変化を制限する?
/// </summary>
public class BoneConstraint : MonoBehaviour
{
[System.Serializable]
public class ContraintBoneParent
{
public Transform Bone;
[Range(0, 1)] public float Coeficient = 1f;
public void Init()
{
_initialQuaternion = Bone.localRotation;
}
public Quaternion DiffQuaternion()
{
return Bone.localRotation * Quaternion.Inverse(_initialQuaternion);
}
private Quaternion _initialQuaternion;
}
[SerializeField] private List<ContraintBoneParent> _parents;
Transform _target;
private Quaternion _targetInitQuaternion;
// Use this for initialization
private void Awake()
{
foreach (var item in _parents)
{
item.Init();
}
_target = this.transform;
_targetInitQuaternion = _target.localRotation;
}
// Update is called once per frame
void Update()
{
_target.localRotation = _targetInitQuaternion;
foreach (var item in _parents)
{
var coeficientedQuartanion =
Quaternion.Slerp(_targetInitQuaternion, item.DiffQuaternion(), item.Coeficient);
_target.localRotation *= coeficientedQuartanion;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.