Unity 多人游戏:当 Y 轴小于 -2 时重置玩家位置
Unity Multiplayer: Reset player position when Y axis is less then -2
当玩家 Y 轴小于阈值 -2 时,我在重置玩家位置时遇到了这个问题。
using UnityEngine;
using UnityEngine.Networking;
public class ResetPlayerPosition : NetworkManager {
public float threshold = -2f;
NetworkIdentity UniquePlayer;
// On button click, it checks the players position and resets the position if values are true
public void ResetPosition () {
UniquePlayer = GameObject.Find("Player").GetComponent<NetworkIdentity>();
var Player = GameObject.FindWithTag("Player");
// Reset player position if the players Y axis is less than -2
if (Player.transform.position.y < threshold) {
Debug.Log("player position has been reset");
Player.transform.position = new Vector3(0, 1, 0);
} else {
Debug.Log("Player position Y is currently at: " + Player.transform.position.y);
}
}
}
我的目标是捕捉唯一玩家的 y 位置,如果它小于 -2,则将其重置为 1。当你一个人在比赛中时我让它工作,但是一旦你在比赛中有超过 1 名球员,它就会做奇怪的事情,因为它没有指向特定的球员。
我在本地主机上使用 NetworkManager 及其 运行。我已经尝试通过获取播放器的唯一网络 ID 来解决这个问题,但无法弄清楚如何组合这些信息。
希望有人能给我指出正确的方向。
为什么不直接使用 MonoBehaviour 脚本并将其附加到播放器对象?
这样您就已经拥有了正确的 Player GameObject,并且您不必找到带有 Tag 的 GameObject。
首先,我建议进行更多测试,以缩小主机系统和客户端系统上奇怪行为的差异。这可能会让您深入了解到底出了什么问题。
其次,我同意 Sebastian 的观点,即在播放器预制件上放置 MonoBehaviour 可能是更好的方法。像这样的事情应该是一个万无一失的解决方案:
using UnityEngine;
public class PositionReset : MonoBehaviour {
public float threshold = -2;
public float resetHeight = 1;
private void Update() {
if (transform.position.y < threshold) {
// Note, I keep the x and z position the same, as it sounds like that's what you were looking for. Change as needed
transform.position = new Vector3(transform.position.x, resetHeight, transform.position.z);
}
}
}
如果出于某种原因不能接受将行为放在播放器预制件本身上,这里是您的代码片段的修改版本,可能会解决该问题:
using UnityEngine;
using UnityEngine.Networking;
public class ResetPlayerPosition : NetworkManager {
public float threshold = -2f;
// On button click, it checks the players position and resets the position if values are true
public void ResetPosition () {
var Players = GameObject.FindGameObjectsWithTag("Player");
foreach(GameObject Player in Players) {
// Reset player position if the players Y axis is less than -2
if (Player.transform.position.y < threshold) {
Debug.Log("player position has been reset");
Player.transform.position = new Vector3(0, 1, 0);
} else {
Debug.Log("Player position Y is currently at: " + Player.transform.position.y);
}
}
}
}
您会注意到,我们不是使用玩家标签检索一个游戏对象,而是检索所有游戏对象,并使用 foreach 循环对所有游戏对象执行评估。这应该会产生更一致的行为。
除此之外,我会考虑使用 NetworkTransform,这将有助于保持玩家的位置在所有动作中通过网络同步;几乎所有联网游戏的必备工具。
当玩家 Y 轴小于阈值 -2 时,我在重置玩家位置时遇到了这个问题。
using UnityEngine;
using UnityEngine.Networking;
public class ResetPlayerPosition : NetworkManager {
public float threshold = -2f;
NetworkIdentity UniquePlayer;
// On button click, it checks the players position and resets the position if values are true
public void ResetPosition () {
UniquePlayer = GameObject.Find("Player").GetComponent<NetworkIdentity>();
var Player = GameObject.FindWithTag("Player");
// Reset player position if the players Y axis is less than -2
if (Player.transform.position.y < threshold) {
Debug.Log("player position has been reset");
Player.transform.position = new Vector3(0, 1, 0);
} else {
Debug.Log("Player position Y is currently at: " + Player.transform.position.y);
}
}
}
我的目标是捕捉唯一玩家的 y 位置,如果它小于 -2,则将其重置为 1。当你一个人在比赛中时我让它工作,但是一旦你在比赛中有超过 1 名球员,它就会做奇怪的事情,因为它没有指向特定的球员。
我在本地主机上使用 NetworkManager 及其 运行。我已经尝试通过获取播放器的唯一网络 ID 来解决这个问题,但无法弄清楚如何组合这些信息。
希望有人能给我指出正确的方向。
为什么不直接使用 MonoBehaviour 脚本并将其附加到播放器对象?
这样您就已经拥有了正确的 Player GameObject,并且您不必找到带有 Tag 的 GameObject。
首先,我建议进行更多测试,以缩小主机系统和客户端系统上奇怪行为的差异。这可能会让您深入了解到底出了什么问题。
其次,我同意 Sebastian 的观点,即在播放器预制件上放置 MonoBehaviour 可能是更好的方法。像这样的事情应该是一个万无一失的解决方案:
using UnityEngine;
public class PositionReset : MonoBehaviour {
public float threshold = -2;
public float resetHeight = 1;
private void Update() {
if (transform.position.y < threshold) {
// Note, I keep the x and z position the same, as it sounds like that's what you were looking for. Change as needed
transform.position = new Vector3(transform.position.x, resetHeight, transform.position.z);
}
}
}
如果出于某种原因不能接受将行为放在播放器预制件本身上,这里是您的代码片段的修改版本,可能会解决该问题:
using UnityEngine;
using UnityEngine.Networking;
public class ResetPlayerPosition : NetworkManager {
public float threshold = -2f;
// On button click, it checks the players position and resets the position if values are true
public void ResetPosition () {
var Players = GameObject.FindGameObjectsWithTag("Player");
foreach(GameObject Player in Players) {
// Reset player position if the players Y axis is less than -2
if (Player.transform.position.y < threshold) {
Debug.Log("player position has been reset");
Player.transform.position = new Vector3(0, 1, 0);
} else {
Debug.Log("Player position Y is currently at: " + Player.transform.position.y);
}
}
}
}
您会注意到,我们不是使用玩家标签检索一个游戏对象,而是检索所有游戏对象,并使用 foreach 循环对所有游戏对象执行评估。这应该会产生更一致的行为。
除此之外,我会考虑使用 NetworkTransform,这将有助于保持玩家的位置在所有动作中通过网络同步;几乎所有联网游戏的必备工具。