Unity Netcode for GameObjects(多人联机小Demo)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

Netcode for GameObjects 是 Unity 官方推出的一套用于开发多人网络游戏的框架,旨在简化基于 Unity 引擎的多人游戏开发流程。它允许开发者轻松地在多个客户端之间同步游戏对象(GameObject)的状态、处理网络通信以及管理玩家连接等核心功能,尤其适合中小型多人游戏项目。

链接: 官方地址

一、安装 Netcode for GameObjects

打开 Unity 项目(建议使用 Unity 2021.3 或更高版本)。

进入 Package Manager(Window → Package Manager)。

点击左上角 "+" 图标 → Add package by name...

输入包名 com.unity.netcode.gameobjects 并安装(确保勾选 "Enable Preview Packages" 以获取最新版本)。

直接搜索下载也可以。

二、做个小Dome

doem的内容就是:一个客户端随机移动圆球位置,其他客户端会同步显示变化。

1.NetcodeManageNet

创建一个场景,在场景创建一个空物体挂载NetcodeManage组件,并选择UnityTransport,选择后会自动挂载UnityTransport脚本

2.创建UI

创建4个按钮:,一个text和InputField 。并挂载脚本,如下图

3.创建预制体

创建一个圆球,挂载NetwrokObject和NetworkTransform

NetworkTransform 的pocition Rotation Scale全部勾选(多人同步:位置、旋转、大小)

NetworkManage 添加这个预制件,如下图

4.代码介绍

UI代码

csharp 复制代码
using System.Net;
using System.Net.NetworkInformation;
using Unity.Netcode;
using Unity.Netcode.Samples;
using Unity.Netcode.Transports.UTP;
using UnityEngine;
using UnityEngine.UI;
namespace Twq
{
 public class UI_Init : MonoBehaviour
 {
        public Transform NetworkManager_;
        public Text text_IP;
        public Button HostBtn;

        public Button ServerBtn;

        public InputField inputField;

        public Button ClientBtn;

        public GameObject obj01;
        public GameObject obj02;

        public Button RandomBtn;

        private void Awake()
        {
            text_IP.text = GetIP();
            var networkManager = NetworkManager_.GetComponent<NetworkManager>();
            UnityTransport unityTransport = networkManager.GetComponent<UnityTransport>();
            //服务器地址填写:0.0.0.0   本地可连接,外网也可链接(放在云服务器上才行)
            //其他客户端连接时  输入 服务器IP  即可
            HostBtn.onClick.AddListener(() => {
                unityTransport.SetConnectionData("0.0.0.0", 7777);
                networkManager.StartHost();
                obj01.SetActive(false);
                obj02.SetActive(true);
            });
            ServerBtn.onClick.AddListener(() => {
                unityTransport.SetConnectionData("0.0.0.0", 7777);
                networkManager.StartServer();
                obj01.SetActive(false);
            });
            ClientBtn.onClick.AddListener(() => {
                if (inputField.text != null && inputField.text != "")
                {
                    unityTransport.SetConnectionData(inputField.text, 7777);
                    networkManager.StartClient();
                    obj01.SetActive(false);
                    obj02.SetActive(true);
                }
                else
                {
                    Debug.Log("请输入服务器的IP");
                }

            });

            RandomBtn.onClick.AddListener(() => {
                if (!networkManager.IsClient)
                {
                    Debug.Log("没有 连上");
                }
                if (networkManager.LocalClient != null)
                {
                    // Get `BootstrapPlayer` component from the player's `PlayerObject`
                    if (networkManager.LocalClient.PlayerObject.TryGetComponent(out BootstrapPlayer bootstrapPlayer))
                    {
                        // Invoke a `ServerRpc` from client-side to teleport player to a random position on the server-side
                        bootstrapPlayer.RandomTeleportServerRpc();
                    }
                }
            });
        }

        private string GetIP()
        {
            string ipv4 = "";
            foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
            {
                NetworkInterfaceType _type1 = NetworkInterfaceType.Wireless80211;
                NetworkInterfaceType _type2 = NetworkInterfaceType.Ethernet;
                if (item.NetworkInterfaceType == _type1 || item.NetworkInterfaceType == _type2 && item.OperationalStatus == OperationalStatus.Up)
                {
                    foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
                    {
                        if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {
                            ipv4 = ip.Address.ToString();
                        }
                    }
                }
            }
            return ipv4;
        }
    }
}
 
 
 
 

随机位置代码

csharp 复制代码
using UnityEngine;

namespace Unity.Netcode.Samples
{
    /// <summary>
    /// Component attached to the "Player Prefab" on the `NetworkManager`.
    /// </summary>
    public class BootstrapPlayer : NetworkBehaviour
    {
        /// <summary>
        /// If this method is invoked on the client instance of this player, it will invoke a `ServerRpc` on the server-side.
        /// If this method is invoked on the server instance of this player, it will teleport player to a random position.
        /// </summary>
        /// <remarks>
        /// Since a `NetworkTransform` component is attached to this player, and the authority on that component is set to "Server",
        /// this transform's position modification can only be performed on the server, where it will then be replicated down to all clients through `NetworkTransform`.
        /// </remarks>
        [ServerRpc]
        public void RandomTeleportServerRpc()
        {
            var oldPosition = transform.position;
            transform.position = GetRandomPositionOnXYPlane();
            var newPosition = transform.position;
            print($"{nameof(RandomTeleportServerRpc)}() -> {nameof(OwnerClientId)}: {OwnerClientId} --- {nameof(oldPosition)}: {oldPosition} --- {nameof(newPosition)}: {newPosition}");
        }

        private static Vector3 GetRandomPositionOnXYPlane()
        {
            return new Vector3(Random.Range(-3f, 3f), Random.Range(-3f, 3f), 0f);
        }
    }
}

总结

项目源码: 链接

相关推荐
二哈赛车手5 小时前
新人笔记---ApiFox的一些常见使用出错
java·笔记·spring
栗子~~6 小时前
JAVA - 二层缓存设计(本地缓冲+redis缓冲+广播所有本地缓冲失效) demo
java·redis·缓存
YDS8296 小时前
DeepSeek RAG&MCP + Agent智能体项目 —— RAG知识库的搭建和接口实现
java·ai·springboot·agent·rag·deepseek
未若君雅裁8 小时前
MyBatis 一级缓存、二级缓存与清理机制
java·缓存·mybatis
HonestGoat8 小时前
Unity3d之碰撞体设置
unity
AI人工智能+电脑小能手8 小时前
【大白话说Java面试题 第65题】【JVM篇】第25题:谈谈对 OOM 的认识
java·开发语言·jvm
阿维的博客日记9 小时前
Nacos 为什么能让配置动态生效?(涉及 @RefreshScope 注解)
java·spring
雨辰AI9 小时前
SpringBoot3 + 人大金仓读写分离 + 分库分表 + 集群高可用 全栈实战
java·数据库·mysql·政务
辰海Coding10 小时前
MiniSpring框架学习-完成的 IoC 容器
java·spring boot·学习·架构
小小编程路10 小时前
C++ 多线程与并发
java·jvm·c++