UE4で最近ゲームを作り始めたものです。
現状はプレイヤーが通過した床ブロックがプレイヤーカラーに変わるようなブループリントを組んだ状態です。これに付け足して同色で囲まれたブロックも色が変わるような仕組みをブループリントで組みたいと考えたのですが、情けないことにどのようにしたらうまくいくのか思いつかず煮詰まってしまいました。
説明が下手でうまく伝えられないのですが、キャプチャ画像の丸で印した箇所を動的?に検出する方法を考えています。
もしわかる方がいましたら御教授宜しくお願い致します。
UE4で最近ゲームを作り始めたものです。
現状はプレイヤーが通過した床ブロックがプレイヤーカラーに変わるようなブループリントを組んだ状態です。これに付け足して同色で囲まれたブロックも色が変わるような仕組みをブループリントで組みたいと考えたのですが、情けないことにどのようにしたらうまくいくのか思いつかず煮詰まってしまいました。
説明が下手でうまく伝えられないのですが、キャプチャ画像の丸で印した箇所を動的?に検出する方法を考えています。
もしわかる方がいましたら御教授宜しくお願い致します。
再起関数と呼ばれているペイントの塗りつぶしに使うアルゴリズムを使うと解決できると思います(`・ω・)ゞ
上下左右のマスの座標と色を取得し、
自分の色じゃなかったら次の上右下左マス
自分の色じゃなかったら次の上右下左マス
自分の色じゃなかったら次の上右下左マス
という動きを繰り返します。
この繰り返しを再起関数と言うらしいです。
範囲外に出た場合はすべてなかったことにします(´・ω・)
すべて自分の色で突き当たった場合はそれまでに取得したマスを
全部自分の色に変えます。
[BP]
・プレイヤーが踏んだ部分の色をプレイヤー固有の色に変更
・上右下左のマスを順番に色と座標を取得
(再起関数とは別に取得します)
・再起関数の実行
[再起関数内部]
→上右下左のマスを順番に色を取得
→マスの範囲外に突き当たった場合、再起関数の終了
→取得した色とプレイヤー固有の色、検索済み色を比較
・プレイヤー固有の色でも検索済みの色でもない場合、
取得できた座標を検索済み用配列と塗用配列へ保存
・マスを検索済み色に変更
→再起関数を再び実行
[関数終了]
・検索終了
・検索済み用配列から色を元のマスの色に変換
・範囲外に1度も突き当たらなかった場合、塗用配列を使い
プレイヤー固有色に塗り替えます。
(配列に何も入っていない場合は隣接マスをプレイヤー固有色に塗り替えます)
・配列の初期化
[BP終わりです]
関数内部で一度コンパイルをすることで自分自身(関数)を呼び出しできるようになります。
よくわからないところがあればコメントください
(*゚∀゚)ノシ
かなりトンチンカンなことをやってしまっているかもしれませんが、
マスの情報の取得の仕方が自分で思いつくかぎりで下図のような方法なのですが、
わざわざマス目のブロック一つ一つに情報を検出するためのアクターを常駐させなければならないことになってしまいます。
danteloさんんはどのように周りのマスの情報を取得させているのか教えていただけないでしょうか。
可能でしたら全体の流れや再帰関数のBPのスクリーンショットを数点掲載していただければ幸いです。
他力本願な申し出ばかりで不快な思いをさせてしまいましたら申し訳ありません。
マス目の色の管理には配列を使うのがいいと思います。
色を塗る時に配列にSETして、計算する時はそこからGETすれば、アクターをたくさん作らなくてよくなります。
配列にSETするデータは色で、
インデックスには、ブロックが100毎に並んでいるようなので、各ブロックのXとYを100で割ったものを使えば良さそうです。
縦と横の、2つのインデックスのある、2次元配列が作れると都合が良いのですが、
UE4には1次元配列しかないので、下記の記事などを参考にして応用が必要です。
http://katze.hatenablog.jp/entry/2016/06/25/144111
BP掲載の件、承知いたしました。
これとは別にいくつか質問させていただきたいのですが、
質問がたくさんになってしまい恐縮なのですが、お時間取れる際にでも御回答いただけたらと思います。よろしくお願いいたします。
全体BPの流れになります
プレイヤー1人の場合で作られていますので
検索色にプレイヤー固有色を混ぜる事や優先順位などの工夫が必要です(`・ω・´)ゞ
ブロックサイズを変更する可能性や特殊ブロックを置く場合があると思いましたので
座標受け渡しはタグを使っています。
Recursive 色を塗る関数
Paint 再起関数本体
Paint 再起関数本体の続きです。
ありがとうございます!
1.BPを組み込む場所はマス目となるブロックアクターのブループリントであってますでしょうか。
あってます!(`・ω・´)ゞ
恐らく変数を受け渡せばどこでも大丈夫ですが、わかりやすいところが良いと思います!
関数ライブラリーという機能を使うとどこでも関数呼び出しができるので便利です!
マクロライブラリーの方で再起関数を作るとクラッシュするので注意してください(; ・`д・´)・・・理由はワカリマセン・・・
2.再帰関数とは別に上下左右の座標と色を取得しなければならないのは何故でしょうか。
4方向の座標を取得しますが、画像のように青の方向に移動し色を塗った際に
1方向、緑色の→矢印の検索が範囲外となります。
このため緑色の←矢印が塗れるマスがあるにも関わらず、範囲外があるために
再起関数内部に組み込んだ場合すべてのマスが塗れなくなってしまうため、
このような方法をとっています(`・ω・´)ゞたぶんもっとスマートな方法があります!
3.配列に何も入ってない場合隣接マスをプレイヤー固有色にするのはなぜでしょうか。
2.の理由により、配列に何も入っていない状態になります。
よって配列に何も入っていない状態 かつ 範囲外に出なかった場合
1マス目を塗る必要があります(/・ω・)/
4.一つ前の質問の内容と被るのですがマス目ブロックの上下左右のマス目を検出する仕組みはどのようにしてますか。
上下左右マスの検出は単純です(`・ω・)ゞ
二次元配列の2つのindexの値を
上(Y+1),下(Y-1),左(X-1),右(X+1)のように座標を隣マスにズラしています!
5.配列は、ブロックアクターのブループリント内ではなく、配列を置いておく専用のブループリントのようなところに作った方がよいのでしょうか。
マス目のアクターで良いと思います。
さらに動的に配列変更が必要な場合は構造体とデータテーブルを使うと良いと思います!たぶん(´・ω・)
自分なりにBPを組んでみたのですが、
再帰関数内で上下左右の検索をSequenceノードで4つに分岐させていたり、
その分岐さきのそれぞれに再帰呼び出しをおいてしまっていたりと、
さんのBPとだいぶ違う感じになっていてエラーもでてしまいどうもうまくいきません(-.-
図々しいお願いなのですが、上記のBPで使用しているノードが確認できる大きさのスクリーンショットをWindowsのSnipping Toolなどを使って分割で撮っていただけないでしょうか。
詳細なところまでは公開できないなどの御都合や、何より手間を取らせてしまうことになるので難しい場合は構いません。
可能でしたらよろしくお願い致します。
BPでの2次元配列についてとても参考になりました。
ありがとうございました。
上記の記事を参考にBPで2次元配列を使うことができました。
有難うございました。
Sequenceノードは擬似的に並列処理を行うようなので、
マス検索が失敗している可能性があります(`・ω・)ゞ
そこで使う方向が4方向だけなので
ForLoopノードを使って方向を指定しています。
MassVector関数内部です。
進行する方向を決めています。
INT型の変数の場合はSwitchというBranchの複数版のようなノードが使えるので
便利です(/・ω・)/
上右下左と順番を決めているため、計算式も固定です(; ・`д・´)・・・
うまく動くようになりました!
最後まで丁寧に教えてくださいまして本当に有難うございました。