質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

2085閲覧

unityでマルチプレイヤー用の関数を呼ぶことが出来ない

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2017/05/17 17:14

###前提・実現したいこと
unityでマルチプレイヤー用に関数を呼んでクライアント間でデータをやりとりしたい。

###発生している問題・エラーメッセージ
ホストからクライアントの関数を呼ぶことはできるが、クライアントからホストの関数を呼ぶことが出来ない。

###該当のソースコード
動作確認のため、NetworkBehaviourを継承した以下のようなソースを記述しています。

[SyncVar (hook = "HookChangeName")]
private string name = "";

public void ChangeName(){
Debug.Log("call ChangeName");

string create_name = "";
for(int i = 1; i <= 4;i++) create_name += Random.Range(0,10);

name = create_name;
name_label.text = name + ":ChangeName";
CmdChangeName(name);
}

private void HookChangeName(string set_name){
Debug.Log("call HookChangeName");
name = set_name;
name_label.text = name + ":HookChangeName";
CmdChangeName(name);
}

[Command]
private void CmdChangeName(string set_name){
Debug.Log("call CmdChangeName");
name = set_name;
name_label.text = name + ":CmdChangeName";
}
###試したこと
上記コードは動作確認用に「ChangeName」関数を呼ぶと適当な名前を生成し、それの表示と名前を各クライアントで共有する、というものです。
このコードで、ホストで「ChangeName」関数を実行すると、「ChangeName」、「HookChangeName」、「CmdChangeName」、「CmdChangeName」の順に呼ばれ、
クライアントでは「HookChangeName」のみが呼ばれ、確かにホスト側で生成した名前が表示されます。

しかし、クライアントで「ChangeName」関数を実行しても、
name変数が変更されたことによる「HookChangeName」も、明示的に実行している「CmdChangeName」も呼ばれず、
ホスト側ではいずれの関数も呼ばれません。従って、クライアントで生成した名前をホスト側に渡すことが出来ません。

クライアントからホストの関数を呼ぶにはどうすればよいのでしょうか?

クライアント間の通信には「Network Manager HUD」を使用し、
ホスト側では「Enable Match Maker」から「Create Internet Match」を、クライアント側では「Find Internet Match」で作成したマッチに接続しています。

###補足情報
unityのverは5.5.0f3 personalです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

よくわからんけど参考書を買って自己解決しました

投稿2017/07/08 07:43

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ホストには、サーバーとローカルクライアントがありますので、サーバーの状態でなくローカルクライアントの状態を見てるだけではありませんか?

[Command]と“Cmd” プレフィックスのように、[ClientRpc]と“Rpc” プリフィックスがありますので
サーバーへ届いていれば、今度はサーバーから呼ぶクライアントの関数につけてみてはどうでしょうか?

投稿2017/05/26 03:56

tmp

総合スコア277

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/05/26 08:59

ご回答ありがとうございます。 しかし、「ClientRpc」を使用した関数を呼び出すようにしても、やはり動作しませんでした。 「サーバーの状態でなくローカルクライアントの状態を見てるだけではありませんか? 」という言葉の意味がよくわからないのですが、こちらはどういう意味でしょうか?
tmp

2017/05/29 08:48

まことに申し訳ございません。間違っていました。 SyncVarのhookの関数は、サーバーで変化があった場合に、クライアントで呼ばれますのでクライアントで変更しても呼ばれません。 次に、CmdChangeNameですが、これはクライアントに権限があるオブジェクトから呼ばれた場合のみサーバーで実行されます。 (NetworkIdentityのLocal Player Authorityにチェックをつけたもの) 例えば、CmdChangeNameがネットワークと関係ないGUIなどから呼ばれた場合は、実行されませんが、今回の場合、ChangeNameをどのように読んでいますか?
退会済みユーザー

退会済みユーザー

2017/06/12 09:24

回答、ありがとうございます。 まずは、確認が非常に遅くなってしまい、大変申し訳ありませんでした。 「CmdChangeName」の呼び方ですが、確かに「CmdChangeName」を呼んでいる「ChangeName」はネットワークと関係なく、 NGUIでラベルを作成し、ラベルを選択したときに、呼ぶという処理でした。 ですので、「ChangeName」が含まれているコードをアタッチしているラベルに「NetworkIdentity」をアタッチして、「Local Player Authority」をチェック、という方法と、 適当なオブジェクトを作成し、「ChangeName」が含まれているコードをアタッチ、「NetworkIdentity」をアタッチして、「Local Player Authority」をチェック、 ラベルを押したとき、このオブジェクトの「ChangeName」関数を実行させる。 という2種類の方法を試したのですが、どちらもクライアントで「ChangeName」関数を実行しても、「CmdChangeName」関数が実行されることはありませんでした。
tmp

2017/06/12 15:44

チェック付きでも、それらを外部から呼んでは実行されません、 「NetworkIdentity」の「Local Player Authority」チェック付きのUpdate内から呼んでみてください。
退会済みユーザー

退会済みユーザー

2017/06/14 16:45

ご回答、ありがとうございます。 以下のようにボタンを押したときにフラグをたて、Updateから呼ぶようにしたのですが、やはり実行されませんでした。一旦諦めようと思います。ありがとうございました。 void Update () { if(call_cmd){ call_cmd = false; Debug.Log("CmdChangeName"); CmdChangeName(player_name); } }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問