てんちょーの技術日誌

自分がつまづいたこととかメモ

【UE4】VRてんぷれーとを読んでみた本 正誤表

正誤表

ハッシュタグ #VRテンプレ本 等に寄せられた誤字脱字、訂正などを適宜追加しておきます。

ページ/対象箇所
P19 / Animation Stateを管理してる部分の箇条書き Can Frab Can Grab
P24 / 3行目 Over lap Overlap
P59 / コメント等で改行する Crtl + Enter Shift + Enter

他にもありましたら、 Twitter: shop_0761 等にご連絡ください

【Chrome拡張】VALUで後で見るリストを作るやつを作ってみた

はじめに

VALU夏休みらしく、VAのやりとりが出来ない期間にバンバン新着更新されたりして 月曜日は一体どうしたら…みたいな気持ちになったりします。

それにこの感じだと新着が夜中に来て、9時に備えなきゃ…みたいなことに今後なりうるかも、 と思ってパパっと作ってみました。

Chrome拡張自体は初めて作ったけど、意外となんとかなりました。 またストアに公開しても良かったんですが、開発者登録料がかかるしChrome拡張の有料版もあんまり見たことないしで 微妙だなと思ってやめました。野良拡張として配布するので、導入するかどうかは自己責任ということでお願いします。

勝手にVListと呼んでます。

機能紹介

とりあえずこんな感じ。

f:id:shop_0761:20170805095905g:plain

消す時はこれ。

f:id:shop_0761:20170805100024g:plain

また、右クリックからも追加できます。

f:id:shop_0761:20170805100245g:plain

あとはボタンにあるように、登録した人を新規タブで全部開くボタンと、全部消すボタンです。

配布先と導入方法

GitHubにおいておきます

github.com

CSSはこちらを使わせて頂いてます。

github.com

導入方法はここが参考になるかも。

qiita.com

まとめ

ソースコード一式公開してるので、各自勝手に改造してもらってかまいません。

また応援していただける方はこちらもお願いします。

valu.is

【UE4】Oculus Preview Appとしてアップする時にチェックしておきたいこと

はじめに

最近はVALUしたり、bitcoinを覗いたりしてます。

valu.is

そしてめちゃ安かったので買ってしまった…

ついさっきRiftのセットアップをして、HoloStickyの前のVRStickyで動作チェックしようと思ってゴニョゴニョしてました。

いろいろ面倒でPreview Appにしてしまえと思ったら、久々にやってハマったところがあったのでメモついでに。

HoloStickyはこちら。

てんちょー@C92 1日目東こ34b委託 on Twitter: "⚡️ "HoloStickyを作るまで" #HoloSticky https://t.co/VVfP3jflEr"

やること

  • entitlement checksを実装する
  • VR Modeで起動するようにする
  • Steam VR Pluginを切る

の3つです。

entitlement checks

なんじゃこりゃ。 こちらを読んで下さい。

qiita.com

端的にまとめると、

  • Online Platform → Online SubSystem Oculus プラグインを有効に
  • プロジェクト名\Config\DefaultEngine.ini に追記
  • Verify Entitlement ノードの追加

です。2つ目の追記事項はこんな感じ そのまま1番下に追加すればいいはず。 OculusAppIdに関してはDeveloper Dashboardで配布用アプリの設定をしてから、https://dashboard.oculus.com/application/“ココ!!”/build のココの部分にある数字の列をコピペしてください。

Oculus Developer Dashboard

[OnlineSubsystem]
DefaultPlatformService=Oculus
[OnlineSubsystemOculus]
bEnabled=true
OculusAppId="IDを入れる"

そしてVerify Entitlement ノードはこんな感じ。どこでもいいのかなこれ。 今回はMotionControllerPawnを使っているので、そのBeginPlayにはさんでます。

f:id:shop_0761:20170803013710p:plain

LatentノードなのでOn SuccessとOn Failure時の処理を決められます。とりあえず元の処理を一番上に繋いでいます。 今回は適当にFailureだったらQuit Gameしてるだけなので、大したことはないです はい。

VR Modeで起動

エディタで実行テストしてると普通にVR Previewできちゃうので忘れがちですが、普通にパッケージングしてもVR Modeにはなりません。 ので、Execute Console Commandを仕込む、起動時に引数でVR Modeにするなどあるかと思います。 けど、面倒いので1番簡単そうなStart In VR にチェックをいれました。

