妹でもわかるUnrealEngine4

毎日更新? 妹に説明するために書いてるけど、たまにわかってない場合もあるUnrealEngine4を中心としたゲーム制作の話。略すとイモリアル

毎日更新? 妹に説明するために書いてるけど、たまにわかってない場合もあるUnrealEngine4を中心としたゲーム制作の話。略すとイモリアル

3Dウィジェットと普通のウィジェットが重なった場合の追加実験

f:id:una_unagi:20171016234211p:plain

「昨日のウィジェットの重なりでちょっと気になることがあって試してたんだけど、設定がWorldだったら、操作判定のある普通のウィジェットに隠れてても、普通に押せるということがわかった。ボタンもカーソルのホバーに反応する」

妹「Worldっていうのは、3Dの中にあって、マテリアルとか使える方だっけ」

「そう。で、Screenの方は完全に無効化されてる。隠れてる部分では、カーソルを合わせてもボタンが反応しないし、クリック以外の方法で反応させようとしても駄目だった」

f:id:una_unagi:20171016234117p:plain

ウィジェットのせいでクリックイベントが取れてないのかなと思ったら、そういうわけじゃなかった。クリック自体には反応してるけど、WidgetInterectionが、そこにはウィジェットがないと判断してる」

妹「普通のウィジェットと同じ仕組みだから?」

「たぶんそうなんだと思う。普通のウィジェットも、ウィジェット同士で重なってる部分は操作不能だから」

3Dウィジェットが物陰に隠れている場合の判定

f:id:una_unagi:20171015223118p:plain

「3Dウィジェットは3D空間にあるわけで、とうぜん隠れたりしてよく見えない場合がある。これの判定はどうなってるんだろうと思って調べた」

f:id:una_unagi:20171015223128p:plain

「基本的にレイを飛ばして物体を探す仕組みと同じで、レイがウィジェットに届いたかどうかで、押せるかどうかが決まる。今回はマウスカーソルで操作しようとしてるから、カメラからマウスカーソルの奥に向かってレイを飛ばす感じだと思う」

妹「じゃあ途中に物があると押せないの?」

コリジョンが小さいと、見えてないけど押せたりするけどね。レイの判定はコリジョンでやるから。逆に大きいと見えてるのに押せなかったり。あと一部がコリジョンに隠れてても、それ以外の場所は押せる」

妹「じゃあ半透明でもコリジョンあったら駄目なんだ」

「操作出来た方がいい場合は、途中にある物体のコリジョンプリセットとかを調整する。例えばVisibilityをオフするとか。他に悪影響があると困るから、真面目にやるなら専用のトレースチャンネルとか作った方がいいだろうけど」

f:id:una_unagi:20171015223147p:plain

「さっきのはWorldモードで、こっちはScreenモード。普通にウィジェットをAddViewportした場合は、普通のが手前に来るらしい。ZOrderとかそれっぽい変数があるんだけど、数字を変えても効果が見られなかった」

妹「他のウィジェットに隠れてるボタンはどうなるの? ウィジェットコリジョンはないと思うけど」

「これは手前のウィジェットが優先されて、クリック可能なウィジェットが手前にあるとそれに邪魔される。SetInputModeGameOnlyにしててもそうなる

f:id:una_unagi:20171015225326p:plain

妹「ウィジェット同士が重なったら?」

「それも手前優先。3Dウィジェット同士で重なっても、手前になんかあると、奥のやつは押せなくなる」

複数のPawnが同じ入力イベントを受け取ることはできない(Actorならできる)

「AnswerHubの質問に答えてて気づいたんだけど、複数のポーン(Pawn)で入力を受け取るっていうのが出来ないっぽい」

妹「あれ? 昔そういうのやってなかったっけ……」

「それは全部複数のActorが入力を受け取る方法だったんだよ。Pawnではなくて

imoue.hatenablog.com

imoue.hatenablog.com

「今までやって上手くいってたのは、対象のPawnやCharacterが1つしかない場合だけだった。PawnだとAutoReceiveInput設定も、EnableIn
putノードも効かない

妹「え、でもPawnっていうのは、Actorクラスを継承してるんだから、PawnもActorの一種なんじゃないの?

「まあそうなんだけど、でも継承してるってことで確実なのは、親クラスと同じパラメータを持っているってとこまでで、それが同じパラメータが同じ動作をするとは限らないんだよ。動作を上書きできるから」

妹「詐欺なのでは」

「極端な場合だと、どのパラメータに何を入れても何の意味のクラスだって作れる。わかりにくいだけだから普通はやらないけど」

f:id:una_unagi:20171014224400p:plain

「Pawnの場合、AutoPossessPlayerで設定するか、EnableInputの代わりにPossessノードで設定すると、入力イベントのノードが動くようになる。あとPlayerStartからスポーンされた場合も」

imoue.hatenablog.com

「ただ、あるポーンを有効にすると、他のポーンでは無効になるから、同時に1つしか操作できない」

妹「なんで1個だけなんだろ?」

「Possessっていうのは所有って意味の英語で、プレイヤーが所有できるポーンは1つという風に決まってるらしい。GetPlayerPawnもそういう前提だし」

妹「GetPlayerPawnじゃないけど、ただ操作できるだけのPawnだったら問題はないのでは?」

「ややこしくなるし、不必要だから禁止してるんだと思う。複数のPawnを操作するにしても、操作用のブループリントをPawnに書く必要はないし」

妹「意味ないんだったら、AutoReceiveInputの設定項目もなくしてくれればわかりやすいのに……」

「それをやると”親クラスと同じパラメータを持っている”じゃなくなるからね。キャストの互換性がなくなってしまう。エディタ上では見えなくしたり、実行時に何らかのエラーを出してくれる仕組みがあればありがたいとこだけど」