SyncVarNetworkIdentity.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // persistent NetworkIdentity SyncField which stores .netId internally.
  2. // this is necessary for cases like a player's target.
  3. // the target might run in and out of visibility range and become 'null'.
  4. // but the 'netId' remains and will always point to the monster if around.
  5. //
  6. // original Weaver code with netId workaround:
  7. /*
  8. // USER:
  9. [SyncVar(hook = "OnTargetChanged")]
  10. public NetworkIdentity target;
  11. // WEAVER GENERATED:
  12. private uint ___targetNetId;
  13. public NetworkIdentity Networktarget
  14. {
  15. get
  16. {
  17. return GetSyncVarNetworkIdentity(___targetNetId, ref target);
  18. }
  19. [param: In]
  20. set
  21. {
  22. if (!SyncVarNetworkIdentityEqual(value, ___targetNetId))
  23. {
  24. NetworkIdentity networktarget = Networktarget;
  25. SetSyncVarNetworkIdentity(value, ref target, 1uL, ref ___targetNetId);
  26. if (NetworkServer.localClientActive && !GetSyncVarHookGuard(1uL))
  27. {
  28. SetSyncVarHookGuard(1uL, value: true);
  29. OnTargetChanged(networktarget, value);
  30. SetSyncVarHookGuard(1uL, value: false);
  31. }
  32. }
  33. }
  34. }
  35. */
  36. using System;
  37. using System.Runtime.CompilerServices;
  38. namespace Mirror
  39. {
  40. // SyncField<NetworkIdentity> only stores an uint netId.
  41. // while providing .spawned lookup for convenience.
  42. // NOTE: server always knows all spawned. consider caching the field again.
  43. public class SyncVarNetworkIdentity : SyncVar<uint>
  44. {
  45. // .spawned lookup from netId overwrites base uint .Value
  46. public new NetworkIdentity Value
  47. {
  48. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  49. get => Utils.GetSpawnedInServerOrClient(base.Value);
  50. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  51. set => base.Value = value != null ? value.netId : 0;
  52. }
  53. // OnChanged Callback is for <uint, uint>.
  54. // Let's also have one for <NetworkIdentity, NetworkIdentity>
  55. public new event Action<NetworkIdentity, NetworkIdentity> Callback;
  56. // overwrite CallCallback to use the NetworkIdentity version instead
  57. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  58. protected override void InvokeCallback(uint oldValue, uint newValue) =>
  59. Callback?.Invoke(Utils.GetSpawnedInServerOrClient(oldValue), Utils.GetSpawnedInServerOrClient(newValue));
  60. // ctor
  61. // 'value = null' so we can do:
  62. // SyncVarNetworkIdentity = new SyncVarNetworkIdentity()
  63. // instead of
  64. // SyncVarNetworkIdentity = new SyncVarNetworkIdentity(null);
  65. public SyncVarNetworkIdentity(NetworkIdentity value = null)
  66. : base(value != null ? value.netId : 0) {}
  67. // implicit conversion: NetworkIdentity value = SyncFieldNetworkIdentity
  68. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  69. public static implicit operator NetworkIdentity(SyncVarNetworkIdentity field) => field.Value;
  70. // implicit conversion: SyncFieldNetworkIdentity = value
  71. // even if SyncField is readonly, it's still useful: SyncFieldNetworkIdentity = target;
  72. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  73. public static implicit operator SyncVarNetworkIdentity(NetworkIdentity value) => new SyncVarNetworkIdentity(value);
  74. // NOTE: overloading all == operators blocks '== null' checks with an
  75. // "ambiguous invocation" error. that's good. this way user code like
  76. // "player.target == null" won't compile instead of silently failing!
  77. // == operator for comparisons like Player.target==monster
  78. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  79. public static bool operator ==(SyncVarNetworkIdentity a, SyncVarNetworkIdentity b) =>
  80. a.Value == b.Value;
  81. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  82. public static bool operator !=(SyncVarNetworkIdentity a, SyncVarNetworkIdentity b) => !(a == b);
  83. // == operator for comparisons like Player.target==monster
  84. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  85. public static bool operator ==(SyncVarNetworkIdentity a, NetworkIdentity b) =>
  86. a.Value == b;
  87. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  88. public static bool operator !=(SyncVarNetworkIdentity a, NetworkIdentity b) => !(a == b);
  89. // == operator for comparisons like Player.target==monster
  90. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  91. public static bool operator ==(NetworkIdentity a, SyncVarNetworkIdentity b) =>
  92. a == b.Value;
  93. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  94. public static bool operator !=(NetworkIdentity a, SyncVarNetworkIdentity b) => !(a == b);
  95. // if we overwrite == operators, we also need to overwrite .Equals.
  96. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  97. public override bool Equals(object obj) => obj is SyncVarNetworkIdentity value && this == value;
  98. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  99. public override int GetHashCode() => Value.GetHashCode();
  100. }
  101. }