using UnityEngine; using System.Collections.Generic; using System.Linq; public class BoneController : MonoBehaviour { public BoneController additive_parent; public float additive_rate; public CCDIKSolver ik_solver; public BoneController[] ik_solver_targets; public bool add_local; public bool add_move; public bool add_rotate; /// /// 簡略化トランスフォーム /// [System.Serializable] public class LiteTransform { public Vector3 position; // 位置 public Quaternion rotation; // 回転 public LiteTransform(Vector3 p, Quaternion r) {position = p; rotation = r;} } private LiteTransform prev_global_; private LiteTransform prev_local_; /// /// 初回更新前処理 /// void Start() { if (null != ik_solver) { ik_solver = transform.GetComponent(); if (0 == ik_solver_targets.Length) { ik_solver_targets = Enumerable.Repeat(ik_solver.target, 1) .Concat(ik_solver.chains) .Select(x=>x.GetComponent()) .ToArray(); } } UpdatePrevTransform(); } /// /// ボーン変形 /// public void Process() { if (null != additive_parent) { //付与親有りなら LiteTransform additive_parent_transform = additive_parent.GetDeltaTransform(add_local); if (add_move) { //付与移動有りなら transform.localPosition += additive_parent_transform.position * additive_rate; } if (add_rotate) { //付与回転有りなら Quaternion delta_rotate_rate; if (0.0f <= additive_rate) { //正回転 delta_rotate_rate = Quaternion.Slerp(Quaternion.identity, additive_parent_transform.rotation, additive_rate); } else { //逆回転 Quaternion additive_parent_delta_rotate_reverse = Quaternion.Inverse(additive_parent_transform.rotation); delta_rotate_rate = Quaternion.Slerp(Quaternion.identity, additive_parent_delta_rotate_reverse, -additive_rate); } transform.localRotation *= delta_rotate_rate; } } } /// /// 差分トランスフォーム取得 /// /// 差分トランスフォーム /// ローカル付与か(true:ローカル付与, false:通常付与) public LiteTransform GetDeltaTransform(bool is_add_local) { LiteTransform result; if (is_add_local) { //ローカル付与(親も含めた変形量算出) result = new LiteTransform(transform.position - prev_global_.position , Quaternion.Inverse(prev_global_.rotation) * transform.rotation ); } else { //通常付与(このボーン単体での変形量算出) result = new LiteTransform(transform.localPosition - prev_local_.position , Quaternion.Inverse(prev_local_.rotation) * transform.localRotation ); } return result; } /// /// 差分基点トランスフォーム更新 /// public void UpdatePrevTransform() { prev_global_ = new LiteTransform(transform.position, transform.rotation); prev_local_ = new LiteTransform(transform.localPosition, transform.localRotation); } }