質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

解決済

Rotationのキーリダクションが正しく行われない

flame_mori
flame_mori

総合スコア12

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

1回答

0リアクション

0クリップ

170閲覧

投稿2022/08/18 04:41

編集2022/08/19 00:37

前提

アニメーションのキーリダクションを行うスクリプトを作っているのですが、以下のコードでキーリダクションを行うと、Rotationだけ正しく行われません。
正確には、xはうまくいっているのですが、y、zは一部の値が変わってしまっているようです。

キーリダクション前:
イメージ説明

キーリダクション後:
イメージ説明

スクリーンショットで使用したanimファイル

実現したいこと

Rotationのキーリダクションが正しく動作する

該当のソースコード

c#

using System.IO; using System.Linq; using UnityEngine; using UnityEditor; using System.Collections.Generic; using System; public class KeyReductionTest : AssetPostprocessor { [MenuItem("Assets/Key Reduction Test")] static void KeyReduction() { Debug.Log("Key Reduction Test..."); foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(AnimationClip), SelectionMode.Editable)) { string path = AssetDatabase.GetAssetPath(obj); AnimationClip anim_clip = (AnimationClip)AssetDatabase.LoadAssetAtPath(path, typeof(AnimationClip)); foreach (var binding in AnimationUtility.GetCurveBindings(anim_clip).ToArray()) { AnimationCurve curve = AnimationUtility.GetEditorCurve(anim_clip, binding); AnimationCurveKeyReduction(curve, binding.propertyName, 0.001f); AnimationUtility.SetEditorCurve(anim_clip, binding, curve); } string anim_clip_name = Path.GetDirectoryName(path) + "/" + Path.GetFileNameWithoutExtension(path); WriteAnimationCurve(anim_clip, anim_clip_name); } } static private void WriteAnimationCurve(AnimationClip anim_clip, string anim_clip_name) { string tmp_name = anim_clip_name + "_tmp.anim"; var copyClip = UnityEngine.Object.Instantiate(anim_clip); AssetDatabase.CreateAsset(copyClip, tmp_name); FileUtil.ReplaceFile(tmp_name, anim_clip_name + ".anim"); AssetDatabase.DeleteAsset(tmp_name); AssetDatabase.Refresh(); } static private float GetValueFromTime(Keyframe key1, Keyframe key2, float time) { float t; float a, b, c; float kd, vd; if (key1.outTangent == Mathf.Infinity) return key1.value; kd = key2.time - key1.time; vd = key2.value - key1.value; t = (time - key1.time) / kd; a = -2 * vd + kd * (key1.outTangent + key2.inTangent); b = 3 * vd - kd * (2 * key1.outTangent + key2.inTangent); c = kd * key1.outTangent; return key1.value + t * (t * (a * t + b) + c); } static private bool IsInterpolationValue(Keyframe key1, Keyframe key2, Keyframe comp, float eps) { var val1 = GetValueFromTime(key1, key2, comp.time); if (eps < System.Math.Abs(comp.value - val1)) return false; var time = key1.time + (comp.time - key1.time) * 0.5f; val1 = GetValueFromTime(key1, comp, time); var val2 = GetValueFromTime(key1, key2, time); return (System.Math.Abs(val2 - val1) <= eps) ? true : false; } static public IEnumerable<int> GetDeleteKeyIndex(Keyframe[] keys, float eps) { for (int s_idx = 0, i = 1; i < keys.Length - 1; i++) { if (IsInterpolationValue(keys[s_idx], keys[i + 1], keys[i], eps)) { yield return i; } else { s_idx = i; } } } static public void AnimationCurveKeyReduction(AnimationCurve in_curve, string propertyName, float eps = 0.0001f) { if (in_curve.keys.Length <= 2) return; var del_indexes = GetDeleteKeyIndex(in_curve.keys, eps).ToArray(); foreach (var del_idx in del_indexes.Reverse()) in_curve.RemoveKey(del_idx); } }

補足情報(FW/ツールのバージョンなど)

Unity 2020.3.19f1

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

Bongo

2022/08/18 21:44

Animationビュー上のSpotLightBase_B_y_03 : Rotationを右クリックするとコンテキストメニュー上に「Interpolation」という項目があるかと思いますが、それの設定はどうなっているでしょうかね(https://docs.unity3d.com/ja/2020.3/Manual/animeditor-AnimationCurves.html#:~:text=%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82-,%E5%9B%9E%E8%BB%A2%E3%81%AE%E8%A3%9C%E9%96%93%E6%96%B9%E6%B3%95%E3%81%AE%E7%A8%AE%E9%A1%9E,-Unity%20%E3%81%A7%E3%81%AF%E5%9B%9E%E8%BB%A2 )? あれが「Quaternion」だと、Animationビュー上では回転がオイラー角で表示されていても、内部的にはQuaternion方式でデータが保存されるようです。スクリーンショットを拝見しますにX軸回転90°付近で特にズレが大きくなっているように見えますが、もしかするとQuaternionからAnimationビュー上のオイラー角へ変換する際に起こる致し方ない現象なのかもしれませんね。Animationビュー上の見た目が少々おかしくても、実際にアニメーションを再生したときに不自然な動きがないようでしたらお気になさる必要はないかもしれません。 キーリダクション前のアニメーションクリップファイルをどこかにアップロードしていただくことは可能でしょうか?それがあれば挙動を調べやすくなるんじゃないかと思います。
flame_mori

2022/08/19 00:39

キーリダクション前のアニメーションクリップファイルをアップロードしましたので、本文にリンクを追加しました。 スクリーンショットのすぐ下に追加しています。 「Interpolation」の設定ですが「Quaternion」になっていることを確認しました。
flame_mori

2022/08/19 01:05

「Interpolation」を「Euler Angles」に変更してキーリダクションを行ったところ、正しく動くことを確認できました。 ご協力ありがとうございました。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。