У меня есть модель лица с 12 blendshape, где каждая blendshape - это просто список значений с плавающей точкой между 0 (нейтральное выражение лица) и 1 (максимальное активированное выражение), но яначиная только с первых 2 смешанных форм;т.е. только два списка на данный момент, скажем, улыбка и скептический взгляд.
Мое намерение состоит в том, чтобы просмотреть все возможные комбинации всех элементов в этих двух списках и сделать кадры (мувиклип) движений лица,чтобы показать, как выглядят все возможные комбинации значений / весов blendshape.
Итак, я написал следующее, чтобы упростить этот сценарий только для двух blendshapes, и сохраню их в файл, как только приложение закроется.:
public class BlendShapesVAL : MonoBehaviour
{
private List<float> _weightValues_Preset1_smile = new List<float>();
private List<float> _weightValues_Preset2_skeptic = new List<float>();
public bool _TransitionAnimation = true;
public float _TransitionAnimationSpeed = 2f;
public BlendShapesPresetController _BSPC;
private List<float> _weightsList = new List<float>();
public List<bool> _ActivationsList = new List<bool>();
public List<string> _PresetsNamesList = new List<string>();
private void Awake()
{
_weightsList.Clear();
_ActivationsList.Clear();
for (int i = 0; i < _PresetsNamesList.Count; ++i)
{
_ActivationsList.Add(false);
_weightsList.Add(0);
}
}
private void Start()
{
if (_BSPC != null)
{
// . . .
}
else
{
_BSPC = GetComponent<BlendShapesPresetController>();
}
StartCoroutine("Interpolate");
}
/// <summary>
/// Writes (i.e. saves) blendshape values to file when the application quits.
/// </summary>
///
private void OnApplicationQuit()
{
SaveBlendShapesValues(_weightValues_Preset1_smile);
SaveBlendShapesValues(_weightValues_Preset2_skeptic);
PlayerPrefs.DeleteAll();
}
/// <summary>
/// Goes thorugh all the possible combinations of blendshape weights.
/// For now, only the first two though!
/// </summary>
///
private IEnumerator Interpolate()
{
for (int i = 0; i <= 100; i++)
{
float weightValuesmile = (float)i / 100.0f;
_BSPC.SetWeight("Preset1_smile", weightValuesmile);
_weightValues_Preset1_smile.Add(weightValuesmile);
for (int j = 0; j <= 100; j++)
{
float weightValueSkeptic = (float)j / 100.0f;
_BSPC.SetWeight("Preset2_skeptic", weightValueSkeptic);
_weightValues_Preset2_skeptic.Add(weightValueSkeptic);
}
yield return null;
}
}
/// <summary>
/// Writes (i.e. saves) blendshape values to file.
/// <param name="blendShapesValuesFilePath">
/// The path to the file that will store the list of float values;
/// i.e. "Application.dataPath" plus the name of the CSV file.
/// </param>
/// <param name="values">
/// The float values that are the blendshape weights.
/// </param>
/// </summary>
///
private static void SaveBlendShapesValues(List<float> values)
{
List<string> lines = new List<string>
{
/// Add a header row for the labels.
"TimeStamp,Preset1_smile,Preset2_skeptic"
};
foreach (var value in values)
{
/// Iterate through all the elements.
lines.Add(DateTime.Now + "," + value);
}
/// Load the old counter.
int counter = PlayerPrefs.GetInt("_counter_", 0);
/// Concatenate the file name constituents and combine it with the application data path.
string fileName = string.Format("BlendShapesValues_{0}.csv", counter.ToString() );
string tempPath = Path.Combine(Application.dataPath, fileName);
try
{
File.WriteAllLines(tempPath, lines.ToArray() );
Debug.Log("Saved blendshape weight values to: " + tempPath);
/// Increment the counter.
counter++;
/// Save the current counter.
PlayerPrefs.SetInt("_counter_", counter);
PlayerPrefs.Save();
}
catch (Exception e)
{
Debug.LogWarning("Failed to save to PlayerPrefs: " + tempPath);
Debug.LogWarning("Error: " + e.Message);
}
}
}
В редакторе Unity смешанные формы отображаются со значениями от 0 до 100, поэтому мое преобразование в коде, как показано на снимке экрана:
Первый файл имеет значения 101 (0 ... 100 плюс верхняя строка для меток столбцов), на этом скриншоте можно увидеть фрагмент:
Второй файл имеет значения 10201 .Мой первый вопрос - является ли этот метод сохранения повторяющихся значений в файл после остановки приложения хорошим решением, учитывая значительный рост значений при добавлении новых списков (т. Е. Blendshapes)?
Мой Второй вопрос - как я могу замедлить итерации, потому что (на первом скриншоте) значения улыбки начинают отсчитываться от 0 до 100, и я вижу их (лицо медленно перемещается в видимомно, как это происходит, я замечаю, что второй список (скептик), по-видимому, сразу переходит на 100, так что это делается так быстро, что он не может быть записан устройством записи экрана Win ...