您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
160 行
7.4 KiB
160 行
7.4 KiB
using System;
|
|
using System.Runtime.CompilerServices;
|
|
using UnityEngine;
|
|
|
|
namespace Unity.Netcode
|
|
{
|
|
/// <summary>
|
|
/// A helper struct for serializing <see cref="NetworkObject"/>s over the network. Can be used in RPCs and <see cref="NetworkVariable{T}"/>.
|
|
/// </summary>
|
|
public struct NetworkObjectReference : INetworkSerializable, IEquatable<NetworkObjectReference>
|
|
{
|
|
private ulong m_NetworkObjectId;
|
|
|
|
/// <summary>
|
|
/// The <see cref="NetworkObject.NetworkObjectId"/> of the referenced <see cref="NetworkObject"/>.
|
|
/// </summary>
|
|
public ulong NetworkObjectId
|
|
{
|
|
get => m_NetworkObjectId;
|
|
internal set => m_NetworkObjectId = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new instance of the <see cref="NetworkObjectReference"/> struct.
|
|
/// </summary>
|
|
/// <param name="networkObject">The <see cref="NetworkObject"/> to reference.</param>
|
|
/// <exception cref="ArgumentNullException"></exception>
|
|
/// <exception cref="ArgumentException"></exception>
|
|
public NetworkObjectReference(NetworkObject networkObject)
|
|
{
|
|
if (networkObject == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(networkObject));
|
|
}
|
|
|
|
if (networkObject.IsSpawned == false)
|
|
{
|
|
throw new ArgumentException($"{nameof(NetworkObjectReference)} can only be created from spawned {nameof(NetworkObject)}s.");
|
|
}
|
|
|
|
m_NetworkObjectId = networkObject.NetworkObjectId;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new instance of the <see cref="NetworkObjectReference"/> struct.
|
|
/// </summary>
|
|
/// <param name="gameObject">The GameObject from which the <see cref="NetworkObject"/> component will be referenced.</param>
|
|
/// <exception cref="ArgumentNullException"></exception>
|
|
/// <exception cref="ArgumentException"></exception>
|
|
public NetworkObjectReference(GameObject gameObject)
|
|
{
|
|
if (gameObject == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(gameObject));
|
|
}
|
|
|
|
var networkObject = gameObject.GetComponent<NetworkObject>();
|
|
|
|
if (networkObject == null)
|
|
{
|
|
throw new ArgumentException($"Cannot create {nameof(NetworkObjectReference)} from {nameof(GameObject)} without a {nameof(NetworkObject)} component.");
|
|
}
|
|
|
|
if (networkObject.IsSpawned == false)
|
|
{
|
|
throw new ArgumentException($"{nameof(NetworkObjectReference)} can only be created from spawned {nameof(NetworkObject)}s.");
|
|
}
|
|
|
|
m_NetworkObjectId = networkObject.NetworkObjectId;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to get the <see cref="NetworkObject"/> referenced by this reference.
|
|
/// </summary>
|
|
/// <param name="networkObject">The <see cref="NetworkObject"/> which was found. Null if no object was found.</param>
|
|
/// <param name="networkManager">The networkmanager. Uses <see cref="NetworkManager.Singleton"/> to resolve if null.</param>
|
|
/// <returns>True if the <see cref="NetworkObject"/> was found; False if the <see cref="NetworkObject"/> was not found. This can happen if the <see cref="NetworkObject"/> has not been spawned yet. you can try getting the reference at a later point in time.</returns>
|
|
public bool TryGet(out NetworkObject networkObject, NetworkManager networkManager = null)
|
|
{
|
|
networkObject = Resolve(this, networkManager);
|
|
return networkObject != null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resolves the corresponding <see cref="NetworkObject"/> for this reference.
|
|
/// </summary>
|
|
/// <param name="networkObjectRef">The reference.</param>
|
|
/// <param name="networkManager">The networkmanager. Uses <see cref="NetworkManager.Singleton"/> to resolve if null.</param>
|
|
/// <returns>The resolves <see cref="NetworkObject"/>. Returns null if the networkobject was not found</returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
private static NetworkObject Resolve(NetworkObjectReference networkObjectRef, NetworkManager networkManager = null)
|
|
{
|
|
networkManager = networkManager != null ? networkManager : NetworkManager.Singleton;
|
|
networkManager.SpawnManager.SpawnedObjects.TryGetValue(networkObjectRef.m_NetworkObjectId, out NetworkObject networkObject);
|
|
|
|
return networkObject;
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public bool Equals(NetworkObjectReference other)
|
|
{
|
|
return m_NetworkObjectId == other.m_NetworkObjectId;
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override bool Equals(object obj)
|
|
{
|
|
return obj is NetworkObjectReference other && Equals(other);
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override int GetHashCode()
|
|
{
|
|
return m_NetworkObjectId.GetHashCode();
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
|
|
{
|
|
serializer.SerializeValue(ref m_NetworkObjectId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Implicitly convert <see cref="NetworkObjectReference"/> to <see cref="NetworkObject"/>.
|
|
/// </summary>
|
|
/// <param name="networkObjectRef">The <see cref="NetworkObjectReference"/> to convert from.</param>
|
|
/// <returns>The <see cref="NetworkObject"/> the <see cref="NetworkObjectReference"/> is referencing</returns>
|
|
public static implicit operator NetworkObject(NetworkObjectReference networkObjectRef) => Resolve(networkObjectRef);
|
|
|
|
/// <summary>
|
|
/// Implicitly convert <see cref="NetworkObject"/> to <see cref="NetworkObjectReference"/>.
|
|
/// </summary>
|
|
/// <param name="networkObject">The <see cref="NetworkObject"/> to convert from.</param>
|
|
/// <returns>The <see cref="NetworkObjectReference"/> created from the <see cref="NetworkObject"/> parameter</returns>
|
|
public static implicit operator NetworkObjectReference(NetworkObject networkObject) => new NetworkObjectReference(networkObject);
|
|
|
|
/// <summary>
|
|
/// Implicitly convert <see cref="NetworkObjectReference"/> to <see cref="GameObject"/>.
|
|
/// </summary>
|
|
/// <param name="networkObjectRef">The <see cref="NetworkObjectReference"/> to convert from.</param>
|
|
/// <returns>This returns the <see cref="GameObject"/> that the <see cref="NetworkObject"/> is attached to and is referenced by the <see cref="NetworkObjectReference"/> passed in as a parameter</returns>
|
|
public static implicit operator GameObject(NetworkObjectReference networkObjectRef)
|
|
{
|
|
var networkObject = Resolve(networkObjectRef);
|
|
if (networkObject != null)
|
|
{
|
|
return networkObject.gameObject;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Implicitly convert <see cref="GameObject"/> to <see cref="NetworkObject"/>.
|
|
/// </summary>
|
|
/// <param name="gameObject">The <see cref="GameObject"/> to convert from.</param>
|
|
/// <returns>The <see cref="NetworkObjectReference"/> created from the <see cref="GameObject"/> parameter that has a <see cref="NetworkObject"/> component attached to it</returns>
|
|
public static implicit operator NetworkObjectReference(GameObject gameObject) => new NetworkObjectReference(gameObject);
|
|
}
|
|
}
|