かみおかのチラ裏

思い付きを書き溜めておくばしょ

Dynamic Input辞書もどきをつくる1

前回の記事にも書いた通り、
しばらく前からUnreal EngineのNiagaraを使ってエフェクトを作るようになりました。
色々あって、単純にエフェクトを作るというよりは
Niagaraの機能を把握しながらエフェクトを作るというちょっと変わったことをしているので、
Dynamic Inputの一覧表がほしいなぁ〜、ついでに入出力型も分かるといいのになぁ〜
というのと、公式ドキュメントも全てのモジュール、DynamicInputを網羅しているわけではなく、たまに困る...。
と思うようになり、表題のDynamic Input辞書もどきをつくろう!ということになりました。

しかし、NiagaraどころかUE初心者な私に
いきなりそんな所業ができるわけもなく...
ということで、今回はChatGPT先生に色々聞きながらやっております。
便利な世の中になったな...
ただ、正直この記事の内容自体全くどこにも需要はないと思いますので、完全に備忘録です。
そして、辞書もまだ完成していないので、途中経過です。

続きを読む

ご無沙汰しております。

大変ご無沙汰しております。
前回の記事が3年前(もうすぐ4年)だそうで...だいぶ放置してしまっていました。

ゲーム開発自体は中断状態ですが、
なんとか細々やっていきたいという気持ちだけはまだ消えてないです。

最近、なぜかエフェクトを作る人になりました。なんででしょうね。
エフェクト制作が本業ではないのですが、エフェクトを作っています。不思議です。
ということで、しばらくそんな話をしていくと思います。

ゲーム開発の方もなんとか小さくても一つでも出せるようにしていきたいなー
と思っていますが、おそらくしばらくエフェクトの話になると思います。
長い連休の時なんかにちょっとずつやれたらなぁと、色々画策中です...。

2022年開発振り返り

この記事はUnityゲーム開発者ギルド2 Advent Calendar 2022の25日目(遅刻)の記事です。
adventar.org

せっかくUGDGのアドカレ記事を書くので、
本当ならなんでもいいからUnity関係特に技術周りのことを書きたかったのですが、
書けそうなアウトプットもないので今年の開発について振り返ることにします。

さて、twitterのヘッダーをひっそりと変えずに置いたままにしていますが、
そらとぶメンダコの年内リリースはやはり難しかった。
最初のうちは見積りの何倍もかかるということは
他のインディー開発の方の経験談から知っていて、
ゲーム自体もミニマムな設計にしていましたが、
やはりそれでも見積り通りにはいかないものですね。

原因としては見積りの甘さもさることながら
自分の体調の安定しなさや仕事を始めたことも影響していまして、
なかなか難儀だなぁと思っています。

しれっと書きましたが、3年ぶりに仕事を始めました。
仕事自体は経験があるのでそれなりに要領は得てきましたが、
改めて感じるのは、
自分は社会人適性が本当にないな!
です。
昔から自覚がないわけではなかったのですが、
やっぱり他の人と長時間共にいること自体がしんどいです。
とりあえず、昼休憩は近くの静かなカフェに逃げ込んで回復しています。
思えば、バリバリやっていた頃から昼休憩は9割がたひとりでご飯食べていたな...(∵)

とは言え、難儀なことばかりでもなく、
現実的にリリースできるものにするにはどう工夫をしたらいいか、
を考えられるようにもなったので、
自分の実力に合わない実装方法で開発自体頓挫することを回避できるようになりました。
この点はいいことかなと思っています。
目標や理想は高いのが一番いいですが、
やはりリリースできることが一番重要かなと思うので、
無理のない設計ができるようになることも大事かもしれません。

そんな感じで開発自体はとても順調とは言い難いですが、
前進していることは間違いありません。
年内はもうちょっとだけ開発しようと思いますので、
進捗がありましたらまたいつものようにtwitterでつぶやきます。
よくてもよくなくても、ぜひ見ていただけると嬉しいです。

最後に、最近開発周りで感動したこともちょっと書いておきます。
先日国立科学博物館(上野)に行ってきたのですが、
本館3F南翼にメンダコの標本が豊富にあることに感動しました。

メンダコというのはおなじみ八腕類つまり、タコの仲間なのですが、
現状で日本近海では3種類発見されているようでして、
それがメンダコ、オオメンダコ、センベイダコの3種なのですね。
しかし、メンダコ以外はなかなか展示事例がなく情報も少ないのですが、
かはくにはこれらのメンダコ全ての標本と詳細説明があったのです!

標本を見るとどれも同じメンダコじゃねーかって感じですが、
大きさや生息地がちょっと違うんですね。
the深海のアイドル!といえば、やはりおなじみのメンダコなのですが、
この子は相模湾〜常磐沖の水深150~600付近の海底に棲んでいます。
だから、静岡県や東京都、神奈川県、そして茨城県の水族館での
展示事例が複数あるのですね。
(来年はまだ行ってない水族館にいっぱい行けたらいいなぁ)

