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

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

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

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

1回答

565閲覧

Unity-Chan The Phantom KnowledgeのプロジェクトをUnity2018.2で開くと出る cannot override inherited member のエラーの対処法

matsu_vr

総合スコア6

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2018/08/10 17:01

編集2018/08/12 02:45

前提・実現したいこと

タイムラインの動作を知りたいと思ったため、ユニティ・テクノロジーズ・ジャパンから配布されているUnity-Chan The Phantom Knowledgeのプロジェクト(本来はUnity2017向け)をUnity2018.2で開くとエラーが出ます。

Unity2018.2でタイムラインを使いたいと思って学習を始めたので、このプロジェクトを2018.2.1で動かしたいと思っています。

発生している問題・エラーメッセージ

2か所同じ内容のエラーが出ます。

Assets/MovieProxy/Scripts/Tracks/MovieProxy/MovieProxyTrack.cs(22,37): error CS0506: `UTJTimelineUtil.MovieProxyTrack.CreatePlayable(UnityEngine.Playables.PlayableGraph, UnityEngine.GameObject, UnityEngine.Timeline.TimelineClip)': cannot override inherited member `UnityEngine.Timeline.TrackAsset.CreatePlayable(UnityEngine.Playables.PlayableGraph, UnityEngine.GameObject, UnityEngine.Timeline.TimelineClip)' because it is not marked virtual, abstract or override
Assets/MovieProxy/Scripts/Tracks/Fader/FaderTrack.cs(19,37): error CS0506: `UTJTimelineUtil.FaderTrack.CreatePlayable(UnityEngine.Playables.PlayableGraph, UnityEngine.GameObject, UnityEngine.Timeline.TimelineClip)': cannot override inherited member `UnityEngine.Timeline.TrackAsset.CreatePlayable(UnityEngine.Playables.PlayableGraph, UnityEngine.GameObject, UnityEngine.Timeline.TimelineClip)' because it is not marked virtual, abstract or override

おそらく、Unity2017と2018とで、CreatePlayableの挙動が変わったんじゃないかと思っているのですが、普段はほとんどスクリプトを書かない立場なので途方に暮れております。

該当のソースコード

