スクリプトをヒエラルキーにドラッグアンドドロップしてゲームオブジェクトが作られるようにする

ヒエラルキーにスクリプトをドラッグアンドドロップしたら、そのスクリプトがアタッチされたゲームオブジェクトがヒエラルキーにできると思っていたことがありました。それはプレハブをドラッグアンドドロップするとそのコピーができることからそんな勘違いをしていたのです。
そうなっていてほしいことがそうなっていないので、Unityを使っていて長い間不満でした。それでどうにかできないかと思っていたので、今回なんとかしてみました。スクリプトはC#のみ対象です。BooやJavaScriptの方は型の情報が取れなかったので、やめました。といってもC#がメインでしょうからあまり関係ありません。

以上のようにMonoBehaviourを継承していようが、継承していなくても関係なくスクリプトをヒエラルキーにドラッグアンドドロップしても何も起こりません。これはUnityの通常の挙動です。
MonoBehaviourを継承したクラスはゲームオブジェクトにアタッチできますから、MonoBehaviourを継承したクラスのスクリプトをヒエラルキーにドラッグアンドドロップしたら、新しいゲームオブジェクトをヒエラルキーに作成しそのスクリプトをアタッチするというように変更したいと思います。

できたものの動作は以下のようになりました。
MonoBehaviourを継承したスクリプトのみ反応して、ゲームオブジェクトが作られています。(partialを使った場合は、クラス名と一致するスクリプトのときだけ反応します。)

これをどうやって作ったかは結構難しい話になると思います。まず参考にしたサイトがいくつかあるのでそれを挙げておきます。
Unity5 HierarchyにC#スクリプトをドラッグ&ドロップできるようにするエディター拡張
Create GameObjects/Components by Dragging Assets to Hierarchy/Inspector
の2つです。特に前者の方の目的はやりたかったことそのままと言ってもいいです。じゃあわざわざ作る必要があったのかとなりますが、うまく動かなかったので自分で作ることにしました。

以下に作ったコードを載せておきます。現在、私が使っているUnityのバージョンは5.3.1f1 Personalです。これで動くことは確認しています。使い方は、UnityのプロジェクトにEditorフォルダを作りそこにこのスクリプトDropScript.csを置けば使えます。
ログに”DropScript AutoStart”と出れば読み込みが完了しています。

#if~#endifの部分は手動でこの拡張機能をON/OFFするためのものです。使いたい場合は適当なdefineを入れてください。
重要なのはリフレクションを使って型の情報を取っている部分です。(Unity4だったら、名前でAddComponentできるので、それにclassNameを渡すだけで良いです。)Types.GetTypeという部分がドキュメントには載っていないので、使い方が正しいか微妙です。
ドラッグのイベントは何度も呼ばれてしまうので、boolフラグで一度だけ呼び出されるように対処しています。

完成したものは十分に要件を満たしていますが、いくつかの欠点があります。もう少し改善すると注意せずに誰でも使えるものになりますが、ちょっと無理そうなのでそれはしません。

  • ヒエラルキーにゲームオブジェクトがひとつもないと反応しない
  • スクリプトをドラッグしたままヒエラルキーを横切るとゲームオブジェクトができてしまう
  • スクリプトをドラッグしてゲームオブジェクトにアタッチすると、ついでにゲームオブジェクトができてしまう
1つ目はEditorApplication.hierarchyWindowItemOnGUIがヒエラルキーにあるゲームオブジェクトから呼ばれているようなので、他の判定方法がないと改善できません。よって、これはどうしようもないと……

2つ目はドラッグ中にヒエラルキーのウィンドウ外に出ることをドロップと判定されているようなので、おそらくどうよもないです。
3つ目は個人的に結構大きな問題と考えています。ドラッグでのアタッチをやめてボタンからコンポーネントをつければ競合しないですが、気をつけないと知らずに不要なものができてしまうので問題です。
まあ何らかの方法で対応できるかもしれませんが、これを使うとこんな感じのこともできるのでこのままの方が使えると思っています。ヒエラルキーをまたぐように行ったり来たりして大量のゲームオブジェクトを作っています。

これすごく便利だと思うので、Unityの公式の機能としていずれ追加してほしいです。

コメント

タイトルとURLをコピーしました