unity官方内置网络unet的实例

一、添加网络管理组件

新创建一个网络管理器。该网络管理器将控制该项目的网络状态,包括游戏状态管理,生成点管理,场景管理,配对和允许访问相关信息。对于高级用户,可以从NetworkManager派生一个类来自定义组件的行为,扩展未涵盖的NetworkManager

二、创建角色预制体:

NetworkIdentity组件介绍:网络物体最基本的组件,客户端与服务器确认是否是一个物体(netID),也用来表示各个状态,如是否是服务器,是否是客户端,是否有权限,是否是本地玩家等。

三、控制角色移动

四、控制角色射击

子弹预制体的设置

子弹生成:

子弹销毁为什么不用同步,是因为服务端是母体,服务端的销毁掉,客户端自然就会被销毁

五、血量的减少

制作血条:

注意:血量减少,因为服务器是母体,为了防止母体子弹销毁时,客户端子弹还没有碰撞到角色,血量不能及时减少,造成数据不同步,因此血量的控制检测只能是在服务器进行计算并同步到客户端

 

子弹添加碰撞脚本

  

六、控制人物的重生

设置重生点:

  

七、控制敌人的生成

  

敌人在每个客户端都要产生,所以敌人产生在服务端来做,将产生的敌人同步到客户端上

  

RPC是远程调用(服务端与客户端互调用),调用服务器端的某个方法,使用Comond,想调用客户端的某个方法使用ClientRPC,

SyncVar是同步一个变量,比如同步主角的血量,

hook,指定一个字符串参数,这个参数指定方法的名字,变量的值发生改变时,调用Hook指定的方法。

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class PlayerController : NetworkBehaviour {

    public GameObject bulletPrefab;
    public Transform bulletSpawn;	
	// Update is called once per frame
	void Update () {
        if (isLocalPlayer == false)
        {
            return;
        }
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");

        transform.Rotate(Vector3.up * h * 120 * Time.deltaTime);
        transform.Translate(Vector3.forward * v * 3 * Time.deltaTime);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            CmdFire();
        }
	}  
    [Command]//这个命令, 各个客户端会调用这个方法,但是运行是在服务器端运行的
    void CmdFire()//这个方法需要在server里面调用,必须以Cmd开头
    {
        // 子弹的生成 需要server完成,然后把子弹同步到各个client
        GameObject bullet = Instantiate(bulletPrefab, bulletSpawn.position, bulletSpawn.rotation) as GameObject;
        bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * 10;//给初速度
        Destroy(bullet, 2);
        NetworkServer.Spawn(bullet);//网络生成子弹,同步到客户端,如果没有这句代码的的话,另外一个客户端是看不到子弹的生成的
      //bullet 属于网络的一个东西,这句只是把子弹物体分发给了客户端,但是没有给客户端的子弹给与速度
    }
    public override void OnStartLocalPlayer()
    {
        //这个方法只会在本地角色那里调用  当角色被创建的时候
        GetComponent<MeshRenderer>().material.color = Color.blue;
    }
}
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.Networking;
public class Health : NetworkBehaviour {
    public const int maxHealth = 100;
    //下面SyncVar同步的功能会一直检测,检测到之后会调用这个方法,每个客户端都会调用的
    [SyncVar(hook="OnChangeHealth") ]
    public int currentHealth = maxHealth;
    public Slider healthSlider;
    public bool destroyOnDeath = false;//为true,表示是敌人,要销毁   
    public void TakeDamage(int damage) //下面是在服务端执行的方法
    {
        if (isServer == false) return;// 血量的处理只在服务器端执行
        currentHealth -= damage;
        if (currentHealth <= 0)
        {
            if (destroyOnDeath) //表示是敌人,要销毁
            {
                Destroy(this.gameObject); return;
            }
             currentHealth = maxHealth;//死亡之后,当前血量恢复到最大血量            
            RpcRespawn();//不是敌人的话,要重生
        }
    }
    //上面定义同步变量,更新变化后的变量
    void OnChangeHealth(int health)
    {
        healthSlider.value = health / (float)maxHealth;
    }
    //设置重生点
    private NetworkStartPosition[] spawnPoints;
    void Start()
    {
        if (isLocalPlayer)
        {
            spawnPoints = FindObjectsOfType<NetworkStartPosition>();
        }
    }
    /// <summary>
    /// 人物重生,这个方法应该在客户端调用
    /// </summary>
    [ClientRpc]
    void RpcRespawn()
    {
        if (isLocalPlayer == false) return;

        Vector3 spawnPosition = Vector3.zero;

        if (spawnPoints != null && spawnPoints.Length > 0)
        {
            spawnPosition = spawnPoints[Random.Range(0, spawnPoints.Length)].transform.position;
        }
        transform.position = spawnPosition;
    }
}

 

using UnityEngine;
using System.Collections;

public class Bullet : MonoBehaviour {
    void OnCollisionEnter(Collision col)
    {
        GameObject hit = col.gameObject;
        Health health = hit.GetComponent<Health>();

        if (health != null)
        {
            health.TakeDamage(10);
        }
        Destroy(this.gameObject);
    }

}
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class EnemySpawner : NetworkBehaviour {

    public GameObject enemyPrefab;
    public int numberOfEnemies;
    public override void OnStartServer()
    {
        for (int i = 0; i < numberOfEnemies; i++)//敌人的数量
        {
            Vector3 position = new Vector3(Random.Range(-6f, 6f), 0, Random.Range(-6f, 6f));

            Quaternion rotation = Quaternion.Euler(0, Random.Range(0, 360), 0);

            GameObject enemy = Instantiate(enemyPrefab, position, rotation) as GameObject;

            NetworkServer.Spawn(enemy);//同步到客户端,同步到网络上
        }  
    }
	

}