前者の全体のソースを貼ります。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.Playables; 5using UnityEngine.Timeline; 6namespace UTJTimelineUtil 7{ 8 [TrackClipType(typeof(MovieProxyPlayableAsset))] 9 [TrackBindingType(typeof(MovieProxyNativeRenderer))] 10 [TrackMediaType(TimelineAsset.MediaType.Script)] 11 [TrackColor(0.776f, 0.263f, 0.09f)] 12 public class MovieProxyTrack : TrackAsset 13 { 14 LoaderPeriodicJob m_LoaderPeriodicJob; 15 public MovieProxyTrack() 16 { 17 Util.Log("MovieProxyTrack creating ObserverPeriodicJob"); 18 m_LoaderPeriodicJob = new LoaderPeriodicJob(this); 19 m_LoaderPeriodicJob.AddToUpdateManger(); 20 // above job is removed when finished to load by calling RemoveIfFinished(); 21 } 22 protected override Playable CreatePlayable(PlayableGraph graph, GameObject go, TimelineClip clip) 23 { 24 var playable = (ScriptPlayable<MovieProxyPlayableBehaviour>)base.CreatePlayable(graph, go, clip); 25 var myBehaviour = playable.GetBehaviour() as MovieProxyPlayableBehaviour; 26 myBehaviour.m_clip = clip; 27 return playable; 28 } 29 30 public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount) 31 { 32 var mixer = ScriptPlayable<MovieProxyPlayableMixer>.Create(graph, inputCount); 33 var director = go.GetComponent<PlayableDirector>(); 34 if (director != null) 35 { 36 var outputGo = director.GetGenericBinding(this) as MovieProxyNativeRenderer; 37 MovieProxyPlayableMixer bh = mixer.GetBehaviour(); 38 if (outputGo != null) 39 { 40 bh.boundGameObject = outputGo.gameObject; 41 } 42 bh.m_PlayableDirector = director; 43 44 } 45 return mixer; 46 } 47 48 } 49 50}

試したこと

現状ではお手上げです。

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

Unity2018.2.1
Windows 10 Home(64bit)

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

すみませんが、Playables APIの仕組みについては勉強不足で、なんちゃらAssetだのBehaviourだのの各オブジェクトがどのような相互関係にあるのか、どう組み合わせてやるのがベストなのかまるで理解しないままいじっておりますので、あくまでもご参考程度でお願いします。

一応再生できるところまではいったものの、私の試した環境(Unity 2018.2.2f1、Windows 10 Home バージョン1803)では、画面上にCanvasを使って描いているとおぼしきアニメーションがまるで動作せず、煙や火花などのエフェクトが動かないという状態でした。メインマシンが諸般の事情で使用できず、ReadMeに記載されている推奨スペックをまるで満たしていないラップトップマシンでの実験だったことも、もしかすると関係があるのかもしれません。
タイムラインの動作を知る参考にはなりそうですが、せっかくの立派な作品がちゃんと鑑賞できなかったのは残念です...

より有用そうな情報が見つかったら、あるいはThe Phantom Knowledgeが現行バージョン向けにアップデートされたら、そちらをご覧いただくのがいいかと思います。

TrackAssetのCreatePlayableはPlayable.Nullとかいうダミーらしきプレイアブルを作るようにオーバーライドされていて、しかもsealed指定されており、TrackAssetにおいてはCreatePlayableは意味のある役割は果たしていない様子です。
FadePlayableBehaviourあるいはMovieProxyPlayableBehaviourに対して、別の手段でTimelineClipを渡してやる必要がありそうです。
PlayableBehaviourからTimelineClipにアクセスする手はないものかと検索してみたところ、How to access the clip timing (start, end time) in PlayableBehaviour functions - Unity ForumHow to get the TimelineClip for a PlayableBehaviour? - Unity Forumといった質問が見つかりました。
寄せられた回答によれば、TimelineClipにアクセスする手段はないとのことです。しかし、TrackAssetのCreateTrackMixer内でそのトラックに含まれるクリップを列挙することが可能であり、これはクリップのプレイアブル生成よりも先行するとのことでした。

そこで、

  • PlayableAssetにTimelineClipを格納するためのフィールドm_clipを追加する。

CreatePlayableでは、PlayableBehaviour生成時に自身のm_clipを渡してやることにする。

  • TrackAssetのCreateTrackMixer内で全クリップを列挙する。クリップと対応するPlayableAssetはassetプロパティから得られるので、そのm_clipにクリップを代入する。

この代入はプレイアブル生成よりも先行するので、PlayableBehaviourはnullでないクリップを受け取ることができるはず...?

ともくろみました。

PlayableAssetを下記のように変更し...

Assets/MovieProxy/Scripts/Tracks/Fader/FaderPlayableAsset.cs

C#

1// 省略 2 3namespace UTJTimelineUtil 4{ 5 [System.Serializable] 6 7 public class FaderPlayableAsset : PlayableAsset, ITimelineClipAsset 8 { 9 public Color m_color = Color.black; 10 public bool m_noFade = false; 11 public FadeType m_type = FadeType.FadeIn; 12 public TimelineClip m_clip; // クリップへの参照を保持するフィールドを追加 13 14 public ClipCaps clipCaps 15 { 16 get 17 { 18 return ClipCaps.None; 19 } 20 } 21 22 public override Playable CreatePlayable(PlayableGraph graph, GameObject go) 23 { 24 var bh = new FaderPlayableBehaviour 25 { 26 m_clip = this.m_clip // PlayableBehaviourにクリップを伝達 27 }; 28 return ScriptPlayable<FaderPlayableBehaviour>.Create(graph, bh); 29 } 30 31 } 32 33 public enum FadeType 34 { 35 FadeIn, 36 FadeOut 37 } 38}

Assets/MovieProxy/Scripts/Tracks/MovieProxy/MovieProxyPlayableAsset.cs

C#

1// 省略 2 3namespace UTJTimelineUtil 4{ 5 [System.Serializable] 6 public class MovieProxyPlayableAsset : PlayableAsset, ITimelineClipAsset 7 { 8 [System.Serializable] 9 public struct StPicResolution 10 { 11 public int Width; 12 public int Height; 13 }; 14 public int Version; 15 public MovieProxyPlayableAssetParam.StPicResolution Resolution; 16 public string Folder; 17 public string[] Pictures; 18 private bool[] LoadRequested; 19 public int m_loadingIndex = -1; 20 private int m_sLastIndex = -1; 21 public TimelineClip m_clip; // クリップへの参照を保持するフィールドを追加 22 23 // 省略 24 25 // Factory method that generates a playable based on this asset 26 public override Playable CreatePlayable(PlayableGraph graph, GameObject go) 27 { 28 var bh = new MovieProxyPlayableBehaviour 29 { 30 m_clip = this.m_clip // PlayableBehaviourにクリップを伝達 31 }; 32 return ScriptPlayable<MovieProxyPlayableBehaviour>.Create(graph, bh); 33 } 34 35 // 省略 36 37 } 38 39 // 省略 40 41}

TrackAssetは下記のように変更しました。

Assets/MovieProxy/Scripts/Tracks/Fader/FaderTrack.cs

C#

1// 省略 2 3namespace UTJTimelineUtil 4{ 5 [TrackClipType(typeof(FaderPlayableAsset))] 6 [TrackBindingType(typeof(Image))] 7 [TrackMediaType(TimelineAsset.MediaType.Script)] 8 [TrackColor(0.263f, 0.09f, 0.263f)] 9 public class FaderTrack : TrackAsset 10 { 11 // CreatePlayableは削除 12 13 public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount) 14 { 15 // ミキサー生成前に、まずこのトラック上の全クリップを列挙し、それと対応するプレイアブルアセットにクリップの参照を伝達する 16 foreach (var clip in this.GetClips()) 17 { 18 (clip.asset as FaderPlayableAsset).m_clip = clip; 19 } 20 21 var mixer = ScriptPlayable<FaderPlayableMixer>.Create(graph, inputCount); 22 var director = go.GetComponent<PlayableDirector>(); 23 if ( director != null ) 24 { 25 var outputGo = director.GetGenericBinding(this) as Image; 26 FaderPlayableMixer bh = mixer.GetBehaviour(); 27 if ( outputGo != null ) 28 { 29 bh.boundGameObject = outputGo.gameObject; 30 bh.m_initialColor = outputGo.color; 31 } 32 bh.m_PlayableDirector = director; 33 } 34 return mixer; 35 } 36 } 37}

Assets/MovieProxy/Scripts/Tracks/MovieProxy/MovieProxyTrack.cs

C#

1// 省略 2 3namespace UTJTimelineUtil 4{ 5 [TrackClipType(typeof(MovieProxyPlayableAsset))] 6 [TrackBindingType(typeof(MovieProxyNativeRenderer))] 7 [TrackMediaType(TimelineAsset.MediaType.Script)] 8 [TrackColor(0.776f, 0.263f, 0.09f)] 9 public class MovieProxyTrack : TrackAsset 10 { 11 LoaderPeriodicJob m_LoaderPeriodicJob; 12 public MovieProxyTrack() 13 { 14 Util.Log("MovieProxyTrack creating ObserverPeriodicJob"); 15 m_LoaderPeriodicJob = new LoaderPeriodicJob(this); 16 m_LoaderPeriodicJob.AddToUpdateManger(); 17 // above job is removed when finished to load by calling RemoveIfFinished(); 18 } 19 20 // CreatePlayableは削除 21 22 public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount) 23 { 24 // ミキサー生成前に、まずこのトラック上の全クリップを列挙し、それと対応するプレイアブルアセットにクリップの参照を伝達する 25 foreach (var clip in this.GetClips()) 26 { 27 (clip.asset as MovieProxyPlayableAsset).m_clip = clip; 28 } 29 30 var mixer = ScriptPlayable<MovieProxyPlayableMixer>.Create(graph, inputCount); 31 var director = go.GetComponent<PlayableDirector>(); 32 if (director != null) 33 { 34 var outputGo = director.GetGenericBinding(this) as MovieProxyNativeRenderer; 35 MovieProxyPlayableMixer bh = mixer.GetBehaviour(); 36 if (outputGo != null) 37 { 38 bh.boundGameObject = outputGo.gameObject; 39 } 40 bh.m_PlayableDirector = director; 41 42 } 43 return mixer; 44 } 45 } 46}

さらに、UpdateManagerがタイムラインやグループトラックの子トラックを取得するのに失敗、および現在のPlayableDirectorを取得するのに失敗するらしく、大量のNull参照例外を発生させるので、ここにも変更を加えました。
ただしこれも動作を十分に追った上での修正ではなく不確実です...

Assets/MovieProxy/Scripts/UpdateManager.cs

C#

1// 省略 2 3namespace UTJTimelineUtil 4{ 5 6#if UNITY_EDITOR 7 [InitializeOnLoad] 8#endif 9 public class UpdateManager 10 { 11 12 // 省略 13 14 static public PlayableDirector GetCurrentDirector() 15 { 16 EditorWindow timelineWindow = UpdateManager.GetTimelineWindow(); 17 18 if (timelineWindow == null) 19 { 20 return null; 21 } 22 var bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField; 23 var type = timelineWindow.GetType(); 24 var info = type.GetProperty("state", bf); 25 var val = info.GetValue(timelineWindow, null); 26 27 // プロパティ名や場所が変わったみたいなので修正 28 type = val.GetType(); 29 info = type.GetProperty("editSequence", bf); 30 val = info.GetValue(val, null); 31 type = val.GetType(); 32 info = type.GetProperty("director", bf); 33 val = info.GetValue(val, null); 34 35 return val as PlayableDirector; 36 } 37 38 // 省略 39 40 static public List<TrackAsset> GetTrackList(TimelineAsset timelineAsset) 41 { 42 // TimelineAssetに関する子トラック取得の方法を変更 43 return timelineAsset.GetRootTracks().ToList(); 44 } 45 46 static public List<TrackAsset> GetTrackList(GroupTrack groupTrack) 47 { 48 // GroupTrackに関する子トラック取得の方法を変更 49 return groupTrack.GetChildTracks().ToList(); 50 } 51 52 // 省略 53 } 54 55 // 省略 56}

投稿字数削減のため、変更のない部分をだいぶ省略しています。ご容赦ください...

投稿2018/08/13 10:00

Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

アカウントをお持ちの方は

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問