gpt4 book ai didi

c# - 当所有玩家同名时查找 localPlayer

转载 作者:行者123 更新时间:2023-11-30 14:06:00 25 4
gpt4 key购买 nike

在将玩家引用到另一个对象的脚本时,Unity 让我感到困惑。我使用了几种方法来引用 localPlayer 对象:

  1. 比较标签(在某些情况下不太好)
  2. gameObject.Name(从未使用过但也不可靠)
  3. 在检查器中分配 public GameObject Player;拖放(播放器是预制件时会遇到问题)
  4. 创建public static [PlayerControllerClass]实例;并在void Start()函数中设置instance = this。为了访问playerSpeed 来 self 做的另一个脚本 PlayerControllerClass.instance.playerSpeed = 10;

是否有其他解决方案以正确的方式引用玩家。

注意:我知道我的问题可能与特定问题无关,但如果有人愿意提供帮助,我可以解释更多。

Edit1: for example I want to find localPlayer in a NetworkGame where all players have same name, same tag but only one player is a localPlayer. Can I access the localPlayer from another script?

Edit2 : The answer I accepted is what I felt the best.I will use the answer provided in previewing score text of the localPlayerby accessing it from a set of players [localPlayer]

最佳答案

在您进行编辑之前,您的问题并不清楚,然后我才意识到这是一个网络问题。

I need to find localPlayer in a NetworkGame where all players have same name, same tag but only one player is a localPlayer can I access the localPlayer from another script?

您可以找到具有 NetworkConnection.playerControllers 的播放器,它会返回 PlayerController 列表,然后遍历它并检查它是否有效。之后,从中获取 NetworkBehaviour 检查 isLocalPlayer 属性。原来如此。

像这样:

GameObject FindLocalNetworkPlayer()
{
NetworkManager networkManager = NetworkManager.singleton;
List<PlayerController> pc = networkManager.client.connection.playerControllers;

for (int i = 0; i < pc.Count; i++)
{
GameObject obj = pc[i].gameObject;
NetworkBehaviour netBev = obj.GetComponent<NetworkBehaviour>();

if (pc[i].IsValid && netBev != null && netBev.isLocalPlayer)
{
return pc[i].gameObject;
}
}
return null;
}

如果您将 NetworkIdentity 附加到播放器而不是 NetworkBehaviour,只需获取 NetworkIdentity 并检查 isLocalPlayer 属性(property)。您还可以找到 GameObject,然后检查 NetworkIdentityisLocalPlayer 属性。

if (obj.GetComponent<NetworkIdentity>().isLocalPlayer){}

您可能需要的其他有用的播放器操作:

查找所有玩家:

List<GameObject> ListPlayers()
{
NetworkManager networkManager = NetworkManager.singleton;
List<PlayerController> pc = networkManager.client.connection.playerControllers;

List<GameObject> players = new List<GameObject>();
for (int i = 0; i < pc.Count; i++)
{
if (pc[i].IsValid)
players.Add(pc[i].gameObject);
}
return players;
}

按名称查找播放器(也可以更改为按标签或图层):

GameObject FindNetworkPlayer(string name)
{
NetworkManager networkManager = NetworkManager.singleton;
List<PlayerController> pc = networkManager.client.connection.playerControllers;

for (int i = 0; i < pc.Count; i++)
{
if ((pc[i].IsValid) && (name == pc[i].gameObject.name))
return pc[i].gameObject;
}
return null;
}

编辑前的旧答案:

Is there other solutions for referencing players in a proper way.

是的,您可以使用 GameObject.Find 找到游戏对象,之后,您可以使用 GetComponent 函数来获取附加到它的脚本。

我注意到您提到您也想在场景中引用预制件。预制件和场景中的对象之间存在差异,它们都有不同的引用方式。

这里已经是场景中对象的示例。您可以在层次结构 标签中看到它们:

enter image description here

让我们通过名称引用“ Canvas ”游戏对象:

GameObject canvasObj = GameObject.Find("Canvas");

让我们将 Canvas 脚本附加到“Canvas”游戏对象:

GameObject canvasObj = GameObject.Find("Canvas");
Canvas canvas = canvasObj.GetComponent<Canvas>();

预制件:

这是“项目”选项卡中预制件的示例:

enter image description here

将预制件放在名为“Resources”的文件夹中。您必须这样才能使用 Resources API 引用它们。

让我们引用“Capsule”预制游戏对象:

GameObject prefab = Resources.Load<GameObject>("Capsule");

要使用它,您必须实例化它:

GameObject instance = Instantiate(prefab);

您只能在实例化后获取预制件上的组件:

CapsuleCollider cc = instance.GetComponent<CapsuleCollider>();

关于c# - 当所有玩家同名时查找 localPlayer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51495093/

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