Network 官方案例

2020-12-24 19:59发布

此案例完成了在局域网的多人对战,,,下面是实现过程,,,


1,创建空物体添加Network Manager 和 NetworkManagerHUD组件:

1

运行游戏场景就可以看到,,如下图:

2,创建PlayerPrefab,,,(自定义主角),,然后添加组件Network Identity(勾选die日哥复选框,Local Player Authority),并且将创建好的预值体,赋值给Network Manager面板的Spawn Info下的Play Prefab

3

4

3,编写PlayerMove脚本控制主角移动,,代码如下:就可以在客户端只控制自己的代码了,,

public class PlayerMove : NetworkBehaviour  //更改了继承

{

    void Update()

    {

        if (!isLocalPlayer)   //若不是本地的主角则不产生操作

        {

            return;

        }

        float h = Input.GetAxis("Horizontal");

        float v = Input.GetAxis("Vertical");


        this.transform.Translate(new Vector3(0, 0, -v * Time.deltaTime *10));

        this.transform.Rotate(new Vector3(0, h * 6, 0));


      }

    }

4,同步客户端和服务端的主角位置,,在主角的预制体上添加Network transform,,注意是在Player预制体上添加此组件,,,

5

5,用颜色区分游戏对象哪个是自己控制的,,,接着上面的代码编写:

   //此方法在启动本地角色的时候调用 -- 控制主角场景中显示

    public override void OnStartLocalPlayer()

    {

        GetComponent<MeshRenderer>().material.color = Color.yellow;

    }

运行结果:

6,控制主角的射击,,首先创建出子弹预制体,并且添加Rigidboy组件,,在Player预制体下创建一个空物体,用于控制生成子弹的位置,,,然后继续编写上面的代码:

void CmdFire()  //在Update中设置条件调用

    {

        //生成子弹预制体

        GameObject go = Instantiate(prefabBill, BillPos.transform.position, BillPos.transform.rotation);

        //给子弹初速度

 go.GetComponent<Rigidbody>().velocity = -go.transform.forward * 5;

        //3秒后销毁预制体

 Destroy(go,3f);

    }

7,子弹的同步:在子弹预制体上添加组件,NetworkIdentity 组件和 NetworkTransform 组件然后更改同步信息为Rigidboy3D,,, 
7 
然后将子弹的预制体添加到NetWork Manager 上,以同步服务端数据: 
8


控制主角和子弹的完整代码:

using UnityEngine;

using UnityEngine.Networking;


public class PlayerMove : NetworkBehaviour

{

    public GameObject prefabBill;    //子弹的预制体

    public Transform BillPos;        //子弹生成的位置


    void Update()

    {

        if (!isLocalPlayer)   //若不是本地的主角则不产生操作

        {

            return;

        }

        float h = Input.GetAxis("Horizontal");

        float v = Input.GetAxis("Vertical");


        this.transform.Translate(new Vector3(0, 0, -v * Time.deltaTime *10));

        this.transform.Rotate(new Vector3(0, h * 6, 0));


        if (Input.GetMouseButtonDown(0))

        {

            CmdFire();

        }

    }


    //该特性表示在服务端调用此方法,运行是在客户端(同步)

    [Command]

    void CmdFire()  //方法名一定是Cmd开头

    {

        //子弹的生成需要在Sever端,然后同步到客户端,,

        GameObject go = Instantiate(prefabBill, BillPos.transform.position, BillPos.transform.rotation);

        go.GetComponent<Rigidbody>().velocity = -go.transform.forward * 5;

        Destroy(go,3f);

        //生成指定的游戏物体在客户端

        NetworkServer.Spawn(go);

    }

    //启动本地角色的时候调用 -- 控制主角场景中显示

    public override void OnStartLocalPlayer()

    {

        GetComponent<MeshRenderer>().material.color = Color.yellow;

    }    

}

8,添加血量和进行血量控制: 
编写脚本,(给需要血量的游戏物体添加)

using UnityEngine;

using UnityEngine.Networking;

using UnityEngine.UI;


public class Health : NetworkBehaviour {


    public Slider healehSlider;


    //同步变量 从服务端到客户端   (hook = "方法名",,每当此变量发生变化就调用方法)

    [SyncVar(hook = "OnChangeHealth")]

    public const int maxHealth = 100;

    public int curHealth = maxHealth;


    public void Damager(int damage)

    {

        //只在服务端计算血量,,,

        if (isServer == false) return;


        curHealth -= damage;

        if (curHealth <= 0)

        {

            curHealth = 0;

            Debug.Log("TODO  DEAD");

        }

        //控制血条的显示

        healehSlider.value = curHealth / (float)maxHealth;

    }


    /// <summary>

    /// 同步到客户端的血量数据

    /// </summary>

    void OnChangeHealth(int health)

    {

        healehSlider.value = health / (float)maxHealth;

    }

}

给子弹添加碰撞事件,即碰撞到有血量的物体,游戏对象就掉血:

public class Bullet : MonoBehaviour {

    private void OnCollisionEnter(Collision collision)

    {

        GameObject hit = collision.gameObject;

        Health health = hit.GetComponent<Health>();


        if (health != null)

        {

            health.Damager(10);

        }


        Destroy(this.gameObject);

    }

}

9,添加血条进行显示血量,,, 
创建UGUI下的 Slider,,调整为血条的样子,然后将Canvas调整为Player的子物体,Slider的位置调整到人物的上面,并且叫Canvas的Reader Mode 属性设置为World Space 如下图:

这样发布出来,即可多个人连接起来玩耍了,,,我在这里没有完善死亡后的消失,重生的状态,,基本思路的是死亡销毁,然后随机位置生成,这样就可以完成多人对战了,,,



作者:Czhenya

链接:https://czhenya.blog.csdn.net/article/details/78309812

来源:CSDN
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。