unet多人联机

首先添加两个组件


Paste_Image.png

运行后我们可以发现大致的联机已经完成


Paste_Image.png

多人联机我们在玩家游戏对象上添加两个组件。
Paste_Image.png
玩家移动

然后我们再添加一个移动的脚本,写入代码。

using UnityEngine.Networking;

public class PleyerController : NetworkBehaviour {


    
    // 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);
    }

最后我们打包出来测试下,我们把Unity当作服务器和客户端,把打包出来的当做客户端.我们可以发现这样就已经连接上了。因为都是本地IP所以没有设置IP地址。端口号是系统默认的端口7777。


Paste_Image.png
区分敌我

下面我们再来看看怎么区分敌我,附上代码

// <summary>
    /// 这个方法区分敌我,自身玩家设置为蓝色,敌人是白色.
    /// </summary>
    public override void OnStartLocalPlayer()
    {
        //这个方法只会在本地角色那里调用,当角色被创建的时候
        GetComponent<MeshRenderer>().material.color = Color.blue;
    }
Paste_Image.png
发射子弹

首先我们在子弹的预制物上加上Network Identity组件,并且将生成的子弹上传到网络上。


Paste_Image.png

下面我们来让我们的游戏对象拥有射击功能,看看怎么做吧,先附上射击的代码。这个CmdFire()方法我们在玩家Player预制物的Update里面调用

    public GameObject BulletPrefab;
    public Transform bulletSpawe;
    private float BulltSpeed = 2000f;

  [Command]//表示虽然客户端调用这个方法,但是运行是在服务端运行.
    void CmdFire()
    {//命名必须Cmd开头
        GameObject bullet = Instantiate(BulletPrefab, bulletSpawe.position, bulletSpawe.rotation);
        bullet.GetComponent<Rigidbody>().velocity = -bullet.transform.forward * BulltSpeed * Time.deltaTime;
        Destroy(bullet, 2f);
        NetworkServer.Spawn(bullet);//生成指定的物体同步到各个客户端
    }

随后我们又发现子弹是同步了,但是子弹的速度没有同步过来,So我们将NetworkTransform组件也加上来,NetworkTransform不仅能同步Transform还能同步Rigibody.


Paste_Image.png

这下我们可以发现子弹都已经同步上了。


Paste_Image.png
控制UI血量值同步

当你添加血量减少受到伤害的方法后你会发现服务端和客户端的血量值并不是同步的,那么是为什么呢,这是因为服务器端在发射子弹后敌人的血量在减少同时子弹也被销毁了,那么客户端就有可能无法同时受到伤害因为在服务器端子弹已经被销毁了,那么我们如何去实现同步能,这里我们只能让子弹伤害在服务端去运行然后在同步到所有的客户端。下面我们附上代码.将这个血量的脚本挂载在Player游戏对象上.

using UnityEngine.Networking;


public class Health : NetworkBehaviour {
   public Slider HealthSlider;

    public const int MaxHealth = 100;
    [SyncVar (hook ="OnChangeHealth")]//同步变量,表示这个变量同步到各个客户端
    public int curentllealth = MaxHealth;
    //血量减少的方法,受到伤害
    public void TakeDamage(int damage) {
        if (isServer == false) return;//血量的处理只在服务器端执行
        curentllealth -= damage;
        if (curentllealth<=0) {
            curentllealth = 0;
            Debug.Log("Death");
        }  
    }
    void OnChangeHealth(int health) {
        HealthSlider.value = health / (float)MaxHealth;
    }
}

然后我们在创建一个脚本这个脚本挂载在我们的子弹上,里面写入它的碰撞方法。

public class Bullet : MonoBehaviour {
private void OnCollisionEnter(Collision collision)
    {
        if (collision.transform.tag=="Player") {
            GameObject hit = collision.gameObject;
            Health health = hit.GetComponent<Health>();
            if(health!=null){
                health.TakeDamage(20);
            }
            Destroy(this.gameObject);
        }
    }
}

这样我们就同步了血量伤害的减少


Paste_Image.png
重生到随机的某几个位置

首先我们先随便创建一个位置点空物体。在其上面添加组件Network Start Position。这个是在服务器开始的时候指定一个位置,然后我们在多创建一个位置同意添加这个组件。让我们的玩家在这两个位置随机生成。


Paste_Image.png

然后我们将Player Spawn Met的参数设置为Round Robin指轮流在这两个位置转换.


Paste_Image.png
然后我们在血量的脚本上附上代码
 private NetworkStartPosition[] SpawnPosition;
void Start() {
        if (isLocalPlayer) {
            SpawnPosition = FindObjectsOfType<NetworkStartPosition>();
        }
    }
 //重生
    [ClientRpc]//客户端远程调用
    void Rpcespawn() {//命名必须Rpc开头
        if (isLocalPlayer==false) {
            return;
        }
        Vector3 spawnposition = Vector3.zero;
        if (SpawnPosition!=null&& SpawnPosition.Length>0) {

            spawnposition = SpawnPosition[Random.Range(0, SpawnPosition.Length)].transform.position;
        }
        transform.position = spawnposition;
    }

然后我们将重生的方法调用到血量小于等于0的时候


Paste_Image.png
敌人的随机生成
using UnityEngine.Networking;

public class EnumSpwen : NetworkBehaviour {


    public GameObject Onemyprefab;
    public int numberOfEnemies;

    //会在服务器启动的时候调用
    public override void OnStartServer()
    {
        for (int i=0;i< numberOfEnemies;i++) {
            Vector3 position = new Vector3(Random.Range(-6f, 6f), 0f,Random.Range(-6f,6f));
            Quaternion rotation = Quaternion.Euler(0, Random.Range(0, 360), 0);
            GameObject enemy = Instantiate(Onemyprefab,position,rotation);
            NetworkServer.Spawn(enemy);
        }
    }
Paste_Image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容