ちなみに、センベイダコとオオメンダコについてもざっくり説明すると、
センベイダコはほぼメンダコと同じくらいの大きさですが、生息地は和歌山沖〜土佐湾。
オオメンダコはメンだこよりも一回り程度大きく、
生息地は北海道近海〜北太平洋亜寒帯なので、結構寒いところですね。
みんな可愛いメンダコだ!!!!!

やっとメンダコの情報を増やせてテンションが上がったのと、
メンダコモチーフのゲームを開発している人間としては外せないことでしたので書きました。以上です。

とっ散らかり気味な記事になってしまいましたが、そろそろ強引に〆ます。
来年はもうちょっと外に出られたらいいなと思いますので、
もしお会いした際には仲良くしてやってくださいませ。

本年もお世話になりました。
来年もよろしくお願いいたします。

少し早いですが、良いお年を。

JoyStickを使って、スクロール移動のようなものをできるようにする

前回、RayCastによる衝突判定を利用したScene移動を実装しましたが、
このメニュー画面はまだ完成ではないので、完成に向けてさらに機能を実装します。

ちなみに、今回やりたいこと(イメージ)はコチラ↓

ポケモンクエストのステージ選択画面に近いことをしたいんですよね。
全く同じこととなると、おそらくUniRxを使うハメになるのでそこまではしませんが、
このスクロールのようなものはやりたい、ということでアレコレ弄っている感じです。

ということで順番に作業していきます。

いつもの注意書き
なるべく正確な記載を心がけていますが、
私の知識不足などにより誤りが含まれている可能性があります。
誤りを発見された場合は、コメント等でご指摘いただければありがたいです(ぺこり)

JoyStick/JoyStick Packとは?

リリースから相当経っているので、
他のサイトさんの説明の方が分かりやすいと思いますが、簡単に書いておきます。
JoyStickとは、ゲームのコントローラーについているスティック状の入力機器です。
もっと平たくいうと、3Dゲームなどで主人公をぐりぐり動かせるアレです。
最近、アクションゲームなどでスマホゲームでも見かけるのは珍しくなくなりましたね。
JoyStick Packは、このJoyStickを簡単に実装できるアセットです。

実際の使用方法

アセットDL〜使用の仕方は文末の参考サイト様を見ていただく方が早いと思いますので、
そこは省略して今回神岡が実際にやったものについて記載します。

JoyStickの配置

JoyStick Packがインポートできたら、SceneにJoyStickを配置しましょう。
JoyStickプレハブはUIなので、Canvasに配置する必要があります。
Canvasオブジェクトがない場合は、UI > Canvasから作成します。
作成したCanvasにインポートしたJoyStick PackのPrefabsフォルダから、
使いたいJoyStickのプレファブをドラッグします。

これでJoyStickの配置は完了です。

あとは、JoyStickを使える範囲を設定しましょう。
お好みでいいと思いますが、今回はこんな感じで設定しています。

Playerの代わりとなる空のオブジェクトを作成

このJoyStick、プレイヤーを操作するために使用することが多いですが、
今回は視点変更することで擬似的にスクロールしているように見せたいので、
空のオブジェクトを作成します。
名前はわかりやすい任意のものでいいですが、今回は「ChangeViewPoint」にしました。

MainCameraをChangeViewPointの子オブジェクトにする

Player代わりのChangeViewPointにカメラを追従させたいので、
MainCameraをChangeViewPointの子オブジェクトにします。

上記の関係性になっていないと、永遠に移動してくれないので注意してください。
とはいえ、MainCameraをChangeViewPointにドラッグするだけなので、
やることはシンプルです。

ViewPointController.csを作成する

実際にChangeViewPointを制御するためのスクリプトを作成します。
こちらもファイル名はお好みでどうぞ。

using UnityEngine;

public class ViewPointController : MonoBehaviour
{
  //FloatingJoystickを格納する(Inspectorで設定)
    [SerializeField] private FloatingJoystick FJoyStick;

    //移動速度を設定する(Inspectorで設定)
    [SerializeField] private float JSMooveSpeed;

    // Update is called once per frame
    void Update()
    {
   //上下移動する
        this.transform.position += this.transform.up * joyStick.Vertical * JSMooveSpeed * Time.deltaTime;
   //左右移動する
        this.transform.position += this.transform.right * joyStick.Horizontal * JSMooveSpeed * Time.deltaTime;
    }

}

今回は2Dゲームということもあり、
上下左右(斜めも可能なのですが)移動できるようにしたかったので、
upプロパティとrightプロパティを使用しました。
しかし、3Dの場合ですと前後移動したいことも多いと思います。
その場合はforwardを使いましょう。