Project Settings → Description の下の方にあります。

f:id:shop_0761:20170803014357p:plain

ここにチェックを入れるとVR Modeで起動してくれます。

Steam VR Pluginを切る

ここまでの2つは実際大したことないのでアレなんですが、これが盲点というか仕様変更があったのかな…?(前はなかった

このPluginが生きているとPackaging後の WindowsNoEditor\Engine\Binaries\ThirdParty 以下にOpenVR のフォルダが出来ます。これがあるとアップロード時に弾かれます。 忘れたまま一度PackagingしてしまうとPluginを切ったとしても残骸として残っている可能性があります。一応確認しましょう。

ただVR Templateから持ってきたMotionControllerPawnなどを使っているとSteamVR Pluginありきの実装になっている部分が一部あるので、 Pluginを無効にしても大丈夫かチェックする必要があります。

今回はMotionControllerPawnの場合で簡単に説明します。というよりMotionControllerですね。

f:id:shop_0761:20170803015612p:plain

こんな感じでSteamVRChaperoneがついてるので、こいつを消したい。 SetupRoomScaleOutline関数で使っているので消しておきます。

f:id:shop_0761:20170803015818p:plain

忘れずにコンポーネントも消しておきましょう。

f:id:shop_0761:20170803020717p:plain

するとGetBoundsが空になるので、適当に配列を間に合わせで入れておけばセーフw

f:id:shop_0761:20170803020003p:plain

Oculus Riftでも境界線を出したい…そんな時もあるかもしれません…そんな時は!

これに書いてます!!買ってね!! alweiさんのブースに委託させていただいているので、当日はそちらにいます。 紙とPDF版を用意していて、PDF版は後日どこかで頒布しようかなーと思っていたり。

まとめ

最後は急に販促的になりましたが、概ねこんな感じでアップロードできるかと思います。 どれもエラーを追いかければなんとかなりますが、事前に知っておくと便利かもしれないですね!

おまけ

ちなみにアップロード時はzipにするんですが、こんな感じにしてVRStickyのフォルダをzipにしてます。

f:id:shop_0761:20170803021434p:plain

こうするとDashboard側でのLauche Fileのパスはこうなります。

VRSticky/WindowsNoEditor/VoiceRecognition.exe

最初は WindowsNoEditor/VoiceRecognition.exe にしてましたが、多少勝手に補完してくれるようです。

Lumberyard をインストールしてみる

なんとなくLumberyardもやったほうがいいかなと思ったのでやります。 一通り読んでから試すのをオススメします…

Lumberyardとは

CryEngineベースでAmazonが提供してるゲームエンジン(Unity とか UE4 みたいなかんじ) AWS (Amazon Web Services) が使えるのが特徴。

インストールする

ここからDLできます。

Amazon Lumberyard をダウンロード | AWS

インストーラーはこれ。Optionsからインストール先を変更できます。

f:id:shop_0761:20170731210759p:plain

f:id:shop_0761:20170731211027p:plain

とりあえず終わったので起動しましょう。

f:id:shop_0761:20170716122713p:plain

起動してみる

おいおいおい…

f:id:shop_0761:20170731212639p:plain

さすがに今後のことを考えるとちょっとアレなので、Installしなおし…

初回起動時にAmazonのアカウント(amazon.comかも) / AWSのアカウント でログインしてくれと言われるかもなので、 一応AWS用のアカウントを取っておくといいかも。あとで使いたくなるかもだし。

f:id:shop_0761:20170716122126p:plain

参考:

usedoor.jp

ひとつ注意として、住所や名前を登録するときに"英数字で"と指定されたので内部的にはまだ英語ベースな可能性が…

f:id:shop_0761:20170716122835p:plain

起動した

一度 Express Installでやってみたんですが、自分のProjectが作れなくて???ってなりました。 Compile the game code じゃないでしょ!!と言われたので、Custom Installしなきゃいけないようです。

f:id:shop_0761:20170731215841p:plain

そして何やらたくさん必要らしい…☓になってたので全部いれるしかないのかな…とドキドキしながらいれます。

f:id:shop_0761:20170731221513p:plain

ちょっとアレだけど、なんとかProjectは作れそう。

f:id:shop_0761:20170731220049p:plain

Projectの管理系は Lumberyard Project Configurator にまとまってるようです。

f:id:shop_0761:20170731220220p:plain

選択して、Set as defaultにするとそのProjectを開けるようになるようですね

f:id:shop_0761:20170731223041p:plain

なんとなく新しいプロジェクトを作ってみます。

f:id:shop_0761:20170731220332p:plain

ちらちら見えるCryの文字…

f:id:shop_0761:20170731220556p:plain

レベルを作ってみるぞい

f:id:shop_0761:20170731220825p:plain

f:id:shop_0761:20170731220918p:plain

なぜかいきなり海岸が出来ました。

f:id:shop_0761:20170731221050p:plain

f:id:shop_0761:20170731221849g:plain

てかこの海ヤバくないですか…すごい…

砂浜ではなかった

f:id:shop_0761:20170731222043p:plain

Sample Projectだと色々入ってますね。

f:id:shop_0761:20170731223502p:plain

f:id:shop_0761:20170731223713p:plain

f:id:shop_0761:20170731223817p:plain

これゲームできるのかと思ったら出来なくて笑った

まとめ

とりあえずインストールはできました。が何ができるのかさっぱりわかりません。 一応チュートリアルがあるようです。

Tutorials - Game Dev Forum

VR用のサンプルはzip展開後のdev以下のフォルダをエンジンのdev以下に置いたらとりあえず起動できましたが、 Riftが反応しないのでよくわからない…

【UE4】「VRてんぷれーとを読んでみた本」を書いてみたお話【Re:VIEW】

はじめに

めでたい!!終わった!! お祝いにプリンを食べました。はい。

ということで、簡単な内容紹介やら、書くのに使ったツールやらを書いておこうかと思います。 無理して環境を整える必要はないです、こういう方法もあるよくらいでお願いします。

本について

表紙かわいいので見て。

f:id:shop_0761:20170728232754j:plain

タイトルどおりVRテンプレートを読んでみて、まとめました。ノードを一つ一つ追いかけて、なるべく何やってるのかを噛み砕いて書いたつもりです。 その途中で色々なTipsになりそうなことを詰め込んでいるので、最終的に72pになりました…。(表紙込)

エンジンのインストールなどの基本操作系は省略してるので、UE4での開発経験があったり、極み本やマテリアル本をある程度読んだ方が対象かなーとは思います。 一部C++のクラス名が出てきたりしますが、出てくるだけでC++のお話はしてません。 あとは、おまけとして4.16で大きく変わったVR系のコンソールコマンドもいくつか記載してます。一応手元にあるRiftとVive(Pre)ですべて動作チェックしてるので、多分大丈夫かと思います。

そしてそして、忙しい中おかずさん(@pafuhana1213)に添削していただいたり、せんちゃさん(@ukiukisoda)に表紙/背表紙を描いていただきました。 本当にありがとうございました!!

夏コミではalweiさん(@aizen76)のところに委託して頒布します。(僕も行きます)1日目 東こ34bです。 PDF版も用意しようと思って、DLカードを作ってます。当日どうしても来れない方はどこかで頒布するつもりなので、しばしお待ちをー!

ハッシュタグは #VRテンプレ本 ですので、感想や、ダメ出しがあればこちらを使ってもらえると僕が追いかけられます。

今回書くのに使ったものたち

あたりです。そもそのRe:VIEWとは…?みたいな方はこちらの記事を読んでみるといいかも。

magicbullet.hatenablog.jp

今回はようてんさん(@youten_redo)の記事を参考に同じところに入稿しました。

技術書典2 サークル参加レポ #技術書典 - ReDo

かくいう僕も全く知らず、LaTeXでゴリゴリ書くしかないのか…と思っていた矢先に技術書典で存在を知ったくらいなので。 簡単に言うなら、マークダウン風の記法で割りといい感じに文章がかけるよみたいなツールです。 Wordを久しく使ってないえんじにゃーの方にはこっちのほうが馴染むかもですw

ただWindows環境だとこの辺の環境構築が…めんどい…のですが、そこで Bash on Ubuntu on Windows をオススメしたいですね。

qiita.com

そしてVSCode

これ!!!これ!!! マジでこれができるだけでVSCodeだけでコンパイルも終わるし、最高かよ…という気持ちになりました。 作業用ディレクトリをdropboxにするだけで他の端末でも見れるしバージョン管理してくれるし、 そして適当にファイルを監視してくれるシェルスクリプトを書いて、保存するとコンパイルが走るみたいのもすぐできるしでとても良かったです。 もちろんVSCode単体でもgitが使えるのでバージョン管理できます。(一応してた)

qiita.com

まとめ

初参加にして死にそうです。がんばります。

UE4 + Hi 5 Glove を使ってみた感想とか

はじめに

今回はこちらで Hi 5 Gloveが使えるとのことで行ってきました

jvrh2017.peatix.com

UE4が使える人がいたのでチームを組んでいましたが、申し訳ないと思いつつも全力でHi 5 Gloveで遊んでいました(チームのコンテンツには使ってない

その時の感想やらなにやらを書いておこうかと思います。 もっと写真撮っとけばよかった…夢中すぎた…

どこまで公開していいか分からない & 正式版とは異なる可能性があるのでふわふわした内容になってるかもです。

そして多分今回1番 UE4 + Hi5 Gloveを触ってます!わいわい

つくったもの

ハッカソン中に作ったものをモーメントにまとめてあります。

動作環境

Noitomさんから頂いたサンプルプロジェクトがUE4.14でした。ちょっと古いかも…と思っていましたが、やっぱりといった感じ。

PCはデスクトップをレンタルしたのでUnityは入ってるけどUE4が入ってませんでした。よくあることですね。

また、サンプルプロジェクトと一緒にUE4.14をzipにしたファイルもあり展開して使ってねと。 (オフラインのインストーラーがないから…らしい

ただこれだとPluginのロードに失敗してしまい結局あとでLauncherからエンジンごと入れ直したらいけました。 (たしかUE4Editor.exeからBrowseで対象のプロジェクトを開いたけどダメだった気が… 多分、既定のアプリ選択ミス…?

そして、会場でめちゃめちゃViveを使っているので

となり、なかなかに厳しい環境でした。

と、Hi 5 Gloveでの開発をするために30時間のハッカソン中は20分くらいしか寝てません()

キャリブレーション

Hi 5 Glove 独特のダンスをします。

参考はこち

BCPポーズと呼ぶらしい。導入用ビデオがあったらしいけど、もらったファイル類には含まれてなくて見てない…

使い方

グローブ側と通信するドングルがあるので、そいつを差して指の動きを取りつつ、ViveTrackerで手の位置を取る感じです。 ドングルとの接続するには、グローブ側にあるボタンを押すだけで繋がったら振動します。

UE4の場合、頂いたサンプルプロジェクトはすでにマニュアルの手順が終わっててキャリブレーションするだけでした。

ただよくわからないタイミングでクラッシュしたり、静かに亡くなったりして開発途中感があってちょっと楽しかったです。(つらい

今後変わるかもですが、グローブがつながってない状態で実行終了するとEditorが帰ってきません。

これは1個でも繋げばちゃんと戻ってきます。おかえり。

感想とか

ちゃんとキャリブレーション出来て、ViveTrackerも安定する環境でやるとめちゃめちゃキレイに動きが取れます。すごい。 そして、UE4なエンジニアじゃない人がEnglishなサポートしてくれてて、その人がわからない時はエンジニアに直で聞いてくれてたのでとても助かりました!ありがとうございます!

ただ若干グローブの着脱が難しい…かも Viveの頭のところのバンドを締める感じで腕に固定するんですが、 片手をつけた後にもう片方をつける時にグローブの素材がマジックテープにくっつくのでつらい()

ま まあ後は磁気なので気をつけるところはPerception Neuronに近いのかなと思ったり

まとめ

色々遊べるけど LeapMotionとの違いを見せつけるものにしような!!!

Hi 5 Gloveがはやくほしい(ください

【Unity】UNET(PC-Android) をしてみたお話

はじめに

UNETの基本的な使い方は我らが凹みTipsにまとまっています。

tips.hecomi.com

UNETのよくわからなさ加減はizmさんの記事の太字だけでもさらっと目を通すと、つらさがわかると思います…

qiita.com

いくつか抜粋します

対応策:スクリプトの名前を動くようになるまで適当に変えます。(つらい)

とか

NetworkSimulationは期待した通りに動きません

かなしみ

今回は個人的にハマったりしたポイントや理解しにくいとこをまとめてみます。 Android6.0.1(Galaxy S6 Edge)-PC(Windows 7)間の通信がメインです。

PCをHost、AndroidをClientとして考えます。

Unityは5.6.0f3です。

ちなみにUnityをまともに初めて2-3ヶ月くらいなので、間違いとかは多めに見て欲しいです…(間違いがあれば教えてください)

ハマリポイントたち

Androidでの実機テスト

いちいち実機に移してテストするのは面倒だったのでPCでテストして、区切りのいいとこで実機テストしてました。

怠惰ゆえにUnity-Android間でテストしたくなりますが、出来ないっぽい…?

一応NetworkManagerのnetworkAddressにPC側のIPAdressを設定していても駄目でした。 どうやら、Client側がHost側を見つけられない → TimeOut のようなので 同一LAN内からUnityEditorが見えてないのかなと思ったり。

そのため、毎回PC版ビルドとAndroidに転送しなければテストできない… (方法があれば教えてください…)

ちらっとようてんさんに聞いたところ、Android側が悪さをしている可能性があるらしく、カーネルをゴニョゴニョするといけるかもとのこと。(やりたくない

悩める民たち(解決してなさそう)

https://forum.unity3d.com/threads/wifi-issues-on-lan-or-android-client-windows-server.336183/#n10

この辺ググっても全然でなくてみんなPhoton使ってるのかな…

この記述をみてもしや…と思って出来たくらい情報がない…

ネットワーク上の別PCと通信するには、ビルドしたアプリを配布して行う。LAN Client にホスト側のIPを設定するのを忘れずに。

qiita.com

おまけ

実行時に勝手にServer、Clientを判断してStartするのはこんな感じで書きました。

こいつはNetworkConnector.csとして作成して、NetworkMangerがAttachされてるGameObjectに 一緒にAttachしてます。

using UnityEngine;
using UnityEngine.Networking;

public class NetworkConnector : NetworkBehaviour
{

    NetworkManager manager;

    //こいつを用意しておくとInspectorから変えれてPC上でのデバッグに割りと便利 お好みで
    public bool isStartAsHost = true;

    public string serverIPAdress = "(対象のPCのIPAdressをいれる 指定しないとlocalhostっぽい)";

    // Use this for initialization
    void Start()
    {
        manager = GetComponent<NetworkManager>();

        if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer)
        {
            if (isStartAsHost)
            {
                manager.StartHost();
                Debug.Log("Start as Host");
            }

            else
            {
                manager.networkAddress = serverIPAdress;
                manager.StartClient();
                Debug.Log("Start as Client");
            }

        }

        else if (Application.platform == RuntimePlatform.Android)
        {
            manager.networkAddress = serverIPAdress;
            manager.StartClient();
            Debug.Log("Start as Client");
        }
    }

}
}

参考

simplestar-tech.hatenablog.com

Attribute

UNETはAttributeをつけることで、いろいろ挙動を制御できます。 Serverだけで実行したい関数、ClientからServerにデータを送りたいなどなど。

あちこちみても、結局この図に集約されている気がします。

f:id:shop_0761:20170420000254j:plain

まず、冒頭の凹みTipsの記事より

まず大前提として、UNET では同じゲームのコードでクライアント・サーバ共に動かしています。サーバ専用の言語を覚えたりする必要はありません。

これを把握していないと混乱して死にます。(死んだ)

ちょっと言い換えると、"一つのソースでServer、Clientが共存している" といったイメージです。

なので、同じソース内でServerとClientのやり取りをすることになります。 (ココらへんは混乱ポイントな気がする)

ので、"この変数は今Clientで更新したんだな"とかを把握しておかなきゃいけないわけで…

イメージ図を書いてみました。こんな感じで共存しています。緑のやつが実際に呼べる関数です。

f:id:shop_0761:20170420012553p:plain

Attributeの中で一番ハマったのはCommand / ClientRpc Attributeです。

またまた凹みTipsより

クライアントからサーバへのコマンドの送信 Cmd から始まる関数に Command アトリビュートをつけるとサーバで実行されるクライアントから呼び出せる関数になる

サーバからクライアントの RPC(リモートプロシージャコール) Rpc から始まる関数に ClientRpc アトリビュートをつけるとクライアントで実行されるサーバから呼び出せる関数になる

ポイントは “○○で実行される△△から呼び出せる関数” の部分です。

ちょっと自己流に言い換えるなら “実行するのは○○にある関数だけど、呼べるのは△△からだけだよ” って感じだと思ってます。

この"△△からだけ"ってのが重要で、

凹みTipsにもある

ただし、サーバかクライアントかといったことや、参照しているオブジェクトが各クライアントから見てローカルなのかリモートなのかは強く意識する必要があります。

ここに繋がるのではないかと思ってます。

もちろん呼び出すところを間違えるとエラーが出ます。

ただし、izmさんの記事より

[ServerCallback] クライアントから呼ばない時に付けますがエラーや警告が出ません。

同様に

[ClientCallback] サーバーから呼ばない時に付けますがエラーや警告が出ません。

ので注意しましょう。

— 2017/04/24追記

また、NetworkManagerからPlayerとしてSpawnしたPrefabには権限(LocalPlayerAuthority)が付与されます。

権限がない他のPrefabからCommand Attribute のついた関数を呼び出そうとするとWarningが出ます。

Trying to send command for object without authority.

ので、基本的にはCommandはPlayerで使うものになりますが、Unity5.2から他のオブジェクトにも 権限を持たせられるようになったそうです。

詳しくはこちら

docs.unity3d.com


NetworkBehaviour を継承しておいて、 isServer、isClient、isLocalPlayerなどを使って分岐しましょう。

ただこれらも注意しないと同時にフラグが立ったりする可能性があるので、一応InspectorをDebug表示にするなどしてEditor上で確認するのがよいかと。

例) Hostとして起動した時のPlayer

f:id:shop_0761:20170420111259p:plain

参考

docs.unity3d.com

SyncVar

変数をServerとClientで同期できます。 が、

izmさんの記事より

変数をサーバーからすべてのクライアントに自動的に同期するために使用されます。クライアントからそれらに割り当てないでください。クライアント側での割り当ては無意味です

はい。 Clientで更新した変数はSyncVar Attributeで同期できません。

ので、こんな感じで書きました。

[SyncVar (hook = "OnUpdatePlayerID")]
int playerID = 0;

[Client]
void setPlayerID(int id){
  playerID = id;
  CmdUpdatePlayerID(id);
}

[Command]
void CmdUpdatePlayerID(int id)
{
    playerID = id;
}

[Client]
void OnUpdatePlayerID(int id)
{
  //処理
}

流れ

  1. ClientのどこかでsetPlayerID() -> ClientのplayerIDを更新 Syncされない
  2. CmdUpdatePlayerID() -> ServerのCmdUpdatePlayerID()を実行
  3. Server側のplayerIDが更新されるのでここでSyncする
  4. ついでにhookしておいたOnUpdatePlayerID()が呼べる(ただし、SyncしたのはClient側なのでClientで呼ばれる)

と、これを同一コード内でやるので、ごっちゃごちゃする可能性が…

hookのところはあってもなくてもおっけーです。(hook あまり自信ない…

hookに関してはこちらを

hiyotama.hatenablog.com

Network Message

Attributeよりわかりやすい気がします。(ただ、こいつも同じコード内でやり取りするとこを書くけど)

参考

docs.unity3d.com

適当に書いてみたやつを貼ります。Network Messageを使いたいコード内に書いちゃえば使えます。(やっつけ) まあFindしてるのは重たいのでホントはやらないほうがいいですが。

(手直ししてる部分があるので、あやしいとこがあるかも)

public NetworkClient client;
int playerID;

//MessageTypeを判別するのに使う
public class MyMsgTypes
{
    public static short MY_MES = 1001;
};

//送りたいMessageのクラス MessageBaseを継承しておくこと
public class MyMesssge : MessageBase
{
    public byte[] bytes;
    public Vector3 pos;
    public bool isHit;
    public int playerID;
}

public void SetupClient()
{
    NetworkManager manager = GameObject.Find("NetworkManager").GetComponent<NetworkManager>();
    Debug.Log("Find NetworkManager: " + manager);
    client = manager.client;
    client.RegisterHandler(MsgType.Connect, OnConnected);
    Debug.Log("Setup Client");
}

//OnHogehogeを登録しておく
public void SetupServer()
{
    NetworkServer.RegisterHandler(MyMsgTypes.MY_MES, OnHogehoge);
    Debug.Log("Setup Server");
}

//繋がったときに呼ばれる
public void OnConnected(NetworkMessage netMsg)
{
    Debug.Log("Connected to server");
}

//送る時用 適当に作った
//MyMessageをnewして、値をセットして、client.Send()すればなんでもいいはず
//Client Attributeをつけるといいかも
public void SendMes(){
    MyMesssge msg = new MyMesssge();
    msg.bytes = ...
    msg.pos = ...
    msg.isHit = ...
    msg.playerID = ...
    client.Send(MyMsgTypes.MY_MES, msg);
    Debug.Log("Send Msg");
}

//受け取ったときに呼ばれる 今回はServer側に登録してあるので、Serverで呼ばれる
public void OnHogehoge(NetworkMessage netMsg){
    MyMesssge msg = netMsg.ReadMessage<MyMesssge>();
    byte[] bytes = msg.bytes;
    Vector3 pos = msg.pos;
    bool isHit = msg.isHit;
    int playerID = msg.playerID;
    Debug.Log("recieved Msg");
}

RegisterHandlerでデリゲートを追加する感じで使えると思います。

SetupClientはあってもなくてもいいですが、client.Send()は使えるようにどこかでclientを格納しておく必要があります。

これはClient→Serverですが、RegisterHandlerを同じように使えば逆もできるはず…(やってないけど)

サンプルがpublicになってたので、なんとなくpublicにしてあります(変な地雷を踏みたくないので)

– 2017/04/25追記

playerにIDを割り振りたい

参考

hiyotama.hatenablog.com

だいたいどこを見ても、

playerNetID = GetComponent().netId;

で持ってきています。確かにユニークです。

ただ、playerに0始まりでIDを振りたいとなると話は別です。

ここから想像のお話なので、あってるかはわかりません。詳しくはソースを読んで下さい。

この netId 恐らくScene上のNetworkIdentity Component の数に依存している気がします。

というのも、netIdで取ってきた数値がなぜか 4 始まりだったので、

playerNetID = GetComponent<NetworkIdentity>().netId - 4;

とかやってました。

ですが、他のprefabでNetworkIdentityを使うことになったので、追加するとErrorが吐かれてしまいました。

つまり、今後SceneにUNET周りを使いたいPrefabなりなんなりが増えるたびにIDがズレます。

しかも恐らくplayerはSceneの最後でSpawnされるのかどんどん後ろにずれていく気がします。

        public override void OnStartLocalPlayer()
        {
            if (isClient)
            {
                playerID = GameObject.FindGameObjectsWithTag("MainCamera").Length - 1;
            }
        }

とかで取ってくるほうがよい気がしました…

想像おわり。

おまけ -AndroidでScreenShot-

普通はApplication.CaptureScreenshotを使うらしいのですが、 これは真っ黒になるので使えませんでした。

こちらを参考にRenderTexture経由のほうがよいです。

qiita.com

ついでに、保存先はAndroidの場合 Application.dataPath ではなく、 Application.persistentDataPathのほうがいいそうです。(というかこっちでないと保存できない)

PCに送りたいときはできたbyte配列をNetworkMessageで送ってやればよいです。 ただし、サイズが大きいと怒られるので分割して送って受信側でくっつけてやればよいです。 (正しく送れるとは言っていない)

おまけ2 同一LAN内のはずなのに繋がらない

Network初心者あるある(だと勝手に思ってる)

テスト環境で複数Wifiが飛んでいて、ついつい全て端末に登録しておくと 勝手にWifiを繋ぎ変えられてデバッグで死ぬ可能性があります。

そのため、1つしか登録しないとか、繋がらないときは端末のIPAdressに pingを飛ばして確認したほうがよいです。(1時間くらい悩んだ)

あとはTimeOutの時間を伸ばしておくと良いかもです。 NetworkManager → timeouts → Connect Timeout で設定できます。

まとめ

  • PC-Android間のデバッグはPC側もビルドしたものを
  • Command / ClientRpc Attributeはちょっと厄介かも
  • Network Message のほうがわかりやすい!便利!

さいごに

デバッグがつらい!! 毎回ビルドしなきゃいけない!!

聞いた話によるとPhotonのほうが楽らしいです。 そっちは見てないのでわかりません。

以上ここ1週間くらい格闘している(進行形)お話でした。 (つづくかも

なにかあれば@shop_0761まで

あなたにUNETのご加護があらんことを