Unity之UNet学习之旅(一)

本文介绍使用Unity UNet组件开发局域网游戏的过程。包括自定义网络管理器和发现组件、实现局域网扫描及连接、创建和加入游戏会话等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UNet组件是unity自带制作网络游戏的强大组件,在unity5.x之前叫做NetworkView,之后新为UNet。刚开始接触UNet,开始第一步旅行。首先大致了解一下UNet制作局域网游戏的框架。

首先上图,了解下NetworkManger和Network Discovery两个组件;  

  

这是unity提供的2个组件,也是我们要用的组件,其参数后面进行详解~

(1)制作两个场景,Scene1为开始场景(UI场景),Scene2为游戏主场景(Game场景),这个就不说了(太过Easy~);

(2)编写UNet框架,直接上代码吧,有注释哟~

~~~~~NetworkDiscoveryCustom.cs~~~~~~

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

/// <summary>
/// 扫描局域网
/// </summary>
public class NetworkDiscoveryCustom : NetworkDiscovery {
    // 
    public override void OnReceivedBroadcast(string fromAddress, string data)
    {
        StopBroadcast();
        NetWorkMangerCustom.singleton.networkAddress = fromAddress;
        NetWorkMangerCustom.singleton.StartClient();
    }
}


~~~~~~NetworkMangerCustom.cs~~~~~

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.Match;
using UnityEngine.SceneManagement;


public class NetWorkMangerCustom : NetworkManager {
    // 单人模式
    public static void SingPerson()
    {
        singleton.StartHost(singleton.connectionConfig, 1);
    }

    // 局域网模式
    public static void LanGame()
    {
        singleton.StartCoroutine((singleton as NetWorkMangerCustom).DiscoveryNetwork());
    }

    /// <summary>
    /// 开启协程扫描局域网
    /// </summary>
    /// <returns></returns>
    public IEnumerator DiscoveryNetwork()
    {
        NetworkDiscovery discovery = GetComponent<NetworkDiscoveryCustom>();
        discovery.Initialize(); // 初始化
        discovery.StartAsClient(); // 扫描局域网内的服务器,如果有,就直接加入
        yield return new WaitForSeconds(1);

        // 如果没有找到局域网内的服务器
        if (discovery.running)
        {
            discovery.StopBroadcast(); // 停止广播
            yield return new WaitForSeconds(0.5f);
            discovery.StartAsServer(); // 把自己作为服务器,进行广播
            StartHost(); // 同时作为服务端 and 客户端启动
            //StartServer(); // 只作为服务端
            //StartClient(); // 只作为客户端
        }
    }

    // 网络模式
    public static void NetGmae()
    {
        singleton.StartMatchMaker(); // 表示UNet网络功能,发起请求
        singleton.matchMaker.ListMatches(0,4,"",false,0,0,singleton.OnMatchList);
                // 参数1:表示list的第几页
                // 参数2:表示每一页的个数
                // 参数3:目标房间的名称
                // 参数4:是否返回带有密钥的房间
                // 参数5:关于竞赛方面的设置?(不明白)
                // 参数6:一个 "域" ,表示只能从这个 "域" 上返回房间
                // 参数7:回调函数
    }
    public override void OnMatchList(bool success, string extendedInfo, List<UnityEngine.Networking.Match.MatchInfoSnapshot> matchList)
    {
        if (!success)
        {
            return;
        }
        if (matchList != null)
        {
            List<MatchInfoSnapshot> availableMatches = new List<MatchInfoSnapshot>();
            foreach (MatchInfoSnapshot match in matchList)
            {
                // 当前玩家数
                if (match.currentSize < match.maxSize)
                {
                    availableMatches.Add(match); // 保存房间没满的情况
                }
            }
            // 判断列表数量是否为0
            if (availableMatches.Count == 0)
            {
                // 创建服务器
                CreateMatch();
            }
            else
            {
                // 加入服务器
                matchMaker.JoinMatch(availableMatches[Random.Range(0,availableMatches.Count - 1)].networkId,"","","",0,0,OnMatchJoined);
            }
        }
    }
    /// <summary>
    /// 通知UNet创建网络服务器
    /// </summary>
    void CreateMatch()
    {
        matchMaker.CreateMatch("",matchSize,true,"","","",0,0,OnMatchCreate);
                // 参数1:房间名
                // 参数2:房间中的玩家数
                // 参数3:
                // 参数4:服务器密码
                // 参数5:Client IP地址(公网)
                // 参数6:私网地址
                // 参数7:
    }
    public override void OnMatchCreate(bool success, string extendedInfo, MatchInfo matchInfo)
    {
        if (!success)
        {
            return;
        }
        StartHost(matchInfo); // 利用 UNet 返回的 matchInfo 创建服务器
    }

    public override void OnMatchJoined(bool success, string extendedInfo, MatchInfo matchInfo)
    {
        if (!success)
        {
            // 重新加载当前场景
            int CurrentScene = SceneManager.GetActiveScene().buildIndex;
            SceneManager.LoadScene(CurrentScene);
            return;
        }
        StartClient(matchInfo); 
    }
}




~~~~添加Button事件~~~~~~


以上就是本次全部代码啦~~


(3)在主场景中添加游戏物体,然后将其制作为预制体,并添加NetworkIdentity标识!


(4)在主场景中创建一个空物体,将上面的NetworkManger和Network Discovery添加到空物体上


(5)注意:一定要将主场景添加到途中OnlineScene中,打开SpawnInfo,将Player Prefab选中为当前游戏物体预制体


(6)将Scene1和Scene2添加到BuildSettings里面,点击Build

(7)运行Build后生成的 exe 程序,就会有如下效果:
这是两个客户端运行结果,可以看到两个客户端均创建了2游戏物体Cube










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值