Unity は Mirror を使用して LAN 同期を作成します

1. スクリプト レイアウト: 実稼働用の戦車デモを参照してください。

1. スクリプトを管理するオブジェクトである新しい空のオブジェクト (manager) を作成し、NetworkManager、kcpTransport、NetworkManagerHud をマウントします 2. プレーヤー
のスポーン ポイント、spawnPoint を設定し、初期位置 (*) を設定し、NetworkStartPosition スクリプトをマウントします
3. 新しいプレーヤー プレハブ、NetworkIdentity、NetworkTransform (信頼性が低い) をマウントするためのスクリプト、および独自のカスタム スクリプトを作成します。カスタム スクリプトは NetworkBehaviour を継承する必要があることに注意してください。編集時に変更する必要があります。以下はメイン プレーヤーのモバイル コードです。 MainPlayerControll.cs.
4. 新しいタレット プレハブを作成し、rigibody、NetworkIdentity、TurretMove をマウントします、「rigibody は重力をオフにする必要があります」。

using Mirror;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;

public class MainPlayerControll : NetworkBehaviour
{
    
    
    public float speed = 5;
    public float Rspeed = 25;
    public GameObject turretPrefab;
    public Transform firepoint;
    [SyncVar] public int health = 10;
    int lastHealth = 0;
    public TextMesh nameTxt;
    public override void OnStartLocalPlayer()
    {
    
    
        base.OnStartLocalPlayer();
        Camera.main.transform.SetParent(transform);
        Camera.main.transform.localPosition = new Vector3(0, 0.5f, 0);
        Camera.main.transform.localRotation = Quaternion.identity;
    }
    public override void OnStopLocalPlayer()
    {
    
    
        base.OnStopLocalPlayer();
        Camera.main.transform.SetParent(null);
    }
    void Update()
    {
    
    
        if (health != lastHealth)
        {
    
    
            nameTxt.text = $"{
      
      gameObject.name} <color=red>{
      
      health}</color>";
            lastHealth = health;
        }
        if (!isLocalPlayer) return;

        float horizontalInput = Input.GetAxis("Horizontal");
        float verticalInput = Input.GetAxis("Vertical");

        Vector3 movement = transform.forward * verticalInput * speed * Time.deltaTime;
        Vector3 rotation = new Vector3(0f, horizontalInput * Rspeed * Time.deltaTime, 0f);

        transform.Translate(movement, Space.World);
        transform.Rotate(rotation);
        if (Input.GetKeyDown(KeyCode.Space))
        {
    
    
            CmdFire();
        }
    }
    [Command]
    void CmdFire()
    {
    
    
        GameObject projectile = Instantiate(turretPrefab, firepoint.position, firepoint.rotation);
        NetworkServer.Spawn(projectile);
    }
    [ServerCallback]
    void OnTriggerEnter(Collider other)
    {
    
    
        if (other.GetComponent<TurretMove>() != null)
        {
    
    
            --health;
            if (health == 0)
                NetworkServer.Destroy(gameObject);
        }
    }
}
using Mirror;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TurretMove : NetworkBehaviour
{
    
    
    public float destroyAfter = 2;
    public Rigidbody rigidBody;
    public float force = 1000;
    public override void OnStartServer()
    {
    
    
        Invoke(nameof(DestroySelf), destroyAfter);
    }

    void Start()
    {
    
    
        rigidBody.AddForce(transform.forward * force);
    }

    // destroy for everyone on the server
    [Server]
    void DestroySelf()
    {
    
    
        NetworkServer.Destroy(gameObject);
    }
    [ServerCallback]
    void OnTriggerEnter(Collider co) => DestroySelf();
}

2. 注: マネージャーの NetworkManager では、PlayerPrefab に値を割り当て、生成されたプレーヤー プレハブをドラッグし、トランスポート内の同じオブジェクトの kcpTransport コンポーネントをドラッグする必要があります。PlayerspawnMethod は RoundRobin を選択します
。プレーヤー プレハブは弾丸プレハブ内にドラッグする必要があります。また、発射ポイントもドラッグする必要があります。発射ポイントは、空のオブジェクトを作成し、それを発射ポイントとしてプレーヤー上に配置することです。弾丸は独自のリジボディをドラッグするだけで済みます
。 TurretMode.cs スクリプトに追加します。

メイン プレーヤー スクリプトのブロードキャスト フィールドは、次のように宣言する必要があります。 [SyncVar] public int health = 10;

一部の受動的な衝突の場合、[ServerCallback] もトリガー メソッドに追加する必要があります。

  [ServerCallback]
    void OnTriggerEnter(Collider other)
    {
    
    
        if (other.GetComponent<TurretMove>() != null)
        {
    
    
            --health;
            if (health == 0)
                NetworkServer.Destroy(gameObject);
        }
    }

発砲などのアクティブなトリガー: [コマンド]を追加する必要があります

    [Command]
    void CmdFire()
    {
    
    
        GameObject projectile = Instantiate(turretPrefab, firepoint.position, firepoint.rotation);
        NetworkServer.Spawn(projectile);
    }

要約:

[コマンド]: クライアント上でサーバー上のメソッドを呼び出すために使用されます。クライアントはこのタグを使用してサーバー上のメソッドを呼び出し、それらをコマンドとして処理できます。メソッド名は「Cmd」で始まる必要があります。
[ClientRpc]: サーバー上で呼び出され、接続されているすべてのクライアント上で実行されるメソッド用。サーバーはこのタグを使用してメソッドを呼び出し、接続されているすべてのクライアントでメソッドを実行できます。メソッド名は任意に付けることができます。
[TargetRpc]: サーバー上で呼び出され、特定のクライアント上で実行されるメソッドです。サーバーはこのタグを使用してメソッドを呼び出し、特定のクライアント上でメソッドを実行できます。メソッド名は任意に付けることができます。
[ServerCallback]: メソッドがクライアントではなくサーバーでのみ実行されることを示すために使用されます。このタグは、サーバー上で特定のロジックを定義したり、サーバー側でイベントを処理したりするために使用されます。メソッド名は任意に付けることができます。

予防:

[Command]、[ClientRpc]、および [TargetRpc] メソッドは、NetworkBehaviour から継承するスクリプトで使用する必要があり、ネットワーク接続と同期設定の正しい構成が必要です。
[Command]メソッドはクライアントからのみ呼び出すことができ、サーバー上でのみ実行されます。
[ClientRpc] メソッドはサーバー上でのみ呼び出すことができ、接続されているすべてのクライアント上で実行されます。
[TargetRpc] メソッドはサーバー上でのみ呼び出すことができ、特定のクライアント上でのみ実行できます。
[ServerCallback] メソッドはサーバー上でのみ実行され、クライアントでは実行されません。

メソッド開始ルール:

[Command]タグのメソッド名は「Cmd」で始まる必要があります。
[ClientRpc]タグ、[TargetRpc]タグ、[ServerCallback]タグのメソッド名は任意に付けることができます。

おすすめ

転載: blog.csdn.net/kuilaurence/article/details/132874985