Unity側の設定

最後に、スクリプトやオブジェクトのアタッチやらをしていきます。
まずはViewPointController.csをChangeViewPointにアタッチします。
次に、ChangeViewPointのInspectorから
FJoyStickにはFloatingJoystickのプレハブを、
JSMoveSpeedには任意の数値を入れましょう。今回は「3」を入れております。

JSMoveSpeedはもちろんコードから直接指定できるのですが、
SerializeFieldにしておきInspectorから設定可能にすると調整しやすいと思います。
この辺はお好みでどうぞ。

こんな感じで動くよ

必要な設定ができていると、こんな感じで動きます。

自力で作るとなるとかなり大変ですが、
このアセットを使うとすごく簡単にできてしまいます。

でも、微妙に見た目がダサいね?


おやおや、画面外にも移動できてしまって青い背景が見えて、
なんだか格好がつきませんね。
せっかく作るゲームなので、ここもちょっとこだわりたいところです。
こちらにつきましても無事に解消できましたので、また別の記事で書きたいと思います。

参考記事

最後に、大いに参考にさせていただいた記事を掲載します。
毎度のことですが、先人の知恵に本当に感謝です...足を向けて寝れませぬ。
qiita.com
solitude-bocchi.com

RayCastによる衝突判定(2D)


ご無沙汰しております。
なんと、前回更新日から136日経ってしまっていたようです。
途中、ダウンしてしまい空いてしまいましたが、開発は細々と継続中です。

今回はRayCastによる当たり判定について、備忘録として書いておきます。

いつもの注意書き
なるべく正確な記載を心がけていますが、
私の知識不足などにより誤りが含まれている可能性があります。
誤りを発見された場合は、コメント等でご指摘いただければありがたいです(ぺこり)
 

さて、現在開発中の「そらとぶメンダコ」のステージ選択画面、
Buttonを使うことでプレイするステージを選択できるようになっているのですが、
一つ問題が...。
選択可能なステージが増えると、視認性や操作性が落ちるのですよね。

今は少ないので視認性に問題はないが、10を超えると...

ということで、画面スクロールをしてひとつの画面内に表示するボタン数を減らそうと思い最初に考えたのがJoyStickによる擬似的な画面スクロールです。

が、当然ですがCanvas内に配置されたUI系のButtonは、
JoyStickによる操作の影響を受けません。
結論を書きますと、UIのスクロールはScroll Viewによって実現できそうなのですが、
Scroll Viewはクセの強い子らしく、なんとか他の方法でできないものかと思いました。

ということで、アドベンチャーゲームなどによくある
ポイント&クリックの仕組みを利用してみることにしました。

さて、ポイント&クリックはご存知の通り、
タップなりクリックしたオブジェクトを何かしらの操作できる仕組みです。
どうやっているかというと、スクリーン上でクリックした位置からRay(光線)を飛ばして
当たり判定をしているようです。
この辺りは他のやり方もあるだろうとは思いますが、
おそらくRayCastによる衝突判定が一番素直で分かりやすいのではないかと思います。

 今回やりたいことの具体的なものとしては、
ステージごとのボタンとなるオブジェクトを配置し、
オブジェクトによって生成するステージを分岐させるなので、
Rayを飛ばす→RayがHitしたオブジェクトを検出する→検出したオブジェクトによってその後の処理を分岐させる、ということになります。

ということで、今回作成したコードは以下のような感じになりました。
(雑に完成した料理を出す某キュー◯ースタイル)

   Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit2D hit = Physics2D.Raycast((Vector2)ray.origin, (Vector2)ray.direction, 20);
            if (hit.collider)
            {
                if(hit.collider.gameObject.name == "GameObject名")
                {
                    //実行したい処理
                }
            }
        }
    }

ifだらけになってあまりスマートとは言えない実装になってしまいました...。
この実装でも問題なく動きますし、
今回はステージ数がそれほど多くないため極端に負荷が上がるとは思えませんが、
できればswitchで分岐させたかったです;;そっちの方がコード的にも読みやすい。

実際の挙動はこんな感じになります。

画像が荒くて見づらい場合もありますが、
上部分のScene Viewで実際に飛ばしたRayを可視化しています。
細いですが、赤線で可視化されています。

ちなみに、3Dの場合は少々書き方が違いまして、

   Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, Mathf.Infinity))
            {
                if(hit.collider.gameObject.name == "GameObject名")
                {
                    //実行したい処理
                }
            }
        }
    }

と、このような感じになります。
使用している物理演算が異なりますね。

