zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Network 官方案例

案例官方 Network
2023-09-11 14:20:51 时间

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


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

1

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

2

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 如下图:

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