我有这段代码,可以生成一个球并将其扔向玩家所看的方向,稍后我想制作一个从库存中扔出物品的系统,但我在多人游戏中遇到问题,因为游戏对象只能生成服务器所以我使用 RPC,但它在抛出对象之前会导致相当大的延迟(例如 0.5 秒)
有谁知道减少这种延迟的方法吗?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Netcode;
public class PlayerFunctions : NetworkBehaviour
{
public GameObject itemPrefab;
public float throwForce;
public Transform cameraPos;
public Transform itemSpawnPos;
private KeyCode throwKey = KeyCode.Q;
bool network = false;
public override void OnNetworkSpawn()
{
base.OnNetworkSpawn();
network = true;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(throwKey) && IsOwner)
{
ThrowServerRpc(itemSpawnPos.position, cameraPos.rotation);
}
else if(!network)
{
Throw();
}
}
[ServerRpc]
void ThrowServerRpc(Vector3 position, Quaternion rotation)
{
GameObject objectToThrow = Instantiate(itemPrefab, position, rotation);
var objectToThrowNetworkObject = objectToThrow.GetComponent<NetworkObject>();
objectToThrowNetworkObject.Spawn();
ThrowClientRpc(objectToThrowNetworkObject.NetworkObjectId);
}
[ClientRpc]
void ThrowClientRpc(ulong networkObjectId)
{
NetworkObject networkObject = NetworkManager.Singleton.SpawnManager.SpawnedObjects[networkObjectId];
if(networkObject != null)
{
Rigidbody itemRb = networkObject.GetComponent<Rigidbody>();
itemRb.AddForce(cameraPos.forward * throwForce, ForceMode.Force);
itemRb.AddForce(transform.up * 100, ForceMode.Force);
}
}
void Throw()
{
GameObject objectToThrow = Instantiate(itemPrefab, itemSpawnPos.position, cameraPos.rotation);
Rigidbody itemRb = objectToThrow.GetComponent<Rigidbody>();
itemRb.AddForce(cameraPos.forward * throwForce, ForceMode.Force);
itemRb.AddForce(transform.up * 100, ForceMode.Force);
}
}
如果您还没有解决这个问题,我看到您的代码中使用了实例化。那是一条缓慢的路。你想要的是对象池。
基本上,您预先实例化给定预制件的实例池,并且您有一个“可用”和“已用”列表,因此当您需要一个实例时,您可以通过“保留”它来获取对已实例化对象的引用,然后修改它来设置它供您使用,它会从“可用”列表转到“已用”列表。当您不再需要它时,您可以清除任何修改(或者更好地说,将实例重置为其默认值)并“释放”它,而不是销毁它,然后它会移回空闲列表。这显然意味着您需要为预实例化的实例数量找到一个好的配置,因为您基本上需要预先支付实例化的成本。这也意味着最坏的情况,即您希望在单个帧中“保留”多少个该对象的实例,以避免在您不想产生成本时实例化更多实例。此外,您不想过度使用它并使其成为开销,因此这是一个找到最佳点数的迭代过程。
您可以轻松地自行开发,但 Unity 现在有自己的 API,ObjectPool,其中 T 是您想要池化的类型。
还有这里有关处理池的 Netcode 内容的文档。