IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> UnityMirror学习笔记(6):权限与运动控制 -> 正文阅读

[游戏开发]UnityMirror学习笔记(6):权限与运动控制

Mirror是一个简单高效的开源的Unity多人游戏网络框架。
官方文档链接:
https://mirror-networking.gitbook.io/docs

在之间的几章博客里,已经基本介绍了UnityMirror的各种有用的概念。
但是并没有详细介绍如何在Mirror中,随心所欲地控制任何一个对象。
如果有读者仿照我之前的实验代码去自己实验,会发现很多问题,
比如rigidbody.velocitytransform.position无法在本地直接设定等。

当然可以通过[Command]等通知服务器进行控制,间接控制本地,
不过个人觉得不太好,有可能导致严重的延迟,客户端还是应该优先强调本地的控制。

本节将权限和控制一起介绍,旨在能实现各个客户端随心所欲控制自己想要控制的对象,而保持良好的同步~

权限

权限是Mirror中一个很重要的概念,它用来描述一个客户端对某个对象的所有权。

运动控制

在Mirror中,由于需要在服务器上获取速度计算物理效果,使用本地的Rigidbody组件是无法完成这个效果的,而且也无法实现同步控制。
因为Mirror不会自动去序列化RigidBody的信息进行同步。

因此此时只会出现两种状况:
服务器可以实现控制,并通过服务器->客户端的同步实现同步运动,这是因为对象默认自带了NetworkTransform组件。
客户端可以实现控制,但由于没有从客户端->服务器的同步,服务器看不到对象的运动。

我们需要挂载NetworkRigidbody组件,
来实现客户端对有权限的物体的运动控制向服务器的同步。

挂载脚本后,直接控制自己的RigidBody即可
这个脚本暂时属于Mirror的Experimental命名空间中,如果需要在自己的脚本中访问控制,需要using Mirror.Experimental;指定
可能遇到出乎意料的问题,大可以往Mirror的github里扔Issue
https://github.com/vis2k/Mirror

使用

在玩家预制体上挂载NetworkRigidbody组件,
并且勾选Client Authority,这样才能从客户端向服务器同步
[外链图片转存中...(img-Sanv3gdO-1646296056197)]

代码案例如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
using Cinemachine;

public class PlayerController : NetworkBehaviour
{
    Rigidbody rb;    
    CinemachineVirtualCamera cv;

    MaterialPropertyBlock prop;

    public GameObject prefabWeapon;
    [Command]
    void spawnWeapon(){
        GameObject tmp = GameObject.Instantiate(prefabWeapon);
        NetworkServer.Spawn(tmp);
        tmp.transform.position = new Vector3(transform.position.x, transform.position.y+2, transform.position.z);
    }


    private void Start() {
        rb = GetComponent<Rigidbody>();
        if(isLocalPlayer){
            cv = GameObject.FindGameObjectWithTag("VCAM").GetComponent<CinemachineVirtualCamera>();
            cv.LookAt = this.transform;
            prop =  new MaterialPropertyBlock();
            GetComponent<Renderer>().GetPropertyBlock(prop);
            prop.SetColor("_Color", (Color.HSVToRGB(Random.Range(0,360), 0.8f, 0.8f)));
            GetComponent<Renderer>().SetPropertyBlock(prop);
        }
    }

    float moveDirX;
    float moveDirY;
    private void Update() {
        if(isLocalPlayer){
            if(Input.GetKeyDown(KeyCode.Space)){
                spawnWeapon();
            }
            moveDirX = Input.GetAxisRaw("Horizontal");
            moveDirY = Input.GetAxisRaw("Vertical");
            rb.velocity = new Vector3(3 * moveDirX, 3*moveDirY, 0);
        }
    } 
}

运行一个纯服务器和一个客户端,在客户端上使用键盘控制实体,可以实现同步:
[外链图片转存中...(img-YbvT8Fhe-1646296056199)]

多端同步也是一致的:
[外链图片转存中...(img-UJ9z3tz5-1646296056199)]

权限给予

角色控制脚本里已经写了按下空格键生成武器的代码。
我们先不让武器跟随,而是将相同的这个角色控制脚本挂载到武器预制体上,同时也将NetworkRigidbody挂载上,且勾选Client Authority
[外链图片转存中...(img-3FMFQaXr-1646296056200)]

虽然期望武器同自己的角色能一起运动,但事实是无法跟随:
[外链图片转存中...(img-lsmQkO2Q-1646296056200)]

这里有两个问题需要修改:

isLocalPlayer 与 hasAuthority

isLocalPlayer为true的对象,在客户端全体对象里,只有唯一一个。(由连接到服务器生成的本地玩家)

因此想要本地控制的其它对象需要必须使用hasAuthority,而不能使用isLocalPlayer
我们这里直接将isLocalPlayer替换成hasAuthority

//在 第36行 Update()中 
if(isLocalPlayer)

=>

if(hasAuthority)

服务器给予客户端对象权限

此时运行依然无法两个都控制,
原因是isLocalPlayer为true的对象默认hasAuthority为true

但是其它在服务器生成并同步到客户端的对象默认在所有客户端hasAuthority为false包括主机的客户端

因此需要在服务器上给予某个客户端对某个对象的权限:
使用NetworkServer.Spawn方法同时携带到客户端的连接通道,是最简单的设置方式。

//在 第18行 spawnWeapon()中
NetworkServer.Spawn(tmp);
=>
NetworkServer.Spawn(tmp,connectionToClient);

此时就可以完成两个都控制了。
[外链图片转存中...(img-kbbrz7w2-1646296056201)]

权限中途分配与取消

有的时候某个对象不是一直属于一个客户端的。

可以通过identity.AssignClientAuthority(conn);进行对象生成完毕后,后续权限的分配。

可以通过identity.RemoveClientAuthority();让这个对象不属于任何一个客户端。

注意localPlayer不可以被取消权限,但是可以通过NetworkServer.ReplacePlayerForConnection(conn, newGameObj);被替换

同一对象多客户端权限是不被允许的,即使中途分配,也只认第一个为主人,先Remove再Assign

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-04 15:56:00  更:2022-03-04 15:56:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 16:38:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码