今回はRayの衝突先のGameObject名を取得して処理を分岐させていますが、
これについてもあまりスマートとは言えない方法だろうと思います。
この方法だと、せいぜい数十程度ならコピペでまあどうにかなりますが、
100を超えてくるとそもそも打ちたくありませんし、何より絶対にミスが発生します。
数が多くなりそうな場合はLayerMaskをうまく使うとよさそうです。
先述の条件分岐も含め、他に良い方法をご存知の方がいらっしゃいましたら、
コメントいただけると嬉しいです。
(ま、マサカリも受け止めます...小声)

ちょっと雑な感じになってしまいましたが、余力があれば加筆修正したいと思います。
今回はこの辺りでさようなら。

Inspectorを整理する

ずっとInspectorに表示されるフィールドが羅列されているだけの状態だったのですが、
つい最近Header Attributeというものを知りまして、とても便利だったので備忘録として残しておきます。
 
いつもの注意書き
なるべく正確な記載を心がけていますが、
私の知識不足などにより誤りが含まれている可能性があります。
誤りを発見された場合は、コメント等でご指摘いただければありがたいです(ぺこり)
 

 

Header Attributeとは?

Inspectorのフィールドに属性を追加することができます。
フィールドが多い時に使うと、Inspector上の視認性が良くなるので便利です。
Unity 4.0の頃からあったため特に新しい機能ということはないのですが、
Unity入門者向けの本などにはあまり載っていないため、今まで知りませんでしたorz
 

使用例

実際に使って見た方が分かりやすいので、実例を出してみます。
 
下の画像はHeader Attributeを使わずにInspectorを表示した場合のものです。

項目ごとに整理しているものの、全て同じように表示されているので少々見づらいです。
コード上だとコメントアウトでコメントしたり、
改行を使って分類ごとに分けられるのでいいのですが、
Inspectorにはもちろん反映されません。
 
対して、Header Attributeを使った場合のInspector。
属性ごとにまとめて表示してくれているので、視認性が良くなりましたね。

使い方

使い方はとっても簡単です。
フィールド定義の上に[Header("")]を追加するだけです。
""の中は任意の文字列を入れます。
上の画像の例だとUIを入れているので、Inspector上だとこんな感じで表示されます。
上手に使えばフィールド定義のコメントアウトが不要になるかもしれません?

ちなみに...ソースコードを貼り付けたかったのですが、
これ、はてな記法かMarkDown記法でないと使えないということを知りました...。
見たままで記事を作ってしまったので時すでにおすし。
次回までに対応する所存。

参考サイト

ekulabo.com

qiita.com

 

特定のオブジェクトの物理演算を一時停止させる


ゲームの進行を一時的に止める時に使うことが多いのは
Time.TimeScale=0;ですが...

 

いつもの注意書き
なるべく正確な記載を心がけていますが、
私の知識不足などにより誤りが含まれている可能性があります。
誤りを発見された場合は、コメント等でご指摘いただければありがたいです(ぺこり)

 

物理演算を使っている自機などをポーズ中に止めたい時、
最もお手軽にできるのがTime.TimeScale=0;です。
しかしこの方法だと、全てのゲーム進行に関わる時間をストップさせてしまいます。
(※厳密には、Update()内に書かれたものなどは止まりません)
そのため、ポーズを解除してゲームに復帰するまでに
カウントダウンさせる時などは、ちょっと不都合です。
時間自体が止まってしまうので、カウントダウン自体も進まないからです。
フラグ管理をすれば実装可能ですが、ちょっとめんどう...。

ということで、何とか特定のオブジェクトだけ停止させる方法がないかと考えていたところ、
Rigidbody2Dクラスにsimulatedというプロパティがあることを教えて頂きまして、
無事に問題を解消できたので備忘録的に残しておきます。

前置きが長くなりましたが、
simulatedとは何かというと、上で書いた通りRigidbody2Dにあるプロパティです。
詳細はUnityの公式リファレンスを見ていただくのが
一番確実だと思うので省略しますが、
このsimulatedはbool型変数なので、trueかfalseのみを代入できます。

trueだとsimulateが有効になり、falseだとsimulateが無効になる。

シンプルですね。

実際に使ってみると、こんな感じです。
ポーズメニューが非表示になったあと、自機がが空中に浮いたまま停止

動画中の自機(メンダコ)は物理演算が有効になっているので、
タップし続けなれば落下してしまいます。
しかしポーズ画面解除〜ゲーム復帰のカウントダウンでは落下させたくないため、
simulated=false;にしています。
Time.TmeScale=0f;と異なる点は、
あくまでもRigidbody2Dにのみシミュレーションを無効にしているため、
それ以外のAnimationやメソッドで動かしているものは動いたままとなる点です。
(例えば動画中の鳥はAnimation+Sin()で動かしています)

特定のオブジェクトだけを動かさないことを実現できる方法は他にもありますが、
Rigidbody2Dを使っている場合で物理演算だけを止めるので十分ならば、
Time.TimeScale=0f;と同じくらい手軽にできる方法ではないかなと思います。