孙广东  2015.7.21

本节提供了与网络系统一起使用的组件的具体信息。

1、Network Animator



NetworkAnimator 用于跨网络同步动画。

Properties

Property:

Function:

animator

要同步的对象上的Animator 组件。

Details  暂无

2、NetworkBehaviour

NetworkBehaviours 是特别脚本。用于处理对象上的 NetworkIdentity 组件。这些脚本都能够执行 HLAPI 。像Commands、 ClientRPCs、 SyncEvents 和 SyncVars 等功能。

与Unity Network Systemserverauthoritative 权威系统。网络对象的 NetworkIdentities 必须是“spawned”,由server使用 NetworkServer.Spawn()。这会导致他们被分配一个NetworkInstanceId,在连接到server的client上创建。

Properties

Property:

Function:

isLocalPlayer

True if this object is the player object for the local client.

isServer

True if this object is running on the server, and has been spawned.

isClient

True if this object is running on a client.

hasAuthority

True if this object is the authoritative version of the object. So either on the server, or on the client with localPlayerAuthority.

assetId

This is the assetId of the object’s NetworkIdentity.

netId

This is the netId of the object’s NetworkIdentity.

playerControllerId

This is the playerControllerId of the object’s NetworkIdentity.

connectionToServer

NetworkConnection object to use to send to the server.

connectionToClient

NetworkConnection object to use to send to the client.


NetworkBehaviours 具有下面的特点,介绍例如以下。

• Synchronized Variables 同步变量
• Network callbacks 网络回调
• Server and Client functionsserver和client功能
• Sending Commands发送命令
• Client RPC Calls client RPC 调用
• Networked Events 网络事件

unity网络同步复盘_unity网络同步复盘


Synchronized Variables
同步的变量
NetworkBehaviours 成员变量能够从server同步到client。由于该server是有权威在此系统中。同步是仅在  server到client  的方向。

客户请求做的事情是通过命令Commands处理,不是从client同步的变量。

SyncVar 属性用于 标记 成员变量,如  正在同步。

SyncVars 能够是不论什么 基本类型、 不是类、 列表或其它集合。

public class SpaceShip : NetworkBehaviour
{
    [SyncVar]
    public int health;

    [SyncVar]
    public string playerName;
}

SyncVar 的值在server上更改。它将发送到全部的游戏中准备好的clients 。当 生成对象 时。client上创建他们从server的全部 SyncVars 的最新状态。

Network callbacks
网络回调

有各种 网络事件的 NetworkBehaviour 脚本调用的回调函数。

这些是对基类 虚函数,所以它们能够被重写在使用这种代码:

public class SpaceShip : NetworkBehaviour
{
    public override void OnStartServer()
    {
        // disable client stuff
    }

    public override void OnStartClient()
    {
        // register client events, enable effects
    }
}

当对象在server上被生成或当server启动时 对场景中的对象   调用 OnStartServer 函数。  当对象在client被生成 。或者当client连接到server以进行场景中的物体,将调用 OnStartClient 函数。

这些函数是实用的, 去做那些特定于client或server的事,  比如suppressing effects 抑制效应在server上,或设置client事件。

      请注意,当使用的是local client 本地client,这两个函数将被同一个对象调用。

其它回调包含:
• OnSerialize - called to gather state to send from the server to clients 调用以收集状态将从server发送到client
• OnDeSerialize - called to apply state to objects on clients 调用以将状态应用于client上的对象
• OnNetworkDestroy - called on clients when server told the object to be destroyed 当server告诉要被销毁的对象在client上调用
• OnStartLocalPlayer - called on clients for player objects for the local client (only)
• OnRebuildObservers - called on the server when the set of observers for an object is rebuild
• OnSetLocalVisibility - called on a host when the visibility of an object changes for the local client
• OnCheckObserver - called on the server to check visibility state for a new client

Server and Client functions
server和client功能

NetworkBehaviours 中的成员函数能够用来   自己定义属性  来指定它们 作为 仅server或仅client的功能标记。

比如:

using UnityEngine;
using UnityEngine.Networking;

public class SimpleSpaceShip : NetworkBehaviour
{
    int health;

    [Server]
    public void TakeDamage( int amount)
    {
        // will only work on server
        health -= amount;
    }

    [Client]
    void ShowExplosion()
    {
        // will only run on client
    }

    [ClientCallback]
    void Update()
    {
        // engine invoked callback - will only run on client
    }
}

