gpt4 book ai didi

c# - 如何在 UNet/Unity5 中同步非玩家游戏对象属性?

转载 作者:太空狗 更新时间:2023-10-29 20:56:22 26 4
gpt4 key购买 nike

我正在研究和学习 Unity 5、UNET 和网络的一些基础知识。我制作了一个简单的 3D 游戏,您可以在其中四处走动并更改对象的颜色。但我现在想让它成为多人游戏,我在弄清楚如何通过网络发送更改以便所有玩家都能看到单个玩家的颜色变化时遇到了很多麻烦。

问题的部分原因是使用较新的 UNET 网络引擎很难找到答案。有时我会遇到适用于旧方法的答案。

所以主要问题是,我如何更改网络非玩家 GameObject 属性?颜色、形状、大小等。

这是我现在拥有的一些代码 - 我有很多不同的版本,所以我只发布当前版本:

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

public class Player_Paint : NetworkBehaviour {

private int range = 200;
[SerializeField] private Transform camTransform;
private RaycastHit hit;
[SyncVar] private Color objectColor;
[SyncVar] private GameObject objIdentity;

void Update () {
CheckIfPainting();
}

void CheckIfPainting(){
if(Input.GetMouseButtonDown(0)) {
if (Physics.Raycast (camTransform.TransformPoint (0, 0, 0.5f), camTransform.forward, out hit, range)) {
string objName = hit.transform.name;
CmdPaint(objName);
}
}
}

[ClientRpc]
void RpcPaint(){
objIdentity.GetComponent<Renderer>().material.color = objectColor;
}

[Command]
void CmdPaint(string name) {
objIdentity = GameObject.Find (name); //tell us what was hit
objectColor = new Color(Random.value, Random.value, Random.value, Random.value);
RpcPaint ();
}
}

我已经尝试了更多的解决方案,包括在我想要更改颜色的对象上编写一个单独的脚本,并包括 [SyncVar] 和 Hook 函数。我还对我期望更新客户端对象的每个函数尝试了 Debug.Log,并且它们正在使用预期数据执行。

我真的不知道还能做什么。我觉得这是我想做的一件非常简单的事情,但我在任何问题、教程或其他资源中都没有遇到同步非玩家 GameObject 的情况。任何想法都会有所帮助,谢谢。

最佳答案

我找到了答案。这非常困难,因为我能找到的几乎每一个问题、帖子、示例等...都是关于玩家对象,而不是非玩家对象。

因此,我需要使用 AssignClientAuthority 函数。我曾尝试过几次,但没有正确使用它。以下是应用于播放器的有效 C# 脚本:

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

public class Player_Paint : NetworkBehaviour {

private int range = 200;
[SerializeField] private Transform camTransform;
private RaycastHit hit;
[SyncVar] private Color objectColor;
[SyncVar] private GameObject objectID;
private NetworkIdentity objNetId;

void Update () {
// only do something if it is the local player doing it
// so if player 1 does something, it will only be done on player 1's computer
// but the networking scripts will make sure everyone else sees it
if (isLocalPlayer) {
CheckIfPainting ();
}
}

void CheckIfPainting(){
// yes, isLocalPlayer is redundant here, because that is already checked before this function is called
// if it's the local player and their mouse is down, then they are "painting"
if(isLocalPlayer && Input.GetMouseButtonDown(0)) {
// here is the actual "painting" code
// "paint" if the Raycast hits something in it's range
if (Physics.Raycast (camTransform.TransformPoint (0, 0, 0.5f), camTransform.forward, out hit, range)) {
objectID = GameObject.Find (hit.transform.name); // this gets the object that is hit
objectColor = new Color(Random.value, Random.value, Random.value, Random.value); // I select the color here before doing anything else
CmdPaint(objectID, objectColor); // carry out the "painting" command
}
}
}

[ClientRpc]
void RpcPaint(GameObject obj, Color col){
obj.GetComponent<Renderer>().material.color = col; // this is the line that actually makes the change in color happen
}

[Command]
void CmdPaint(GameObject obj, Color col) {
objNetId = obj.GetComponent<NetworkIdentity> (); // get the object's network ID
objNetId.AssignClientAuthority (connectionToClient); // assign authority to the player who is changing the color
RpcPaint (obj, col); // usse a Client RPC function to "paint" the object on all clients
objNetId.RemoveClientAuthority (connectionToClient); // remove the authority from the player who changed the color
}
}

!!!重要!!!您要影响的每个对象都必须有一个 NetworkIdentity 组件,并且必须将其设置为 LocalPlayerAuthority

所以这个脚本只是为了改变一种随机颜色,但你应该能够改变实际的东西,将它应用到 Material 的任何变化或任何你想与非玩家对象联网的东西。 “应该”是最佳词 - 我还没有尝试过任何其他功能。

编辑 - 为学习目的添加了更多评论。

关于c# - 如何在 UNet/Unity5 中同步非玩家游戏对象属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33469930/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com