如何将相机连接到HLAPI网络管理器实例化的播放器对象?

ice*_*cub 6 c# unity-game-engine

简而言之,我有一个非常简单的多人游戏.这是Roll A Ball游戏(Unity3D教程).所以现在我让球员等完美地产生,每个人都能完美控制自己的球.

但问题出在这里:我有一个默认的主摄像头.由于只有本地玩家本身需要看到它,我认为尝试为服务器上的每个玩家生成一个单独的摄像头是没有意义的.

但是,为了使相机跟随播放器,我需要将它附加到播放器游戏对象.显然我无法将它附加到播放器预制件上,因为它是相机需要遵循的克隆.但由于播放器是由网络管理器组件生成的,因此我不知道如何引用此克隆.

我自己尝试过的:

public class CameraController : NetworkManager
{

    public GameObject playerPrefab;
    public Transform target;

    private Vector3 offset;

    public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
    {
        GameObject player = (GameObject)Instantiate(playerPrefab, new Vector3(0, 0.5f, 0), Quaternion.identity);
        target = player.transform;
        NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
    }

    void Start()
    {
        offset = transform.position - target.position;
    }

    void LateUpdate()
    {
        transform.position = transform.position + offset;
    }
}
Run Code Online (Sandbox Code Playgroud)

但这导致: 错误的屏幕截图

我觉得非常奇怪,因为你可以清楚地看到,NetworkManager对象上没有NetworkIdentity组件.我在过去的4个小时里一直在尝试很多事情而且我不能这样做.所以现在我希望你们能帮助我.

编辑:这是网络管理器正常生成播放器的方式.如您所见,它没有代码:

网络管理员播放器产卵

小智 7

我有同样的问题,并找出了followig解决方案.好像你已经有了一个解决方案,但也许有趣的是,在同样的情况下为其他人分享一些可能的方法.

这是一种在没有相机连接到预制件的情况下完成此操作的方法.

我正在使用NetworkManager来实例化Player-prefabs.(和你一样)

我通过让克隆告诉摄像机,他们是谁(或者哪个变换属于他们)解决了找到克隆对象引用的问题.

播放器具有以下脚本:

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class PlayerController : NetworkBehaviour {



public override void OnStartLocalPlayer()
{
    GetComponent<MeshRenderer>().material.color = Color.blue;
    Camera.main.GetComponent<CameraFollow>().target=transform; //Fix camera on "me"

}

void Update ()
{
    if (!isLocalPlayer) 
    {
        return;
    }
    var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f;
    var z = Input.GetAxis ("Vertical") * Time.deltaTime * 3.0f;

    transform.Rotate (0, x, 0);
    transform.Translate (0,0,z);

}
}
Run Code Online (Sandbox Code Playgroud)

在我的默认主摄像头上(没有摄像头连接到播放器预制件,只有默认摄像头)我将以下脚本打开.它需要一个目标,我使用检查器使用预制件初始化.

using UnityEngine;
using System.Collections;

public class CameraFollow : MonoBehaviour {

public Transform target; //what to follow
public float smoothing = 5f; //camera speed

Vector3 offset;

void Start()
{
    offset = transform.position - target.position;
}

void FixedUpdate()
{
    Vector3 targetCamPos = target.position + offset;
    transform.position = Vector3.Lerp (transform.position,  targetCamPos,smoothing * Time.deltaTime);
}
}
Run Code Online (Sandbox Code Playgroud)

在开始游戏后,每个克隆都会告诉摄像机他是谁,因此目标会根据玩家脚本中的这一行更改为各个客户克隆:

Camera.main.GetComponent<CameraFollow>().target=transform; //Fix camera on "me"
Run Code Online (Sandbox Code Playgroud)

这样,您不需要为每个播放器预制件实例创建一个摄像头(我不确定这是否会在性能上产生很大差异),并且您不必停用所有不属于您客户端的摄像头.

如果您在编辑器中托管游戏,您可以看到每个连接的客户端只有一个摄像头而不是一个摄像头(就像将其连接到预制件上一样).

我认为这是一个很好的使用这种方法,你可以使用它来放置它,这应该只应用于本地播放器.

public override void OnStartLocalPlayer()
{ 
}
Run Code Online (Sandbox Code Playgroud)

我尝试在编辑器和构建中启动游戏,它似乎运行良好.


Raf*_*wui 3

我会在预制件中添加一个相机,然后编写一个如下的播放器脚本:

using UnityEngine.Networking;

public class Player : NetworkBehaviour
{
    public Camera camera;

    void Awake()
    {
        if(!isLocalPlayer)
        {
            camera.enabled = false;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)