这些属性  使函数马上返回, 假设他们在client或server未处于活动状态时调用。

他们不会生成编译时错误,但假设调用错误的范围内,他们将发出警告日志消息。ServerCallback 和 ClientCallback 的属性能够用于用户代码不能控制的调用的引擎回调函数。

这些属性不会导致生成的警告。

Sending Commands
发送命令

     命令是为client请求做某事  在server上的方式。

由于 HLAPI 是一个server的权威系统,客户能够仅仅通过命令做事情。

发送该命令的client上的player 对象相应的server上执行命令。这种路由会自己主动发生,client一个不同的player发送命令它是不可能的。

命令必须以  前缀"Cmd" 开头和有  [Command] 自己定义属性,例如以下面:

using UnityEngine;
using UnityEngine.Networking;

public class SpaceShip : NetworkBehaviour
{
    bool alive;
    float thrusting;
    int spin;

    [Command]
    public void CmdThrust(float thrusting, int spin)
    {   
        if (!alive)
        {
            this.thrusting = 0;
            this.spin = 0;
            return;
        }
            
        this.thrusting = thrusting;
        this.spin = spin;
    }

    [ClientCallback]
    void Update()
    {
        int spin = 0;
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            spin += 1;
        }
        if (Input.GetKey(KeyCode.RightArrow))
        {
            spin -= 1;
        }
        // this will be called on the server
        CmdThrust(Input.GetAxis("Vertical"), spin);
    }
}

        命令被调用。通常在client上  。可是,而不是命令函数在client上执行的 ,它将在该server上的clientPlayer对象调用。因此,命令是类型安全,有内置的安全机制和路由到player,以及使用參数有效的序列化机制,使高速调用它们。

Client RPC Calls
client RPC 调用

      client RPC 调用是   一个server对象 让  client对象 做一些事情的方式。

这是和怎样用命令发送消息 方向相反。但概念是同样的。client RPC 调用然而不仅仅调用player对象,他们能够在不论什么 NetworkIdentity 对象上调用。必须曾经缀 "Rpc" 开头,而且必须 [ClientRPC] 的自己定义属性,像下面:

using UnityEngine;
using UnityEngine.Networking;

public class SpaceShipRpc : NetworkBehaviour
{
    [ClientRpc]
    public void RpcDoOnClient(int foo)
    {
        Debug.Log("OnClient " + foo);
    }

    [ServerCallback]
    void Update()
    {
        int value = UnityEngine.Random.Range(0,100);
        if (value < 10)
        {
            // this will be invoked on all clients
            RpcDoOnClient(value);
        }
    }
}



Networked Events
网络的事件

      网络的事件就像   client RPC 调用,但不是仅仅在client对象上调用一个函数,client对象上的事件将被触发。为事件 注冊的其它脚本 然后调用 -  參数在server上,所以这使得网络的client上脚本间交互。

事件必须曾经缀 “Event” 开头而且有 SyncEvent 的自己定义属性。

事件能够用于生成功能强大的网络游戏系统。能够通过其它脚本扩展。此演示样例演示怎样影响脚本在client上的能够响应由server上的战斗脚本生成的事件。

using UnityEngine;
using UnityEngine.Networking;

// Server script
public class MyCombat : NetworkBehaviour
{
    public delegate void TakeDamageDelegate(int side, int damage);
    public delegate void DieDelegate();
    public delegate void RespawnDelegate();
    
    float deathTimer;
    bool alive;
    int health;

    [SyncEvent(channel=1)]
    public event TakeDamageDelegate EventTakeDamage;
    
    [SyncEvent]
    public event DieDelegate EventDie;
    
    [SyncEvent]
    public event RespawnDelegate EventRespawn;

    [Server]
    void TakeDamage(int amount)
    {
        if (!alive)
            return;
            
        if (health > amount) {
            health -= amount;
        }
        else
        {
            health = 0;
            alive = false;
            // send die event to all clients
            EventDie();
            deathTimer = Time.time + 5.0f;
        }
    }

    [ServerCallback]
    void Update()
    {
        if (!alive)
        {
            if (Time.time > deathTimer)
            {
                Respawn();
            }
            return;
        }
    }

    [Server]
    void Respawn()
    {
        alive = true;
        // send respawn event to all clients
        EventRespawn();
    }
}



Hints

  • This is a base class that provides Commands and ClientRpc calls.