当所有玩家的名字都相同时,查找 localPlayer

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

  1. 比较标签(在某些情况下不太好)

  2. gameObject.Name(没用过但也不靠谱)

  3. public GameObject Player;在检查器拖放中分配(当播放器是预制件时会遇到问题)

  4. 在函数中制作public static [PlayerControllerClass] instance;和设置instance = thisvoid Start()为了playerSpeed从另一个脚本访问我做PlayerControllerClass.instance.playerSpeed = 10;

是否有其他解决方案可以以适当的方式引用玩家。

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

Edit1:例如我想localPlayer在一个 NetworkGame 中找到所有玩家都具有相同名称、相同标签但只有一个玩家是 localPlayer 的。我可以localPlayer从另一个脚本访问吗?

Edit2:我接受的答案是我感觉最好的答案。我将使用预览score text中提供的答案,方法是localPlayer从一组玩家 [ localPlayer]


慕神8447489
浏览 233回答 3
3回答

神不在的星期二

你的问题直到你的编辑才清楚,然后我意识到这是一个网络问题。我需要在 NetworkGame 中找到 localPlayer,其中所有玩家都具有相同的名称、相同的标签但只有一个玩家是 localPlayer 我可以从另一个脚本访问 localPlayer 吗?您可以找到使用NetworkConnection.playerControllers哪些 retruens List of PlayerControllerthen 循环遍历它并检查它是否有效的玩家。之后,从中获取 NetworkBehaviour 检查 isLocalPlayer 属性。真的是这样。像这样的东西:GameObject FindLocalNetworkPlayer(){&nbsp; &nbsp; NetworkManager networkManager = NetworkManager.singleton;&nbsp; &nbsp; List<PlayerController> pc = networkManager.client.connection.playerControllers;&nbsp; &nbsp; for (int i = 0; i < pc.Count; i++)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; GameObject obj = pc[i].gameObject;&nbsp; &nbsp; &nbsp; &nbsp; NetworkBehaviour netBev = obj.GetComponent<NetworkBehaviour>();&nbsp; &nbsp; &nbsp; &nbsp; if (pc[i].IsValid && netBev != null && netBev.isLocalPlayer)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return pc[i].gameObject;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return null;}如果您已NetworkIdentity附加到播放器而不是NetworkBehaviour,只需获取NetworkIdentity并检查isLocalPlayer属性。您还可以找到 GameObject 然后检查NetworkIdentity和isLocalPlayer属性。if (obj.GetComponent<NetworkIdentity>().isLocalPlayer){}您可能需要的其他有用的播放器操作:查找所有玩家:List<GameObject> ListPlayers(){&nbsp; &nbsp; NetworkManager networkManager = NetworkManager.singleton;&nbsp; &nbsp; List<PlayerController> pc = networkManager.client.connection.playerControllers;&nbsp; &nbsp; List<GameObject> players = new List<GameObject>();&nbsp; &nbsp; for (int i = 0; i < pc.Count; i++)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (pc[i].IsValid)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; players.Add(pc[i].gameObject);&nbsp; &nbsp; }&nbsp; &nbsp; return players;}按名称查找玩家(也可以按标签或图层更改为):GameObject FindNetworkPlayer(string name){&nbsp; &nbsp; NetworkManager networkManager = NetworkManager.singleton;&nbsp; &nbsp; List<PlayerController> pc = networkManager.client.connection.playerControllers;&nbsp; &nbsp; for (int i = 0; i < pc.Count; i++)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if ((pc[i].IsValid) && (name == pc[i].gameObject.name))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return pc[i].gameObject;&nbsp; &nbsp; }&nbsp; &nbsp; return null;}编辑前的旧答案:是否有其他解决方案可以以适当的方式引用玩家。是的,您GameObject.Find可以使用找到 GameObject ,然后,您可以使用该GetComponent函数来获取附加到它的脚本。我注意到你提到你也想在场景中引用预制件。预制件和已经出现在场景中的对象之间存在差异,并且它们都有不同的引用方式。这是场景中对象的示例。您可以在“层次结构”选项卡中看到它们:让我们按名称引用“画布”游戏对象:GameObject canvasObj = GameObject.Find("Canvas");让我们参考Canvas附加到“画布”游戏对象的脚本:GameObject canvasObj = GameObject.Find("Canvas");Canvas canvas = canvasObj.GetComponent<Canvas>();预制件:以下是“项目”选项卡中的预制件示例:将预制件放在名为“Resources”的文件夹中。您必须这样才能使用ResourcesAPI引用它们。让我们参考“Capsule”预制游戏对象:GameObject&nbsp;prefab&nbsp;=&nbsp;Resources.Load<GameObject>("Capsule");要使用它,您必须实例化它:GameObject&nbsp;instance&nbsp;=&nbsp;Instantiate(prefab);您只能在实例化后在预制件上获取组件:CapsuleCollider&nbsp;cc&nbsp;=&nbsp;instance.GetComponent<CapsuleCollider>();

沧海一幻觉

当我需要多个引用时,我一直在寻求使用GameObject.FindGameObjectsWithTag,或者当我只需要对系统中可用的特定游戏对象的一个引用时,使用 GameObject.FindWithTag。要在所述游戏对象上引用脚本(使用上面的 API 参考找到),您只需使用 `` 如GameObject.GetComponent API 参考中所述。一个完整的例子是:为您的玩家游戏对象分配一个标签,例如PlayerA。GameObject player = GameObject.FindWithTag("PlayerA");PlayerScript playerScript = player.GetComponent<PlayerScript>();我希望这会有所帮助,如果您需要进一步说明,我将非常乐意提供帮助。编辑:另一个解决方案:关注点:50 或 50x名玩家太普通而无法分配标签。解决方案:如果您有一组 50 名玩家:我会将它们分组在父游戏对象下。为父游戏对象分配一个标签,例如 ParentPlayer使用GetComponentsInChildren参考。

慕桂英3389331

我推荐单例模式。我在几乎所有的 Unity 项目中为只有 1 个类的对象实现了它,但它是一个单一的行为。using UnityEngine;public abstract class SingletonBehaviour<T> : MonoBehaviour where T : MonoBehaviour{&nbsp; &nbsp; public bool dontDestroyOnLoad = true;&nbsp; &nbsp; private bool isInitialized = false;&nbsp; &nbsp; private static T instance;&nbsp; &nbsp; public static T Instance&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (instance == null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; instance = FindObjectOfType<T>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (instance == null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var obj = new GameObject&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name = typeof(T).Name&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; instance = obj.AddComponent<T>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return instance;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; protected virtual void Awake()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (instance == null)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; instance = this as T;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (dontDestroyOnLoad)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DontDestroyOnLoad(this.transform.root.gameObject);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; else if (instance != this)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Destroy(gameObject);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private void OnEnable()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (!isInitialized)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OnInitialize();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isInitialized = true;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public abstract void OnInitialize();}然后你可以像这样创建一个类:public class MyClass : SingletonBehaviour<MyClass>{&nbsp; &nbsp; public void OnInitialize()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // You can use this instead of awake or start&nbsp; &nbsp; }&nbsp; &nbsp; public void DoStuff();}并这样称呼它:MyClass.Instance.DoStuff()
打开App,查看更多内容
随时随地看视频慕课网APP