facebook twitter hatena line email

Unity/photon/fusion/SharedMode

提供: 初心者エンジニアの簡易メモ
移動: 案内検索

公式

始め方 https://doc.photonengine.com/ja-jp/fusion/current/tutorials/shared-mode-basics/1-getting-started

準備

  1. アセットのシリアル化を実行 [Edit > Project Settings > Editor > Asset Serialization > ModeのForce Text] (初期設定なので、設定されてるかも)
  2. Mono Cecilのインストール(Window > Package Manager > 右上+をクリック > Add package from git URL、"com.unity.nuget.mono-cecil"で、追加)
  3. Unity/photon/fusion/インストール [ショートカット]

シーン初期設定

  1. 空のシーンを作成
  2. Window/Fusion/GameObject/Setup/Networkingを選択し、"Prototype Network Start"と、"Prototype Runner"を、追加する。
  3. Unityを再生すると、Start~な感じのダイアログが出て実行できることを確認。
  4. SharedModeにするために、"Prototype Network Start"のStartModeをAutomaticにして、AutoStartAsをSharedにする。

clientCountが0エラーが出る場合

エラー詳細

GameMode is set to Shared, and clientCount is set to zero. Starting no network runners.

対応方法

  1. "Phototype Network Start"のStartModeを、UserInterfaceにして、起動時にSharedを選択すれば、このエラーは消える

同期キャラクタ作成

  1. 空オブジェクトを作成し、名前を"PlayerCharacter"に
  2. 作ったObjectのInspectorを開いて、NetworkObjectを、AddComponentする。
  3. 一旦、NetworkObjectの"Destroy When State Authority Leaves"にチェックして、削除同期させる。
  4. Allow State Authority Overrideのチェックを外して、他のクライアントが操作できるようにする。
  5. CharacterControllerをAddComponentする。これはキャラ操作用。
  6. NetworkTransformをAddComponentする。
  7. 3dObject/Capsuleを作成し、"Interpolation Target"に名前を変更する。CapsuleColliderを削除。それを、PlayerCharacterの下に、移動。
  8. PlayerCharacterのNetworkTransformのInterpoplationTargetに、↑で作成したInterpoplationTargetを入れる。
  9. PlayerCharacterをProject側のPrefabsのディレクトリに移動。

プレイヤー生成

using Fusion;
using UnityEngine;
public class PlayerSpawner : SimulationBehaviour, IPlayerJoined
{
    public GameObject PlayerPrefab;

    public void PlayerJoined(PlayerRef player)
    {
        if (player == Runner.LocalPlayer)
        {
            Runner.Spawn(PlayerPrefab, new Vector3(0, 1, 0), Quaternion.identity, player);
        }
    }
}
  1. PlayerSpawner.csを作り、上記をコピペ。
  2. "Prototype Runner"オブジェクトに、PlayerSpawnerをAddComponentする

プレイヤー操作

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Fusion;

public class PlayerMovement : NetworkBehaviour
{
    public Camera Camera;
    float PlayerSpeed = 10f;
    private Vector3 velocity;
    CharacterController Controller;
    private void Start()
    {
        velocity = Vector3.zero;
        Controller = GetComponent<CharacterController>();
    }
    public override void FixedUpdateNetwork()
    {
        // Only move own player and not every other player. Each player controls its own player object.
        if (!HasStateAuthority)
        {
            return;
        }
        //var cameraRotationY = Quaternion.Euler(0, Camera.transform.rotation.eulerAngles.y, 0);
        //Vector3 move = cameraRotationY * new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")) * Runner.DeltaTime * PlayerSpeed;
        Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")) * Runner.DeltaTime * PlayerSpeed;
        if (Controller != null)
        {
            Controller!.Move(move + velocity * Runner.DeltaTime);
        }

        if (move != Vector3.zero)
        {
            gameObject.transform.forward = move;
        }
    }
    public override void Spawned()
    {
        if (HasStateAuthority)
        {
            Camera = Camera.main;
            Camera.GetComponent<FirstPersonCamera>().Target = GetComponent<NetworkTransform>().InterpolationTarget;
        }
    }
}

  1. PlayerMovement.csを作成して、上記をコピペ
  2. PrefabのPlayerCharacterオブジェクトに、PlayerMovementをAddComponentする

HasStateAuthorityは、自分のプレイヤーのときのみ、trueとなる。

一人称カメラ設定

using UnityEngine;

public class FirstPersonCamera : MonoBehaviour
{
    public Transform Target;
    public float MouseSensitivity = 10f;

    private float vertialRotation;
    private float horizontalRotation;

    void LateUpdate()
    {
        if (Target == null)
        {
            return;
        }

        transform.position = Target.position;

        float mouseX = Input.GetAxis("Mouse X");
        float mouseY = Input.GetAxis("Mouse Y");

        vertialRotation -= mouseY * MouseSensitivity;
        vertialRotation = Mathf.Clamp(vertialRotation, -70f, 70f);

        horizontalRotation += mouseX * MouseSensitivity;

        transform.rotation = Quaternion.Euler(vertialRotation, horizontalRotation, 0);
    }
}
  1. FirstPersonCamera.csを作成して、上記をコピペ
  2. MainCameraオブジェクトに、FirstPersonCameraをAddComponentする