前提・実現したいこと
Unityでオンラインマルチプレイ対応のお絵描きアプリ(スマホ版お絵かきの森のようなもの)を作成しています。
PUN2を使って同期処理の実装をしているのですが、描画の部分での同期がうまくいきません。
同期自体はできるのですが、実際に描画した側と、同期をとって描画された側とでかなり描画に差が出てしまいます。
下記の画像のような感じになります。
ちなみに描画自体は、下記のスクリプトをアタッチした「LineRenderer」をコンポーネントとして持つオブジェクト(プレハブ)をPhotonNetwork.Instantiateで生成して行っています。
発生している問題
Update関数での描画処理に対して、IPunObservable.OnPhotonSerializeViewでのポジションの値の送受信が少ない?為か、
同期した側がカクカクで描画されてしまう。
該当のソースコード
C#
using System.Collections; using System.Collections.Generic; using UnityEngine; using Photon.Pun; public class Paint : MonoBehaviourPunCallbacks, IPunObservable { LineRenderer paint; //描画担当 Vector3 mousePosition; //タッチした座標 Vector3 position; //タッチした座標を変換した値 int count; //頂点の数 bool paintOn; //描画するかどうか void Start() { paintOn = true; //paintの初期設定 paint = GetComponent<LineRenderer>(); paint.startWidth = 0.1f; paint.endWidth = 0.1f; paint.material.color = Color.black; mousePosition = Input.mousePosition; //タッチした場所の座標を取得 position = Camera.main.ScreenToWorldPoint(mousePosition); //座標の変換 if((2.7f > position.x) && (position.x > -2.7f) && (2.2f > position.y) && (position.y > -3.4f)){ //描画範囲内か確認 count += 1; paint.positionCount = count; //頂点の数設定 paint.SetPosition(count - 1, new Vector3(position.x, position.y, 1f)); //描画処理 } } void Update() { if(paintOn == true){ if(Input.GetMouseButton(0)){ mousePosition = Input.mousePosition; position = Camera.main.ScreenToWorldPoint(mousePosition); if((2.7f > position.x) && (position.x > -2.7f) && (2.2f > position.y) && (position.y > -3.4f)){ count += 1; paint.positionCount = count; paint.SetPosition(count - 1, new Vector3(position.x, position.y, 1f)); } } if(Input.GetMouseButtonUp(0)){ paintOn = false; //指を離したら、このオブジェクトでの描画を終わる } } } void IPunObservable.OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info){ if(stream.IsWriting){ if(count > 0){ stream.SendNext(position.x); stream.SendNext(position.y); } } else { //描画した側の座標を受け取って、他クライアント側でも描画する position.x = (float)stream.ReceiveNext(); position.y = (float)stream.ReceiveNext(); paint = GetComponent<LineRenderer>(); Vector3 pos = new Vector3(position.x, position.y, 1f); count += 1; paint.positionCount = count; paint.SetPosition(count - 1, pos); } } }
考えた対策案
①数秒ごとに同期させて、完全なリアルタイムではなく、徐々に絵を他のクライアントに見せる。
②同期できるポジションの値をどうにかして増やす。
③カメラを同期させて、描画している部分を映す。(カメラの同期なんてない?)
などを考えてみましたが、正直①~③のどれもどうやっていいのか分かりません。
①~③のどれかは実現できるのか、他に対策があるのか、そもそも描画処理自体を別の方法で行った方が良いのかなど、
何かアドバイスが欲しいです。よろしくお願いします!
補足情報
PCはWindows10を使用しています。
Unityのバージョンは2019.3.13です。
まだ回答がついていません
会員登録して回答してみよう