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

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

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

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

Q&A

解決済

1回答

1852閲覧

Client側からもOwner側からも変更できるNetworkVarialbleを作りたい

Ro_bo_t

総合スコア4

Unity

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

0グッド

0クリップ

投稿2023/02/12 08:49

編集2023/02/13 02:11

実現したいこと

マルチプレイヤーゲームで変数をClient側からも書き換えられるようにしたい。

前提

NetCode For GameObject を使って2Dパズルゲームを作っています。
その中のギミックの一つに重力を反転させるという機能を搭載しようと思い、それを実際に搭載してみたところOwner側からは問題なく動きましたが、Client側からはうまく作動しませんでした。
NetworkVariableで重力の状態をBool値で格納して、それを直接切り替えることで重力を変えています。

発生している問題・エラーメッセージ

InvalidOperationException: Client is not allowed to write to this NetworkVariable
Unity.Netcode.NetworkVariable`1[T].set_Value (T value) (at Library/PackageCache/com.unity.netcode.gameobjects@1.1.0/Runtime/NetworkVariable/NetworkVariable.cs:64)
GameManager.ChangeG () (at Assets/GameManager.cs:22)
GravityChanger.OnTriggerEnter2D (UnityEngine.Collider2D collision) (at Assets/Script/GravityChanger.cs:12)

該当のソースコード

当たったら重力を反転させる機能

C#

1using UnityEngine; 2public class GravityChanger : MonoBehaviour 3{ 4 public GameManager gameManager; 5 private void OnTriggerEnter2D(Collider2D collision) 6 { 7 collision.GetComponent<Rigidbody2D>().velocity = Vector2.zero; 8 gameManager.ChangeG(); 9 } 10}

重力を実際に反転させているスクリプト。

C#

1using Unity.Netcode; 2using UnityEngine; 3 4public class GameManager : NetworkBehaviour 5{ 6 public NetworkVariable<bool> GravityN = new NetworkVariable<bool>(true, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server); 7 private void Update() 8 { 9 if (GravityN.Value) 10 { 11 NormalGravity(); 12 } 13 else 14 { 15 OppGravity(); 16 } 17 } 18 public void ChangeG() 19 { 20 GravityN.Value = !GravityN.Value; 21 } 22 private void NormalGravity() 23 { 24 Physics2D.gravity = new Vector2(0, -9.8f); 25 } 26 private void OppGravity() 27 { 28 Physics2D.gravity = new Vector2(0, 9.8f); 29 } 30}

試したこと

元々このように1つ目のコード内で全て済ませようとしていたが動かなかったので、今の次第になりました。

C#

1using System.Collections; 2using System.Collections.Generic; 3using Unity.Netcode; 4using UnityEngine; 5 6public class GravityChanger : NetworkBehaviour 7{ 8 private NetworkVariable<bool> GravityN = new NetworkVariable<bool>(true); 9 private void OnTriggerEnter2D(Collider2D collision) 10 { 11 GravityN.Value = !GravityN.Value; 12 } 13 private void Update() 14 { 15 16 if (GravityN.Value) 17 { 18 OppGravity(); 19 } 20 else 21 { 22 NormalGravity(); 23 } 24 } 25 private void NormalGravity() 26 { 27 Physics2D.gravity = new Vector2(0, -9.8f); 28 29 } 30 private void OppGravity() 31 { 32 Physics2D.gravity = new Vector2(0, 9.8f); 33 } 34}

RPCを使うという情報が調べたら出てきましたが、RPCは関数を呼び起こすもので共通のBool値を使うことはできなそうだったのでRPCでの解決方法もいまいちわからず何時間も画面と睨めっこをすることになってしまいました。

補足情報(FW/ツールのバージョンなど)

全て2023/2/10最新バージョンを使用しています
初めてマルチプレイヤーゲームを作っているのでいまいち仕組みを理解できていません。

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

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

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

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

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

guest

回答1

0

ベストアンサー

私、普段は別のゲームサーバーライブラリを使っているのであまりよくわからないのですが

https://forum.unity.com/threads/networkvariable-write-permission.1176548/
そもそもNetworkVariableは通常クライアントからはリードオンリーの仕様に見えました
素直にRPCで変数同期シーケンスを組むしかないと思います・・・
まあErrorMessageが Client is not allowed to write to this NetworkVariable って言ってる時点で権限がないよいわれてるのでお察しですよねえ・・

https://docs-multiplayer.unity3d.com/netcode/current/basics/networkvariable/index.html#custom-networkvariable-implementations

公式ドキュメントより引用

Write Permissions# There are two options for writing a NetworkVariable.Value: Server(default): the server is the only one that can write the value. This is useful for server side specific states that all clients should should be aware of but can't change. Some examples would be an NPC's status (health, alive, dead, etc) or some global world environment state (that is, is it night or day time?). Owner: This means only the owner of the NetworkObject can write to the value. This is useful if your NetworkVariable represents something specific to the client's player that only the owning client should be able to set This might be a player's skin or other cosmetics

リアルタイムでクライアント間で値を共有する為の機能ではないと思います
恐らく最初に部屋に入った際に設定したい情報を格納する為の機能じゃないでしょうか

投稿2023/02/13 09:43

編集2023/02/13 09:44
UnitySoldier

総合スコア207

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

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

Ro_bo_t

2023/02/13 14:26

ありがとうございました。 NetworkVariableはそのような目的のものなのですね。書き換えることができないとは言われていましたができないなら使い道がないと思って何かうまい方法があるかと思っていました。 RPCに変えたことで、Client側から実際に動かすことはできましたが今度は3秒程度の遅延が発生したりと他の不具合が出てきました。Netcodeは公式リファレンス以外の情報がかなり少ないため過去に使ったことがありコミュニティの情報も豊富なPhotonにツールを変更してそれを使うことにしました。
UnitySoldier

2023/02/13 17:53

あとクソ老婆心というかウルトラ蛇足なんですけど >全て2023/2/10最新バージョンを使用しています Unityでこの表現は辞めた方が良いと思いますよ Unityエディタのライフサイクル上、Unity2020,2021のLTSチャンネルの更新 Unity2022のTechStreamの更新 Unity2023.1 β,αチャンネルの更新が毎月毎週のように走っているのでこれだと本当になにも伝わりません 本当の意味の最新だと先週水曜リリースのUnity 2023.1.0b3になるんですけど流石にbetaチャンネルのUnityをわざわざ新物にぶつけにいくってことはないでしょうしちゃんと書きましょうよ たかだか数行じゃないですか
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問