Unity5之Network子弹发射客户端同步显示

接着上一篇博客,继续讲解Network的功能。本节讲,如何发射子弹,并且同步到各个客户端。

下来我们先做第一步,单机版如何生成子弹发射。

首先把在主角下制作一个Spawn用来做生成点。


然后做一个子弹命名为bullet,要给子弹加个Rigidbody组件,因为我们要使用这个方法让子弹飞。


接下开始写代码,如下:

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class playernetwork : NetworkBehaviour
{

    [SerializeField]
    public Camera fpscamera;
    public GameObject CUBE;
    public GameObject Bulletprefab,Spawn;

    // Use this for initialization
    void Start()
    {

        if (isLocalPlayer)//只有本客户端的角色才会执行

        {
            GetComponent<CharacterController>().enabled = true;
            GetComponent<UnityStandardAssets.Characters.FirstPerson.FirstPersonController>().enabled = true;
            fpscamera.enabled = true;          

        }
    }
    void Update()
    {
        //不是本地角色就返回
        if (isLocalPlayer == false)
        {
            return;
        }

        if (Input.GetKeyDown(KeyCode.K))
        {
            Debug.Log("FIRE");
            Fire();
        }
    }
    //生成子弹方法
    void Fire()
    {
        GameObject bullets = Instantiate(Bulletprefab,Spawn.transform.position, Spawn.transform.rotation)as GameObject;

        bullets.GetComponent<Rigidbody>().velocity=bullets.transform.forward*30f;

        //两秒后销毁
        Destroy(bullets,2);
    }
    /// <summary>
    /// 这个方法只会在本地角色那里调用,当角色被创建的时候就被调用
    /// </summary>
    public override void OnStartLocalPlayer()
    {
        CUBE.GetComponent<MeshRenderer>().material.color = Color.blue;
    }
}

接下来把对应的东西放到代码里对应的位置,如图:


这样按键盘K键就可以生成子弹,并且子弹向前飞走,在2秒后自动销毁。

--------------------------------------上面是单机版生成子弹方法,下面讲如何在network里实现同步功能----------------------------------------------------------------------------------------------------------------------------------------------------

首先要明白,生成子弹的地方肯定是服务器,而客户端只是去看到。

子弹要同步飞行,那必须要添加上network Identity 和 network Transform组件,同时设置如下图:

这里解释一下设置:sync Rigidbody 3D是为了同步刚体进行子弹飞行。network send rate 是指要同步的频率,这里子弹只要同步一次能够飞行就可以了所以设置为0,表示同步速率就一次。


既然要在服务器生成,那必然要在networkmanager里添加上子弹的prefab,如图:

注意:要在networkmanager里添加的物体身上必须有network Identity组件(此处bullet已经添加过)。


接下来就是对代码的改动了,如下:

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class playernetwork : NetworkBehaviour
{

    [SerializeField]
    public Camera fpscamera;
    public GameObject CUBE;
    public GameObject Bulletprefab, Spawns;

    // Use this for initialization
    void Start()
    {

        if (isLocalPlayer)//只有本客户端的角色才会执行

        {
            GetComponent<CharacterController>().enabled = true;
            GetComponent<UnityStandardAssets.Characters.FirstPerson.FirstPersonController>().enabled = true;
            fpscamera.enabled = true;

        }
    }
    void Update()
    {
        //不是本地角色就返回
        if (isLocalPlayer == false)
        {
            return;
        }

        if (Input.GetKeyDown(KeyCode.K))
        {
            Debug.Log("FIRE");
            CmdFire();
        }
    }
    //生成子弹方法 ---加上了command后,此方法虽然写在了客户端代码里,但在服务端运行;而且方法名必须以Cmd开头!!!
    [Command]
    void CmdFire()
    {
        GameObject bullets = Instantiate(Bulletprefab, Spawns.transform.position, Spawns.transform.rotation) as GameObject;

        bullets.GetComponent<Rigidbody>().velocity = bullets.transform.forward * 30f;
        //两秒后销毁
        Destroy(bullets, 2);


        //服务器把生成的子弹同步到全部客户端
        NetworkServer.Spawn(bullets);


    }
    /// <summary>
    /// 这个方法只会在本地角色那里调用,当角色被创建的时候就被调用
    /// </summary>
    public override void OnStartLocalPlayer()
    {
        CUBE.GetComponent<MeshRenderer>().material.color = Color.blue;
    }
}
这里来解释一下command 方法。在一个方法上面加上了[command]后,表示此方法虽然写在了客户端代码里,但会在服务端运行而不是在客户端运行;而且方法名必须以Cmd开头,所以把之前的Fire修改为了CmdFire。

 NetworkServer.Spawn(bullets);这个是network里的一个方法,表示服务器把生成的子弹同步到全部客户端。否则此处,客户端是看不到有子弹生成的。

这样就完成了所有的功能了。运行效果如下(一个客户端,一个服务器端):



猜你喜欢

转载自blog.csdn.net/alayeshi/article/details/80409122
今日推荐