Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9707

Timeline(Playable Director)を複製した際にGameObjectのバインドがはずれてしまう。。

$
0
0
初めに プロジェクト Timeline(Playable Director)を複製した際にGameObjectのバインドがはずれてしまう。。 どんな現象かと言うと。 1.まず、適当にCubeが拡縮するアニメーション作ります。 2、同じようなシーンを作りたくて、シーンをコピーして複製したシーンを開きます。 3,複製元のTimeline(Playable Director)と同じになってしまうので、プロジェクトウィンドウでTimeline(Playable Director)も コピーし複製先のシーンのTimeline(Playable Director)にアタッチすると1,で作ったアニメーションのGameObjectのバインドが外れてしまう。 Unity Forumsで 解決 意外とあっさり、同じことで悩んでいる方がいて、解決しました。 seant_unityさんが対策のスクリプト書いてくれてますが、Timeline(Playable Director)の複製を作って、、HierarchyにTimeline(Playable Director)のCloneをつくり、同じパスにTimeline(Playable Director)のオブジェクトもCloneを作ってくれるものでした。 そのあと、書き込みでも動作しないとか書き込みがあるので、割と最近の投稿のRibさんの投稿を採用することしました。 こんな感じ やったのは、シーンを複製して複製先のシーンでTimeline(Playable Director)の複製を行っただけ スクリプト using System.Linq; using System.Reflection; using UnityEngine; using UnityEngine.Playables; using UnityEngine.Timeline; using UnityEditor; public class DuplicateTimeline : EditorWindow { [MenuItem("imeline/Duplicate Timeline", true)] private static bool DupTimelineValidate() { if (UnityEditor.Selection.activeObject as GameObject == null) { Debug.Log("Null active object"); return false; } GameObject playableDirectorObj = UnityEditor.Selection.activeObject as GameObject; PlayableDirector playableDirector = playableDirectorObj.GetComponent<PlayableDirector>(); if (playableDirector == null) { Debug.Log("Null playableDirector"); return false; } TimelineAsset timelineAsset = playableDirector.playableAsset as TimelineAsset; if (timelineAsset == null) { Debug.Log("Null timelineAsset"); return false; } string path = AssetDatabase.GetAssetPath(timelineAsset); if (string.IsNullOrEmpty(path)) { Debug.Log("Null timeline asset path"); return false; } return true; } [MenuItem("Timeline/Duplicate Timeline")] public static void DupTimeline() { // 再生可能なディレクターを取得し、タイムラインを取得します GameObject playableDirectorObj = UnityEditor.Selection.activeObject as GameObject; PlayableDirector playableDirector = playableDirectorObj.GetComponent<PlayableDirector>(); TimelineAsset timelineAsset = playableDirector.playableAsset as TimelineAsset; // 複製 string path = AssetDatabase.GetAssetPath(timelineAsset); string newPath = path.Replace(".", "(Clone)."); if (!AssetDatabase.CopyAsset(path, newPath)) { Debug.LogError("Couldn't Clone Asset"); return; } // バインディングのコピー TimelineAsset newTimelineAsset = AssetDatabase.LoadMainAssetAtPath(newPath) as TimelineAsset; PlayableBinding[] oldBindings = timelineAsset.outputs.ToArray(); PlayableBinding[] newBindings = newTimelineAsset.outputs.ToArray(); for (int i = 0; i < oldBindings.Length; i++) { playableDirector.playableAsset = timelineAsset; Object boundTo = playableDirector.GetGenericBinding(oldBindings[i].sourceObject); playableDirector.playableAsset = newTimelineAsset; playableDirector.SetGenericBinding(newBindings[i].sourceObject, boundTo); } // 公開された参照をコピーする playableDirector.playableAsset = newTimelineAsset; foreach (TrackAsset newTrackAsset in newTimelineAsset.GetRootTracks()) { foreach (TimelineClip newClip in newTrackAsset.GetClips()) { foreach (FieldInfo fieldInfo in newClip.asset.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { if (fieldInfo.FieldType.IsGenericType && fieldInfo.FieldType.GetGenericTypeDefinition() == typeof(ExposedReference<>)) { // 古い公開名を取得する object exposedReference = fieldInfo.GetValue(newClip.asset); PropertyName oldExposedName = (PropertyName)fieldInfo.FieldType .GetField("exposedName") .GetValue(exposedReference); bool isValid; // 古い公開値を取得する Object oldExposedValue = playableDirector.GetReferenceValue(oldExposedName, out isValid); if (!isValid) { Debug.LogError("Failed to copy exposed references to duplicate timeline. Could not find: " + oldExposedName); return; } // 構造体のexposedNameを置き換えます PropertyName newExposedName = new PropertyName(UnityEditor.GUID.Generate().ToString()); fieldInfo.FieldType .GetField("exposedName") .SetValue(exposedReference, newExposedName); // ExposedReferenceを設定します fieldInfo.SetValue(newClip.asset, exposedReference); // PlayableDirectorのリファレンスを設定する playableDirector.SetReferenceValue(newExposedName, oldExposedValue); } } } } } } 最後に もし、こんな事しなくても出来るとか、オペレーションで回避出来ると言う話であれば、どなたか教えて下さい。 要望とか多いので、ツールやら、Unityのエディタ拡張が最近多いな。。

Viewing all articles
Browse latest Browse all 9707

Trending Articles