naetoru2144
@naetoru2144

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

PUN2で位置が同期されない

Q&A

Closed

解決したいこと

他プレイヤーの回転に加えて、位置も同期したい

概要

Unityでオンラインゲームを制作しています。
同期のためのライブラリはPUN2,位置の同期にはPhotonTransformViewを使用しています。
相手プレイヤーの回転は同期されるのですが位置が同期されません。どうすればいいのでしょうか...

設定状況

  • プレイヤーオブジェクトに付いているPhoton関係のスクリプトは以下三つです
    • PhotonView
    • PhotonTransformView
      • PositionとRotationにチェック
    • PhotonAnimatorView
  • プレイヤーの親オブジェクトはありません

実際の動作動画

右側が操作している画面、左側がそれを見ている画面です。
位置は同期されておらず、回転とアニメーションは同期されている状況と解釈しています。

自分で試したこと

  • キャラクターを動かすスクリプトのUpdateの中身をPhotonView.isMineがTrueの時のみ実行するようにした
  • キャラクターを動かすスクリプト、ルームやキャラクターの作成を行うスクリプトの継承元を MonoBehaviourPunCallbacks に設定した

その他

他に必要な情報、コード等あれば追加致します

スクリプト

  • プレイヤーコントローラー
PlayerController.cs
using UnityEngine;
using Photon.Pun;

[RequireComponent(typeof(CharacterController))]
public class PlayerController : MonoBehaviourPunCallbacks
{
  [SerializeField] private float moveSpeed = 3;
  [SerializeField] private float runSpeed = 5;
  [SerializeField] private float jumpPower = 8;
  [SerializeField] private Animator animator;
  [SerializeField] private earthground _earthground;
  [SerializeField] private GameObject Camera;
  private bool _pastgrounddetection;
  private CharacterController _characterController;
  private Transform _transform;
  private Vector3 _moveVelocity;
  private Vector3 _eulerAngles;
  PhotonView PV;
    
  private void Awake()
  {
    PV = GetComponent<PhotonView>();
  }

  private void Start()
  {
    //CharacterControllerとtransformを取得
    _characterController = GetComponent<CharacterController>();
    _transform = transform;
    
    if(!PV.IsMine)
      {
        Destroy(GetComponentInChildren<Camera>().gameObject);
        Destroy(GetComponent<Rigidbody>());
        //Destroy(GetComponent<CharacterController>());
      }
  }

  private void FixedUpdate()
  {
    //isMineは正常に動作
    Debug.Log(PV.IsMine);
    if( PV.IsMine == false ) return;//追加

    // 移動のための入力受付
    _moveVelocity.x = Input.GetAxis("Horizontal") * moveSpeed;
    _moveVelocity.z = Input.GetAxis("Vertical") * moveSpeed;
    
    // カメラの回転をキャラクタの回転に反映
    _eulerAngles = Camera.transform.rotation.eulerAngles;
    transform.rotation = Quaternion.Euler( 0, _eulerAngles.y, 0);

    // ジャンプの入力受付とキャラクタのジャンプ動作
    if (_earthground.ground_detection == true)
    {
      if (Input.GetKey(KeyCode.Space))
      {
        _moveVelocity.y = jumpPower;
        animator.SetBool("is_jumping", true);
      }
      else
      {
        animator.SetBool("is_jumping", false);
      }
    }
    else
    {
      //もし地面に接触していなければ重力の加速
      _moveVelocity.y += Physics.gravity.y * Time.deltaTime;
    }
    
    if( _pastgrounddetection == false && _earthground.ground_detection == true)
    {
      animator.SetBool("is_jumping", false);
    }

    _pastgrounddetection = _earthground.ground_detection;

    //shiftで走らせる
    if (Input.GetKey(KeyCode.LeftShift) && (_moveVelocity.x != 0 || _moveVelocity.z != 0))
    {
      animator.SetBool("is_running", true);
      _moveVelocity.x = Input.GetAxis("Horizontal") * runSpeed;
      _moveVelocity.z = Input.GetAxis("Vertical") * runSpeed;
    }
    else
    {
      animator.SetBool("is_running", false);
    }

    if (Input.GetMouseButton(0))
    {
      animator.SetTrigger("shot");
    }
    
    //↑で取った左右入力を反映して移動
    _characterController.Move(transform.rotation * _moveVelocity * Time.deltaTime);
    
    animator.SetFloat("MoveSpeed", new Vector3(_moveVelocity.x, 0, _moveVelocity.z).magnitude);
  }
}

  • ルーム作成
RandomMatchMaker.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun; // ★追加
using Photon.Realtime; // ★追加

public class RandomMatchMaker : MonoBehaviourPunCallbacks
{
    public GameObject Player;
    void Start()
    {
        PhotonNetwork.ConnectUsingSettings();
    }
    
    public override void OnConnectedToMaster()
    {
        PhotonNetwork.JoinRandomRoom();
    }

    public override void OnJoinedLobby()
    {
        PhotonNetwork.JoinRandomRoom();
    }

    public override void OnJoinRandomFailed(short returnCode, string message)
    {
        RoomOptions roomOptions = new RoomOptions();
        roomOptions.MaxPlayers = 8; // 最大8人まで入室可能
        PhotonNetwork.CreateRoom(null, roomOptions); //第一引数はルーム名
    }

    public override void OnJoinedRoom()
    {
        PhotonNetwork.Instantiate(
        "Player",
        new Vector3(Random.Range(0f,20f),Random.Range(0f,20f), Random.Range(0f,20f)),   //ポジション
        Quaternion.identity,    //回転
        0
    );
    }
}


0

2Answer

前回の質問にも追伸しましたが、念のためこちらにも

なるほど、ありがとうございました。
スクリプトを再度拝読しましたら、遅ればせながら原因がわかった気がします。
移動を、スクリプト側ではなく、Animator経由で行っていることが間接的に原因となっていることと推察しています。
僕もまだまだPUN2の理解が甘いので、どうしてPhotonTransformViewで座標を完全に同期できないのか説明ができないのですが、PUN2からはPhotonAnimationViewが用意されているので、これがカギになりそうだと感じています。
一度PhotonAnimationViewを設定するとどうなるか、試していただけないでしょうか。

0Like

Comments

  1. @naetoru2144

    Questioner

    ありがとうございます。こちら回答いたしました。ご確認の方よろしくお願いいたします。

自己解決

CharacterController.Move()とPhotonTransformViewを同時に使うと、位置が同期されなくなるようです。移動をAddforceにした所解消されました。

0Like

Your answer might help someone💌