2019.3.0f3まで上げて使ってて見た目が随分変わっててびっくりしました。アイコンとか慣れないです。Lightを使ってみたいと思い、触ってみました。Twitterに投稿しました。久しぶりのUnity投稿です。Lightを使ってみた。それだけだとつまんないのでTilemapと組み合わせて洞窟探索するようなイメージでゲームっぽくしてみました。2020年1月17日そこで一点気になった事があったので記事にしてみます。LWRPを設定するLWRPを設定するとSpriteがLightの影響を受けるようになるらしい。おおこれはやってみたい!ということで先人の知恵をお借りします。kan-kikuchi.hatenablog.com(いつもお世話になっています。)自分でも軽く設定の仕方だけ書いておきます。新規プロジェクトを作成するUnityは2019.3.0f3を使用。Renderer(Experimental)を作成します。Data」の三つのファイルが作られます。RenderDataをセット。(特にパラメータをいじる必要はありません。Settingsに「UniversalRenderPipelineAsset」ファイルをセットすればOKです。適当にSpriteRendererを作成すると、Materialが「Sprite-Lit-Default」になっており、真っ暗になります。Lightを作成すると、Lightの影響を受ける2Dスプライトが確認出来ます。Lightをゆらゆらさせたい!ここからが本題。いうの作ったら、揺らめく炎を作りたくなるもの。Intensityをいじるといい感じに揺らめくな、じゃあこれをスクリプトで触ればいいや(getterしかない。なんで?)で、触ってみるとこれ、アクセサーがgetしかない。なんでええええ?何か別の値から計算して求めているのかな?詳しいことまではわかりませんでしたが、とにかく揺らめかしたいので、リフレクションで触ることにしました。}ソースコード全体としてはこんな感じ。UnityEngine.Experimental.Rendering.LWRPではなく、UnityEngine.Experimental.Rendering.Universalになります。Lightでも実現できました。RPG風なのいいですね。Unity1weekお疲れ様です。第13回unity1week「さがす」。今回のゲームは反応速度を測るシンプルなゲーム「蜻蛉切り」(とんぼきり)です。unityroom.com今回も今までと同様に色々と工夫した点があるので、そこを紹介したいと思います。「サブシーン」の2つに挑戦しました。話を作るのが好きなので今回こそはストーリーものやりたいなぁと漠然と考えていました。【先にさっくりと開発の感想について】めちゃくちゃ満足しています。Rushより満足しています。)ストーリー作れたし、敵キャラ可愛いし、最高です。いうのが作りたかったんだよなぁーと。欲を言うともっとやりたかった。進捗マップ(○がこうつながってるやつ)があって、進んでいく感じとかキャラ変えられるなどなど妄想が広がってますが、とりあえず今回は一週間しかありません。やれるところまでやって、上手くまとめようと思っていました。ゲームについてプログラム側の作業がメインになってしまうだろうと当初から想像していました。リアルタイム通信対応、何が起きるわからないし、デバッグ想像しただけで冷えるレベルです。ゲーム側は極力シンプルにまとめて、わかりやすいステートメントで対応出来るようなゲームがいいなぁと考えていました。「居合斬りみたいな一発系ならオンラインもやりやすいかな」とか簡単に考えてました。ゲームとしてパッと思いついたのは、これが頭に浮かびました。jin115.com正直、もっと似てるゲームあるでしょ!と。カービィの刹那の見斬りでしょうと。マジで似てしまいました。最初はストーリーも無くて、本当に反射神経テストなだけだったのですが、ストーリー書きたい!という欲望からNPCの実装をどうにか詰め込みました。以前から調査していたPhotonを使うことにしました。別の疑似的な通信システムに乗り換えてしまったのですが、リアルタイム通信Photonの実装についてお話したいと思います。ghoul-life.hatenablog.com(長すぎるため別記事に分けました。)とにかくテストするためにはWebGLへのビルドが必要です。実装し、吐き出し、ブラウザとUnityEditorでマルチプレイを行う...というテストを繰り返すことになります。ビルド一発15分ぐらいかかります。これがとにかく時間がかかりました。ビルドしている間は・Utility系のコードを書く・自分コードレビューして設計見直す・お絵描きする・寝る・お茶を飲む(ほぼこれ)と上手く時間を使って、作業効率をあげてました...。事件が起きる土曜日、同じようにテストをしていると、ルーム一覧が取れなくなりました。調べてみると20CCUしか無料では受け入れることが出来ず、テストで使い切ってしまい、制限されてしまったようです。時間を置くと直りましたが、不安がよぎりました。「このままリリースしたら繋がらないという阿鼻叫喚が待っているかも...」100CCUに上げるには約2万円ほどかかってしまいます。それはやりすぎだなと思ったため、思い切って別のシステムに舵を切ることにしました。擬似的な対戦このゲームでリアルタイムマッチングを行った際にやりとりするメッセージは以下の3つを考えていました。準備完了(READY)タップタイム(FIRE)リザルト(RESULT)もっとシンプルにまとめるとデータとしては最低限以下だけで良いです。上記のデータだけ保持出来ればそのまま対戦を行うことが出来ます。これをNCMBに喰わせて、後は出し入れするだけでまかなうことが出来るなと考えました。土曜日一日を使ってこのシステムを作成し、ネットワーク対戦基盤をPhotonからNCMB疑似システムに差し替えました。一度設計を綺麗にしていたのがここで効きました。今回、マジで設計ミスった...。マルチプレイ周りのコントローラー、ゲームコントローラーが当初の予定よりもどんどん膨らんでいってしまってる。各ステートメントごとにクラス分ければよかったと、今必死に書き直してます。切断されてしまった時の中断処理この辺りがまるっとペンディングになっています。(結構頑張った所ではあるのですが...。乱入される、乱入する、といった事を実現出来そうではありました。研究の余地がありそうです...。(他のシステムとかどうかな、モノビットとか)サブシーンについてもう一つ今回実装した技術的なお話をしたいと思います。普段unity1weekをやるときは1sceneファイルでやっていました。OutGameを切り替えていました。Canvasを分けておいて、なんちゃって画面切り替えを実現するなんていう工夫をしていました。これには大きな問題があります。それは多人数開発に向かないです。永遠のソロな自分には関係ないと思っていたのですが、もう13回も参加しているので、いい加減にちょっとはやってみたほうがいいだろうと重い腰を上げて「シーン分割」やってみることにしました。全部このサブシーンシステムの上に乗っかってます。設計についてベースとなるMainSceneがあり、その上にSubSceneとして各画面が乗っかっています。それを管理するのはSceneManagerです。一気にタイトルまで戻れるようにそんなシステムにしたいと考えました。Cameraにしてるので。Overlayで良ければ必要ないです。これ忘れるとリークの元ですよ!と教えてもらいました...。DoTweenに依存しているのはちょっとダメかもですね。単純な移動なので、自作したほうがいいかもしれません。シーンに入った時に呼ばれるイベント。初期化などを行う想定。画面遷移に使用しています。ベースとなるMainSceneにのみCameraとEventSystemを入れて、その他サブシーンでは外しています。一気にタイトルに戻りたい時は、StackをClearしてLoadSceneすればOKです。何が便利だった?カスタマイズ性が高いです。遷移変えたいなという時にささっと変えられる。Cとしたければ、LoadSceneの文字列変えるだけで間に挟むことが出来ます。戻る場合も意識することはありません。スタックされているものを取り出していくだけなので、どんなフローからでも一つずつ戻っていくことが可能です。今回の蜻蛉きりではMainSceneとTitleSceneを分けて、MainSceneをロードしてからTitleSceneをロードするようにしています。将来的にタイトル表示する前に利用規約画面とか挟みたいな!となったらLoadScene変えるだけでいいのです。拡張性も悪くないBaseSceneを継承したクラス作ってサブシーンに当てはめればそれだけでOKです。画面遷移アニメーションとか意識せずに勝手にやってくれるようになります。Contentの設定が手動なのはちょっと今後の課題ですね。逆にダメな所は?一人でやっているので、どこに何があるのか?はもちろん全て把握しているのです。バトル画面いじってて「あ、あの画面のテキストも直さなきゃ」と思ったら別のSceneを開き直さないとなりません。ここが若干面倒でした。シーンを切り替えると、前のシーンが閉じられるので、地味にEditorロードが入って若干なイラつきがあります。サブシーンだけでちょっと実行してみよう、なんて思った時はEventSystemやCameraを付けてあげないと動かないことに注意する必要があります。付けて、動かしてテストして、また消して保存する、なんていう手順が必要かも。サブシーンやってみて単一シーンを多人数で開発するとコンフリクトを引き起こしがちで、Slackで「今から○○触りますー」なんてやりとりが必要になったりするのかもしれません。この辺りはサブシーン化すると分けて編集することが出来るので、並行開発が可能になります。共通処理はBaseで賄えたり、MainSceneがキャッシュを持ってくれたりといった1Sceneのいい所も併せ持ってます。ここは大きなアドバンテージなんじゃないかなと思いました。慣れるといい感じですね。Hierarchyがスッキリするのもいいです。こんな感じで別れて管理できます。開発を終えてとにかくとにかっくネットワークは大変でした。おかげ様でビビらなくはなったのですが、ネットワーク対応はくっそメンドイな...と思いました。リアルタイムで二人で対戦出来るようになると本当に感動的ではあります。次はDotsだろうなーと思ってます。それまでにエンジンをブラッシュアップしておこう!以上、ここまで読んでくれてありがとうございました。Unity1weekunity1weekでリアルタイムオンライン対戦を実現しようとしたのですが、挫折しました。そこまでに勉強したことをまとめてみようと思います。公式を貼っちゃいます。doc.photonengine.com問題なく開始するために、「PUNベーシックチュートリアル」を十分に確認したうえでコーディングしてください。書いてありますが...まあちょっとわかりにくいというか悪い面を伏せているというか。「細かいことは置いておいて、とりあえずホストとクライアントでメッセージのやりとりするにはどうすればいいんだよ?」という観点だけ解説させてください。それでもめちゃくちゃ長いです。文章はななめ読みして、コードと画像だけ見る、でも充分です。使用するAssetはこちらになります。Unityは2019.2.8f1です。assetstore.unity.comそしてテストするためにWebGLで吐き出したものと二つでテストしています。所々にある検証画像も参考にしていただけると。覚えてほしいこといきなり説明してんじゃん!ですが、これだけは覚える必要がありますのでご容赦を。Photonは3つの概念があります。それはPhotonサーバロビールームこの3つです。これさえ忘れなければもう怖いものはありません。相対関係は以下の図をイメージしていただければOKです。アカウントを作成&事前準備この辺はささっと。Photon側の作業Photonを利用するにはアカウントが必要です。dashboard.photonengine.com新しくアプリを作成する作りたい名前を付けて、作成するですぐに作成できます。アプリケーションIDをコピーして覚えておきます。Freeをインストールし、パッケージをインポートします。Photonの設定が開くので、設定にアプリケーションIDなど必要な情報を入力し、SetupProjectボタンを押下すると、自動で設定ファイルが作られます。photonを使うには最低限であれば適当なクラスにPhoton.PUN.MonoBehaviourPunCallbacksを継承してあげればOKです。これでクラスがPhotonサーバのListenerとなってくれます。略}Photonサーバに接続(ホスト、クライアント共通)3つの概念を覚えているでしょうか?その通りに実装すれば問題ありません。Photonサーバに接続します。以下のコードでPhotonサーバに接続することが出来ます。}}コールバックは以下の2つになります。1,2の順番で呼ばれます。(なんで二つとも呼ばれるんだろう...?)OnConnected()OnConnectedToMaster()接続失敗した時のリスナー...は見当たりませんでした。Disconnectが直接来るのかな?(AddMessage()で経由したメソッド名を画面に出力しています。)注意点としては通信出来ない所で接続しようとした場合はコールバックが来ない可能性があるので、ポーリングしてタイムアウト処理などを自作しておいたほうが安心です。ロビーに入る(ホスト、クライアント共通でも良い)Photonサーバに繋いだら、Lobbyに接続します。実はホストのCreateRoomはロビーに入らなくても行うことが出来ます。その際は自動でロビーにも接続されます。(Lobby.Defaultに接続するならば、特にLobbyに入らなくてもOKという意味のようです。指定してルームを作成することになります。ここでは正しい手順でロビー入ってからルームを作っていきます。}}お、なんか変なのいるぞ?(OnRoomListUpdate)これは次に解説します。ルーム一覧を取得する(クライアント)例えば、凄く単純なオンラインゲームを作りたいと考えてホストが部屋を立てて、ゲストがその部屋を探して接続するとしたいと思った場合は、ホストが立てた部屋リストを取得したいですよね。実は簡単なコマンドは用意されていません。やってリストを取るのか?ロビーに参加した瞬間に、以下のコールバックが叩かれます。roomList)ここで現在ロビーにあるルームリストを取ることが出来ます。え、任意でルーム取りたいに決まってんじゃん。ふざけてるの?普通そーする。