简而言之,我有一个非常简单的多人游戏。这是 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;
}
}
我觉得这非常奇怪,因为您可以清楚地看到,NetworkManager 对象上没有 NetworkIdentity 组件。在过去的 4 个小时里,我一直在尝试很多事情,但我就是做不到。所以现在我希望你们能帮助我。
编辑:这是网络管理器通常生成玩家的方式。如您所见,它没有代码:
最佳答案
我遇到了同样的问题并找到了以下解决方案。似乎您已经找到了解决方案,但是与处于相同情况的其他人分享一些可能的方法也许很有趣。
这是一种无需将相机连接到预制件的方法。
我正在使用 NetworkManager 来实例化播放器预制件。 (和你一样)
我通过让克隆对象告诉相机它们是谁(或它们属于哪个变换)来解决查找对克隆对象的引用的问题。
播放器有以下脚本:
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);
}
}
在我的默认主相机上(没有相机连接到播放器预制件,只有默认相机)我打开了以下脚本。它需要一个目标,我使用检查器对预制件进行了初始化。
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);
}
}
开始游戏后,每个克隆人都会告诉摄像机他是谁,因此目标会更改为各个客户端克隆人,并使用玩家脚本中的以下行:
Camera.main.GetComponent<CameraFollow>().target=transform; //Fix camera on "me"
这样你就不需要为每个播放器预制件实例创建一个相机(我不确定这是否会对性能产生很大影响)并且你不必停用所有不属于的相机你的客户。
如果您在编辑器中托管游戏,您会看到只有 1 个摄像头,而不是每个连接的客户端一个摄像头(就像将其附加到预制件时一样)。
我觉得这个方法很好用,可以用来往里面放东西,应该只适用于Local Player。
public override void OnStartLocalPlayer()
{
}
我尝试在编辑器和构建中启动游戏,它似乎运行良好。
关于c# - 如何将相机附加到 HLAPI 网络管理器实例化的播放器对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36261871/