Unity3d 统一多人游戏:Y轴小于-2时重置玩家位置

Unity3d 统一多人游戏:Y轴小于-2时重置玩家位置,unity3d,position,unique,multiplayer,Unity3d,Position,Unique,Multiplayer,当玩家Y轴小于阈值-2时,重置玩家位置会出现这个问题 using UnityEngine; using UnityEngine.Networking; public class ResetPlayerPosition : NetworkManager { public float threshold = -2f; NetworkIdentity UniquePlayer; // On button click, it checks the players posi

当玩家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);
        }   
    }
}
使用UnityEngine;
使用UnityEngine。联网;
公共类ResetPlayerPosition:NetworkManager{
公共浮动阈值=-2f;
网络身份唯一玩家;
//点击按钮,它会检查玩家的位置,如果值为真,则重置位置
公共职位(){
UniquePlayer=GameObject.Find(“Player”).GetComponent();
var Player=GameObject.FindWithTag(“玩家”);
//如果球员Y轴小于-2,则重置球员位置
if(Player.transform.position.y<阈值){
Debug.Log(“播放器位置已重置”);
Player.transform.position=新向量3(0,1,0);
}否则{
Log(“玩家位置Y当前位于:“+Player.transform.position.Y”);
}   
}
}
我的目标是抓住唯一的球员y的位置,并重置为1,如果它小于-2。当你一个人在比赛中时,我让它工作,但是一旦你在比赛中超过一名球员,它就会做一些奇怪的事情,因为它没有指向特定的球员

我正在使用NetworkManager及其在本地主机上运行。我试图通过获取玩家的网络ID来解决这个问题,这个ID是唯一的,但是我不知道如何组合这些信息


希望有人能给我指出正确的方向。

为什么不使用MonoBehavior脚本并将其附加到播放器对象上?

这样,您就已经拥有了正确的玩家游戏对象,并且不必找到带有标签的游戏对象。

首先,我建议您进行更多测试,以缩小主机系统和客户端系统上奇怪行为的差异。这可能会让我们了解到底出了什么问题

第二,我同意塞巴斯蒂安的观点,在球员预制板上放置一个单一行为可能是一个更好的方法。这样的解决方案应该是可靠的:

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);
        }
    }
}
使用UnityEngine;
公共类位置重置:单一行为{
公共浮动阈值=-2;
公众浮子重置高度=1;
私有void更新(){
if(变换位置y<阈值){
//请注意,我保持x和z的位置不变,因为这听起来像是您正在寻找的。根据需要进行更改
transform.position=新矢量3(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);
            }
        }
    }
}
使用UnityEngine;
使用UnityEngine。联网;
公共类ResetPlayerPosition:NetworkManager{
公共浮动阈值=-2f;
//点击按钮,它会检查玩家的位置,如果值为真,则重置位置
公共职位(){
var Players=GameObject.FindGameObjectsWithTag(“玩家”);
foreach(玩家中的游戏对象玩家){
//如果球员Y轴小于-2,则重置球员位置
if(Player.transform.position.y<阈值){
Debug.Log(“播放器位置已重置”);
Player.transform.position=新向量3(0,1,0);
}否则{
Log(“玩家位置Y当前位于:“+Player.transform.position.Y”);
}
}
}
}
您将注意到,我们不是使用player标记检索一个游戏对象,而是检索所有对象,并使用foreach循环对所有对象执行评估。这将产生更一致的行为


除此之外,我将研究使用a,这将有助于在网络上保持所有动作的球员位置同步;这是几乎所有网络游戏的基本工具。

嗯,我试过了。因为在有人托管服务器之前,现场没有玩家,所以我将脚本附加到了玩家预置,这意味着,在连接到游戏时,玩家会自动获得一个玩家对象,这要归功于网络管理器脚本。创建的对象具有相同的名称Player(Clone)@Christian如果将脚本附加到Player Gameobject,则您已经可以访问Gameobject和transform变量。你不必使用GameObject.FindWithTag(“玩家”)它不是wokring。如果我照你说的做,它会一直说物体的位置是1.1,但不是。你可以清楚地看到在右上角,它的方式比那少。脚本附加到预置,网络管理器使用该预置创建该预置的克隆对象。我猜,因为这是一个在线游戏,它只是对这种方式没有反应,我的意思是,我理解你的意思,它也很有意义,但因为它不工作,我假设我必须获得某种对象的ID来指定它?哦,顺便说一句,我使用按钮重置播放器上的OnClick来调用函数ResetPosition()奇怪的是,当您将第一个建议转换为and Update()而不是OnClick时,您的第一个建议与我的建议类似。在在线比赛中尝试重置球员位置时,OnClick似乎会产生负面影响。谢谢你的帮助,非常感谢:)酷,很高兴它起作用了!将其置于更新状态意味着它将检查每一帧。这也意味着它在主机和客户机上运行,而OnClick只会发生在发生click事件的机器上,不会通过网络发送(除非您添加代码)。