Важно: UNet — это устаревшее решение, а также новая многопользовательская и сетьсистема Unity, которая обеспечивает многопользовательскую игру. игры через компьютерную сеть. Подробнее См. в Словарь Решение (Netcode для GameObjects) находится в разработке. Дополнительную информацию и дальнейшие действия см. на веб-сайте Unity Netcode for GameObjects. |
Вы можете использовать функции обработчика порождения, чтобы настроить поведение по умолчанию при создании порожденных игровых объектов из префабовтипа актива, который позволяет вам хранить GameObject вместе с компонентами и свойствами. Префаб действует как шаблон, из которого вы можете создавать новые экземпляры объектов на сцене. Подробнее
См. в Словарь на клиенте. Функции обработчика появления обеспечивают полный контроль над созданием GameObjectосновного объекта в сценах Unity, который может представлять персонажей, реквизит , пейзажи, камеры, путевые точки и многое другое. Функциональность GameObject определяется прикрепленными к нему компонентами. Подробнее
См. в Словарь, а также как его уничтожить.
Используйте ClientScene.RegisterSpawnHandler для регистрации функций для создания и уничтожения клиентских игровых объектов. Сервер создает игровые объекты напрямую, а затем порождает их на клиентах с помощью этой функции. Эта функция принимает идентификатор актива GameObject и два делегата функции: один для обработки создания GameObject на клиенте и один для обработки уничтожения GameObject на клиенте. Идентификатор актива может быть динамическим или просто идентификатором актива, найденным в сборном игровом объекте, который вы хотите создать (если он у вас есть).
Создание/отмену появления должно иметь эту подпись GameObject. Это определено в API высокого уровнясистеме создания многопользовательских возможностей для игр Unity. . Он построен поверх нижнего уровня транспортного уровня связи в реальном времени и выполняет многие общие задачи, необходимые для многопользовательских игр. Подробнее
См. в Словарь.
// Handles requests to spawn GameObjects on the client
public delegate GameObject SpawnDelegate(Vector3 position, NetworkHash128 assetId);
// Handles requests to unspawn GameObjects on the client
public delegate void UnSpawnDelegate(GameObject spawned);
Идентификатор ресурса, переданный функции создания, можно найти в файле NetworkIdentity.assetId для префабов, где он заполняется автоматически. Регистрация динамического идентификатора актива выполняется следующим образом:
// generate a new unique assetId
NetworkHash128 creatureAssetId = NetworkHash128.Parse("e2656f");
// register handlers for the new assetId
ClientScene.RegisterSpawnHandler(creatureAssetId, SpawnCreature, UnSpawnCreature);
// get assetId on an existing prefab
NetworkHash128 coinAssetId = coinPrefab.GetComponent().assetId;
// register handlers for an existing prefab you'd like to custom spawn
ClientScene.RegisterSpawnHandler(coinAssetId, SpawnCoin, UnSpawnCoin);
// spawn a coin - SpawnCoin is called on client
NetworkServer.Spawn(gameObject, coinAssetId);
Сами функции порождения реализованы с помощью подписи делегата. Вот генератор монет. SpawnCreature будет выглядеть так же, но иметь другую логику появления:
public GameObject SpawnCoin(Vector3 position, NetworkHash128 assetId)
{
return (GameObject)Instantiate(m_CoinPrefab, position, Quaternion.identity);
}
public void UnSpawnCoin(GameObject spawned)
{
Destroy(spawned);
}
При использовании пользовательских функций появления иногда полезно иметь возможность удалять объекты GameObject, не уничтожая их. Это можно сделать, вызвав NetworkServer.UnSpawn. Это приводит к тому, что клиентам отправляется сообщение об отмене порождения GameObject, так что на клиентах будет вызываться пользовательская функция отмены порождения. GameObject не уничтожается при вызове этой функции.
Обратите внимание, что на хосте игровые объекты не создаются для локального клиента, поскольку они уже существуют на сервере. Это также означает, что функции обработчика порождения не вызываются.
Настройка пула GameObject с пользовательскими обработчиками появления
Вот пример того, как можно настроить очень простую систему объединения игровых объектов с пользовательскими обработчиками появления. Затем при появлении и исчезновении игровые объекты помещаются в пул или удаляются из него.
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class SpawnManager : MonoBehaviour
{
public int m_ObjectPoolSize = 5;
public GameObject m_Prefab;
public GameObject[] m_Pool;
public NetworkHash128 assetId { get; set; }
public delegate GameObject SpawnDelegate(Vector3 position, NetworkHash128 assetId);
public delegate void UnSpawnDelegate(GameObject spawned);
void Start()
{
assetId = m_Prefab.GetComponent ().assetId;
m_Pool = new GameObject[m_ObjectPoolSize];
for (int i = 0; i < m_ObjectPoolSize; ++i)
{
m_Pool[i] = (GameObject)Instantiate(m_Prefab, Vector3.zero, Quaternion.identity);
m_Pool[i].name = "PoolObject" + i;
m_Pool[i].SetActive(false);
}
ClientScene.RegisterSpawnHandler(assetId, SpawnObject, UnSpawnObject);
}
public GameObject GetFromPool(Vector3 position)
{
foreach (var obj in m_Pool)
{
if (!obj.activeInHierarchy)
{
Debug.Log("Activating GameObject " + obj.name + " at " + position);
obj.transform.position = position;
obj.SetActive (true);
return obj;
}
}
Debug.LogError ("Could not grab GameObject from pool, nothing available");
return null;
}
public GameObject SpawnObject(Vector3 position, NetworkHash128 assetId)
{
return GetFromPool(position);
}
public void UnSpawnObject(GameObject spawned)
{
Debug.Log ("Re-pooling GameObject " + spawned.name);
spawned.SetActive (false);
}
}
Чтобы использовать этот менеджер, создайте новый пустой GameObject и назовите его «SpawnManager». Создайте новый скрипт с именем SpawnManager, скопируйте приведенный выше пример кода и присоедините его к* *новому игровому объекту SpawnManager. Затем перетащите префаб, который вы хотите создать несколько раз, в поле Prefab и установите Размер пула объектов (по умолчанию 5).
Наконец, настройте ссылку на SpawnManager в скрипте, который вы используете для перемещения игрока:
SpawnManager spawnManager;
void Start()
{
spawnManager = GameObject.Find("SpawnManager").GetComponent ();
}
Your player logic might contain something like this, which moves and fires coins:
void Update()
{
if (!isLocalPlayer)
return;
var x = Input.GetAxis("Horizontal")*0.1f;
var z = Input.GetAxis("Vertical")*0.1f;
transform.Translate(x, 0, z);
if (Input.GetKeyDown(KeyCode.Space))
{
// Command function is called on the client, but invoked on the server
CmdFire();
}
}
В логике огня на проигрывателе заставьте его использовать пул GameObject:
[Command]
void CmdFire()
{
// Set up coin on server
var coin = spawnManager.GetFromPool(transform.position + transform.forward);
coin.GetComponent().velocity = transform.forward*4;
// spawn coin on client, custom spawn handler is called
NetworkServer.Spawn(coin, spawnManager.assetId);
// when the coin is destroyed on the server, it is automatically destroyed on clients
StartCoroutine (Destroy (coin, 2.0f));
}
public IEnumerator Destroy(GameObject go, float timer)
{
yield return new WaitForSeconds (timer);
spawnManager.UnSpawnObject(go);
NetworkServer.UnSpawn(go);
}
Автоматическое уничтожение показывает, как игровые объекты возвращаются в пул и повторно используются при повторном запуске.