GameObject无法在Unity网络中的正确位置的“场景”选项卡中直观显示

时间:2017-03-10 21:05:52

标签: c# networking unity3d

我一直在尝试在Unity供应的教程之上添加一些小东西,我对如何使这个特定的机制工作感到困惑。

当我的播放器拍摄时,它会向鼠标方向拍摄。当我在我的计算机上运行客户端和主机以便2个人连接进行测试时,我得到了奇怪的结果。

我让我的两个玩家都朝着正确的方向射击但是当我在其中一个客户端上移动我的鼠标时,我看到我的蓝色圆圈(表示子弹将在哪里产生)正在移动时该客户端没有聚焦,这意味着我目前没有点击该客户端,当我移动我的鼠标时,我看到客户端上移动的蓝色圆圈我不专心,我不确定我在街上的朋友是否要测试这会导致错误

以下是我的场景/游戏视图的2个屏幕截图,以获得更好的视觉效果:Pic 1 - Pic 2

我最终在我的父GameObject上使用网络变换子对我的一个孩子GameObjects有助于产生子弹的位置,但仍然从我的场景选项卡的视觉外观让我担心产生子弹的准确性。

这是我的拍摄代码:

public class PlayerShooting : NetworkBehaviour 
{
public GameObject bulletPrefab;
public GameObject fireSpot;
public float bulletSpeed;
public Transform rotater;
public Camera cam;

void Update()
{
    // Only run the below code if this is the local player.
    if (!isLocalPlayer)
    {
        return;
    }
    // Rotate based on the location of the mouse our spot to shoot bullets.
    Vector3 dir = cam.ScreenToWorldPoint (Input.mousePosition) - rotater.position;
    float angle = Mathf.Atan2 (dir.y, dir.x) * Mathf.Rad2Deg;
    rotater.rotation = Quaternion.AngleAxis (angle, Vector3.forward);

    // When we hit spacebar
    if(Input.GetKeyDown(KeyCode.Space))
    {
        // Fire some bullets.
        CmdFire ();
    }
}


//  Something the client is wanting to be done and sends this "command" to the server to be processed
[Command]
public void CmdFire () 
{
    // Create the Bullet from the Bullet Prefab
    var bullet = (GameObject)Instantiate (bulletPrefab, fireSpot.transform.position, Quaternion.identity);

    // Add velocity to the bullet
    bullet.GetComponent<Rigidbody2D>().velocity = (fireSpot.transform.position - rotater.position).normalized * bulletSpeed;

    // Spawn the bullets for the Clients.
    NetworkServer.Spawn (bullet);

    // Destroy the bullet after 2 seconds
    Destroy(bullet, 4.0f);
}
}

我的动作脚本:

public class Movement : NetworkBehaviour {

void Update()
{
    if (!isLocalPlayer)
    {
        return;
    }

    var x = Input.GetAxis("Horizontal") * Time.deltaTime * 3.0f;
    var y = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f;

    transform.Translate(x, y, 0f);
}
}

1 个答案:

答案 0 :(得分:1)

如果您想在同一台计算机上运行多个统一游戏实例,这将继续存在问题。如果你进入编辑&gt;项目设置&gt;播放器分辨率和演示文稿下有在后台运行选项。如果你选中了这个,那么游戏的两个实例都会从Input.mousePosition收到每帧更新的鼠标位置(请记住Input.GetKeyDown只会注册到游戏的焦点实例,所以有一些这里不一致)。如果您没有选中该复选框,那么您的游戏实例会在没有集中注意力时暂停(如果您正在使用客户端/主机网络范例,我猜你不想这样做)。

有几种方法可以解决这个问题。测试联网游戏的理想方法是为每个游戏实例配备一台独特的PC。如果这不是一个选项,您可以添加一些检查以确保鼠标在窗口上。只要两个窗口没有重叠,您可以通过检查屏幕信息的位置来实现:

bool IsMouseOverWindow()
{
    return !(Input.mousePosition.x < 0 || 
        Input.mousePosition.y < 0 || 
        Input.mousePosition.x > Screen.width || 
        Input.mousePosition.y > Screen.height);
}

然后,您可以使用此功能在Update()中决定是否要更新rotator.rotation

另一种选择是实施MonoBehaviour.OnApplicationFocus。然后,您可以启用/禁用事件(例如,根据mousePosition更新轮换)以响应该事件。最干净的解决方案是让您的系统有一个清晰的方式来询问我的窗口是否正在关注&#34;。你可以创建一个这样的类:

public class FocusListener : MonoBehaviour
{
    public static bool isFocused = true;
    void OnApplicationFocus (bool hasFocus) {
        isFocused = hasFocus;
    }
}

确保您在游戏的某个地方有其中一个,然后通过查看FocusListener.isFocused可以查看任何内容。