読者です 読者をやめる 読者になる 読者になる

simplestarの技術ブログ

目的を書いて、思想と試行、結果と考察、そして具体的な手段を記録します。

Unity:UNETの使い方3

クライアントからサーバーに任意の情報を渡す方法を確認します。

ここまで UNET を使って、HUDに頼らず、どこからでもサーバーに繋がることが確認できています。

UNET にはプレイヤーオブジェクトという特殊なオブジェクトが存在していて
このプレイヤーオブジェクトのみがサーバーにコマンドを送ることができる仕組みとなっています。

もう一度大切なことなので繰り返しますが
"プレイヤーオブジェクトのみがサーバーにコマンドを送ることができる"

なので Command を実行するのは PlayerObject でなければなりません。

クライアントでボタンを押すと、サーバーとクライアントで数字がインクリメントされるという仕組みを書いてみます。
次のスクリプトをプレイヤーオブジェクトに設定します。

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class NetworkCommander : NetworkBehaviour {

    public delegate void RingBellDelegate();

    [SyncEvent]
    public event RingBellDelegate EventRingBell;

    [SyncVar]
    public int syncVal;

    // Use this for initialization
    void Start () {
        EventRingBell += SomeEventHandler;
    }
	
    [Command]
    void CmdIncrement()
    {
        ++syncVal;
        if (null != EventRingBell)
        {
            EventRingBell();
        }
    }
}

プレイヤーオブジェクトは接続が済んだときに生成されるオブジェクトなので
ボタン押下イベントとの結び付けは自分で行う必要があります。

例えば、タグや名前でシーンに検索をかけて、あるボタンイベントに CmdIncrement を結び付けるといった
低速で同期変更の見落としが発生しやすい、バグの温床となりうる機構を書かなければいけません。

SyncEvent も同じく、シーンのどのオブジェクトのどのクラスの関数をハンドラとして設定するのか
生成されたプレイヤーオブジェクトがそれをシーンから探し出し、イベントに追加する必要があります。

SyncEvent が機能しなかったので、使い方について何度も確認しました。
腹立たしいことに、現在 SyncEvent が機能しないというバグがUnityに入っています。

issuetracker.unity3d.com

Fixed となっていますが、まだ修正版は入手できません。
5.3.1 では直っていません。

SyncEvent からネットワークゲームが始まるわけですが…
Unity 5.3 の更新早くしてー!

追記:2016.01.20
Unity - Unity QA - Patch Releases
5.3.1p3 が 1/14 に出ました!
(755450) - Networking: Fixed SyncEvent regression issue.
と修正されたことが明記されています。
確認してみましょう。

確認できました!
よく直してくれた!

以下、過去記事のまま残してあります。

とりあえず、クライアント側にはイベントが飛んできませんが、サーバー側ではイベントが発行されるので
サーバーだけ意図した動作となります。

これなんですが、サーバーのゲーム画面です。
f:id:simplestar_tech:20151227134842p:plain

家のPCでゲームを起動し、Androidデバイスにも同じゲームを入れて
家は下北沢なのですが、新宿まで移動してAndroid側でゲームを起動して
タップしてゲームを終了して家に戻ってきました。

するとこんな感じで数字がインクリメントされていたのです。
これには感動しました。

はやくネットワークゲーム作りたい!