您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
121 行
3.5 KiB
121 行
3.5 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using Unity.Mathematics;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
// TODO: (sunek) With the introduction of prefabs, evaluating procedural bones in edit mode will dirty the prefab.
|
|
// Find a way to not evaluate the script in prefab isolation mode or better yet address the bones in a way that does
|
|
// not change their serialized values (e.g. with a playable graph)
|
|
[ExecuteAlways]
|
|
public class TranslateScale : MonoBehaviour, ISkeletonTypeComponent
|
|
{
|
|
// todo: (sunek) Consider making function distance based (rather than on single axis)?
|
|
public List<TranslateScaleChain> chains = new List<TranslateScaleChain>();
|
|
|
|
// TODO: (sunek) Add support for variable axis
|
|
// public AimAxis aimAxis;
|
|
//
|
|
// public enum AimAxis
|
|
// {
|
|
// X, Y, Z
|
|
// }
|
|
//
|
|
[Serializable]
|
|
public struct Driven
|
|
{
|
|
public Transform joint;
|
|
[HideInInspector]
|
|
public float3 bindpose;
|
|
[Range(0f, 1)]
|
|
public float strectchFactor;
|
|
[Range(0f, 1)]
|
|
public float scaleFactor;
|
|
|
|
public bool IsValid()
|
|
{
|
|
return joint != null;
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public struct TranslateScaleChain
|
|
{
|
|
public Transform driver;
|
|
[HideInInspector]
|
|
public float3 bindpose;
|
|
public List<Driven> drivenJoints;
|
|
|
|
public bool HasValidData()
|
|
{
|
|
for (var i = 0; i < drivenJoints.Count; i++)
|
|
{
|
|
if (drivenJoints[i].joint == null)
|
|
return false;
|
|
}
|
|
|
|
return driver != null;
|
|
}
|
|
}
|
|
|
|
public void SetBindpose()
|
|
{
|
|
for (var i = 0; i < chains.Count; i++)
|
|
{
|
|
var chain = chains[i];
|
|
chain.bindpose = chain.driver.localPosition;
|
|
|
|
for (var j = 0; j < chain.drivenJoints.Count; j++)
|
|
{
|
|
var driven = chain.drivenJoints[j];
|
|
driven.bindpose = driven.joint.localPosition;
|
|
chain.drivenJoints[j] = driven;
|
|
}
|
|
|
|
chains[i] = chain;
|
|
}
|
|
}
|
|
|
|
public void GotoBindpose()
|
|
{
|
|
for (var i = 0; i < chains.Count; i++)
|
|
{
|
|
chains[i].driver.localPosition = chains[i].bindpose;
|
|
for (var j = 0; j < chains[i].drivenJoints.Count; j++)
|
|
{
|
|
chains[i].drivenJoints[j].joint.localPosition = chains[i].drivenJoints[j].bindpose;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
void LateUpdate()
|
|
{
|
|
if (EditorApplication.isPlaying || EditorApplication.isPaused)
|
|
return;
|
|
|
|
for (var i = 0; i < chains.Count; i++)
|
|
{
|
|
var chain = chains[i];
|
|
|
|
if (!chain.HasValidData())
|
|
continue;
|
|
|
|
var stretchOffset = chain.driver.transform.localPosition.y - chain.bindpose.y;
|
|
var stretchFactor = chain.driver.transform.localPosition.y / chain.bindpose.y ;
|
|
|
|
for (var j = 0; j < chain.drivenJoints.Count; j++)
|
|
{
|
|
var driven = chain.drivenJoints[j];
|
|
if (driven.IsValid())
|
|
{
|
|
driven.joint.localPosition = driven.bindpose + new float3(0f, stretchOffset * driven.strectchFactor, 0f);
|
|
var volumeScale = -driven.scaleFactor * stretchFactor + 1 + driven.scaleFactor;
|
|
driven.joint.localScale = new float3(volumeScale, 1f, volumeScale);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|