This repository has been archived on 2025-04-22. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
com.unity.netcode.gameobjects/Components/NetworkRigidBodyBase.cs
Unity Technologies 143a6cbd34 com.unity.netcode.gameobjects@2.0.0-exp.2
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com).

## [2.0.0-exp.2] - 2024-04-02

### Added
- Added updates to all internal messages to account for a distributed authority network session connection.  (#2863)
- Added `NetworkRigidbodyBase` that provides users with a more customizable network rigidbody, handles both `Rigidbody` and `Rigidbody2D`, and provides an option to make `NetworkTransform` use the rigid body for motion.  (#2863)
  - For a customized `NetworkRigidbodyBase` class:
    - `NetworkRigidbodyBase.AutoUpdateKinematicState` provides control on whether the kinematic setting will be automatically set or not when ownership changes.
    - `NetworkRigidbodyBase.AutoSetKinematicOnDespawn` provides control on whether isKinematic will automatically be set to true when the associated `NetworkObject` is despawned.
    - `NetworkRigidbodyBase.Initialize` is a protected method that, when invoked, will initialize the instance. This includes options to:
      - Set whether using a `RigidbodyTypes.Rigidbody` or `RigidbodyTypes.Rigidbody2D`.
      - Includes additional optional parameters to set the `NetworkTransform`, `Rigidbody`, and `Rigidbody2d` to use.
  - Provides additional public methods:
    - `NetworkRigidbodyBase.GetPosition` to return the position of the `Rigidbody` or `Rigidbody2d` (depending upon its initialized setting).
    - `NetworkRigidbodyBase.GetRotation` to return the rotation of the `Rigidbody` or `Rigidbody2d` (depending upon its initialized setting).
    - `NetworkRigidbodyBase.MovePosition` to move to the position of the `Rigidbody` or `Rigidbody2d` (depending upon its initialized setting).
    - `NetworkRigidbodyBase.MoveRotation` to move to the rotation of the `Rigidbody` or `Rigidbody2d` (depending upon its initialized setting).
    - `NetworkRigidbodyBase.Move` to move to the position and rotation of the `Rigidbody` or `Rigidbody2d` (depending upon its initialized setting).
    - `NetworkRigidbodyBase.Move` to move to the position and rotation of the `Rigidbody` or `Rigidbody2d` (depending upon its initialized setting).
    - `NetworkRigidbodyBase.SetPosition` to set the position of the `Rigidbody` or `Rigidbody2d` (depending upon its initialized setting).
    - `NetworkRigidbodyBase.SetRotation` to set the rotation of the `Rigidbody` or `Rigidbody2d` (depending upon its initialized setting).
    - `NetworkRigidbodyBase.ApplyCurrentTransform` to set the position and rotation of the `Rigidbody` or `Rigidbody2d` based on the associated `GameObject` transform (depending upon its initialized setting).
    - `NetworkRigidbodyBase.WakeIfSleeping` to wake up the rigid body if sleeping.
    - `NetworkRigidbodyBase.SleepRigidbody` to put the rigid body to sleep.
    - `NetworkRigidbodyBase.IsKinematic` to determine if the `Rigidbody` or `Rigidbody2d` (depending upon its initialized setting) is currently kinematic.
    - `NetworkRigidbodyBase.SetIsKinematic` to set the `Rigidbody` or `Rigidbody2d` (depending upon its initialized setting) current kinematic state.
    - `NetworkRigidbodyBase.ResetInterpolation` to reset the `Rigidbody` or `Rigidbody2d` (depending upon its initialized setting) back to its original interpolation value when initialized.
  - Now includes a `MonoBehaviour.FixedUpdate` implementation that will update the assigned `NetworkTransform` when `NetworkRigidbodyBase.UseRigidBodyForMotion` is true. (#2863)
- Added `RigidbodyContactEventManager` that provides a more optimized way to process collision enter and collision stay events as opposed to the `Monobehaviour` approach. (#2863)
  - Can be used in client-server and distributed authority modes, but is particularly useful in distributed authority.
- Added rigid body motion updates to `NetworkTransform` which allows users to set interolation on rigid bodies. (#2863)
  - Extrapolation is only allowed on authoritative instances, but custom class derived from `NetworkRigidbodyBase` or `NetworkRigidbody` or `NetworkRigidbody2D` automatically switches non-authoritative instances to interpolation if set to extrapolation.
- Added distributed authority mode support to `NetworkAnimator`. (#2863)
- Added session mode selection to `NetworkManager` inspector view. (#2863)
- Added distributed authority permissions feature. (#2863)
- Added distributed authority mode specific `NetworkObject` permissions flags (Distributable, Transferable, and RequestRequired). (#2863)
- Added distributed authority mode specific `NetworkObject.SetOwnershipStatus` method that applies one or more `NetworkObject` instance's ownership flags. If updated when spawned, the ownership permission changes are synchronized with the other connected clients. (#2863)
- Added distributed authority mode specific `NetworkObject.RemoveOwnershipStatus` method that removes one or more `NetworkObject` instance's ownership flags. If updated when spawned, the ownership permission changes are synchronized with the other connected clients. (#2863)
- Added distributed authority mode specific `NetworkObject.HasOwnershipStatus` method that will return (true or false) whether one or more ownership flags is set. (#2863)
- Added distributed authority mode specific `NetworkObject.SetOwnershipLock` method that locks ownership of a `NetworkObject` to prevent ownership from changing until the current owner releases the lock. (#2863)
- Added distributed authority mode specific `NetworkObject.RequestOwnership` method that sends an ownership request to the current owner of a spawned `NetworkObject` instance. (#2863)
- Added distributed authority mode specific `NetworkObject.OnOwnershipRequested` callback handler that is invoked on the owner/authoritative side when a non-owner requests ownership. Depending upon the boolean returned value depends upon whether the request is approved or denied. (#2863)
- Added distributed authority mode specific `NetworkObject.OnOwnershipRequestResponse` callback handler that is invoked when a non-owner's request has been processed. This callback includes a `NetworkObjet.OwnershipRequestResponseStatus` response parameter that describes whether the request was approved or the reason why it was not approved. (#2863)
- Added distributed authority mode specific `NetworkObject.DeferDespawn` method that defers the despawning of `NetworkObject` instances on non-authoritative clients based on the tick offset parameter. (#2863)
- Added distributed authority mode specific `NetworkObject.OnDeferredDespawnComplete` callback handler that can be used to further control when deferring the despawning of a `NetworkObject` on non-authoritative instances. (#2863)
- Added `NetworkClient.SessionModeType` as one way to determine the current session mode of the network session a client is connected to. (#2863)
- Added distributed authority mode specific `NetworkClient.IsSessionOwner` property to determine if the current local client is the current session owner of a distributed authority session. (#2863)
- Added distributed authority mode specific client side spawning capabilities. When running in distributed authority mode, clients can instantiate and spawn `NetworkObject` instances (the local client is authomatically the owner of the spawned object). (#2863)
  - This is useful to better visually synchronize owner authoritative motion models and newly spawned `NetworkObject` instances (i.e. projectiles for example).
- Added distributed authority mode specific client side player spawning capabilities. Clients will automatically spawn their associated player object locally. (#2863)
- Added distributed authority mode specific `NetworkConfig.AutoSpawnPlayerPrefabClientSide` property (default is true) to provide control over the automatic spawning of player prefabs on the local client side. (#2863)
- Added distributed authority mode specific `NetworkManager.OnFetchLocalPlayerPrefabToSpawn` callback that, when assigned, will allow the local client to provide the player prefab to be spawned for the local client. (#2863)
  - This is only invoked if the `NetworkConfig.AutoSpawnPlayerPrefabClientSide` property is set to true.
- Added distributed authority mode specific `NetworkBehaviour.HasAuthority` property that determines if the local client has authority over the associated `NetworkObject` instance (typical use case is within a `NetworkBehaviour` script much like that of `IsServer` or `IsClient`). (#2863)
- Added distributed authority mode specific `NetworkBehaviour.IsSessionOwner` property that determines if the local client is the session owner (typical use case would be to determine if the local client can has scene management authority within a `NetworkBehaviour` script). (#2863)
- Added support for distributed authority mode scene management where the currently assigned session owner can start scene events (i.e. scene loading and scene unloading). (#2863)

### Fixed

- Fixed issue where the host was not invoking `OnClientDisconnectCallback` for its own local client when internally shutting down. (#2822)
- Fixed issue where NetworkTransform could potentially attempt to "unregister" a named message prior to it being registered. (#2807)
- Fixed issue where in-scene placed `NetworkObject`s with complex nested children `NetworkObject`s (more than one child in depth) would not synchronize properly if WorldPositionStays was set to true. (#2796)

### Changed
- Changed client side awareness of other clients is now the same as a server or host. (#2863)
- Changed `NetworkManager.ConnectedClients` can now be accessed by both server and clients. (#2863)
- Changed `NetworkManager.ConnectedClientsList` can now be accessed by both server and clients. (#2863)
- Changed `NetworkTransform` defaults to owner authoritative when connected to a distributed authority session. (#2863)
- Changed `NetworkVariable` defaults to owner write and everyone read permissions when connected to a distributed authority session (even if declared with server read or write permissions).  (#2863)
- Changed `NetworkObject` no longer implements the `MonoBehaviour.Update` method in order to determine whether a `NetworkObject` instance has been migrated to a different scene. Instead, only `NetworkObjects` with the `SceneMigrationSynchronization` property set will be updated internally during the `NetworkUpdateStage.PostLateUpdate` by `NetworkManager`. (#2863)
- Changed `NetworkManager` inspector view layout where properties are now organized by category. (#2863)
- Changed `NetworkTransform` to now use `NetworkTransformMessage` as opposed to named messages for NetworkTransformState updates. (#2810)
- Changed `CustomMessageManager` so it no longer attempts to register or "unregister" a null or empty string and will log an error if this condition occurs. (#2807)
2024-04-02 00:00:00 +00:00

536 lines
19 KiB
C#

#if COM_UNITY_MODULES_PHYSICS
using System.Runtime.CompilerServices;
using UnityEngine;
namespace Unity.Netcode.Components
{
/// <summary>
/// NetworkRigidbodyBase is a unified <see cref="Rigidbody"/> and <see cref="Rigidbody2D"/> integration that helps to synchronize physics motion, collision, and interpolation
/// when used with a <see cref="NetworkTransform"/>.
/// </summary>
/// <remarks>
/// For a customizable netcode Rigidbody, create your own component from this class and use <see cref="Initialize(RigidbodyTypes, NetworkTransform, Rigidbody2D, Rigidbody)"/>
/// during instantiation (i.e. invoked from within the Awake method). You can re-initialize after having initialized but only when the <see cref="NetworkObject"/> is not spawned.
/// </remarks>
public abstract class NetworkRigidbodyBase : NetworkBehaviour
{
/// <summary>
/// When enabled, the associated <see cref="NetworkTransform"/> will use the Rigidbody/Rigidbody2D to apply and synchronize changes in position, rotation, and
/// allows for the use of Rigidbody interpolation/extrapolation.
/// </summary>
/// <remarks>
/// If <see cref="NetworkTransform.Interpolate"/> is enabled, non-authoritative instances can only use Rigidbody interpolation. If a network prefab is set to
/// extrapolation and <see cref="NetworkTransform.Interpolate"/> is enabled, then non-authoritative instances will automatically be adjusted to use Rigidbody
/// interpolation while the authoritative instance will still use extrapolation.
/// </remarks>
public bool UseRigidBodyForMotion;
/// <summary>
/// When enabled (default), automatically set the Kinematic state of the Rigidbody based on ownership.
/// When disabled, Kinematic state needs to be set by external script(s).
/// </summary>
public bool AutoUpdateKinematicState = true;
/// <summary>
/// Primarily applies to the <see cref="AutoUpdateKinematicState"/> property when disabled but you still want
/// the Rigidbody to be automatically set to Kinematic when despawned.
/// </summary>
public bool AutoSetKinematicOnDespawn = true;
// Determines if this is a Rigidbody or Rigidbody2D implementation
private bool m_IsRigidbody2D => RigidbodyType == RigidbodyTypes.Rigidbody2D;
// Used to cache the authority state of this Rigidbody during the last frame
private bool m_IsAuthority;
private Rigidbody m_Rigidbody;
private Rigidbody2D m_Rigidbody2D;
private NetworkTransform m_NetworkTransform;
private enum InterpolationTypes
{
None,
Interpolate,
Extrapolate
}
private InterpolationTypes m_OriginalInterpolation;
/// <summary>
/// Used to define the type of Rigidbody implemented.
/// <see cref=""/>
/// </summary>
public enum RigidbodyTypes
{
Rigidbody,
Rigidbody2D,
}
public RigidbodyTypes RigidbodyType { get; private set; }
/// <summary>
/// Initializes the networked Rigidbody based on the <see cref="RigidbodyTypes"/>
/// passed in as a parameter.
/// </summary>
/// <remarks>
/// Cannot be initialized while the associated <see cref="NetworkObject"/> is spawned.
/// </remarks>
/// <param name="rigidbodyType">type of rigid body being initialized</param>
/// <param name="rigidbody2D">(optional) The <see cref="Rigidbody2D"/> to be used</param>
/// <param name="rigidbody">(optional) The <see cref="Rigidbody"/> to be used</param>
protected void Initialize(RigidbodyTypes rigidbodyType, NetworkTransform networkTransform = null, Rigidbody2D rigidbody2D = null, Rigidbody rigidbody = null)
{
// Don't initialize if already spawned
if (IsSpawned)
{
Debug.LogError($"[{name}] Attempting to initialize while spawned is not allowed.");
return;
}
RigidbodyType = rigidbodyType;
m_Rigidbody2D = rigidbody2D;
m_Rigidbody = rigidbody;
m_NetworkTransform = networkTransform;
if (m_IsRigidbody2D && m_Rigidbody2D == null)
{
m_Rigidbody2D = GetComponent<Rigidbody2D>();
}
else if (m_Rigidbody == null)
{
m_Rigidbody = GetComponent<Rigidbody>();
}
SetOriginalInterpolation();
if (m_NetworkTransform == null)
{
m_NetworkTransform = GetComponent<NetworkTransform>();
}
if (m_NetworkTransform != null)
{
m_NetworkTransform.RegisterRigidbody(this);
}
else
{
throw new System.Exception($"[Missing {nameof(NetworkTransform)}] No {nameof(NetworkTransform)} is assigned or can be found during initialization!");
}
if (AutoUpdateKinematicState)
{
SetIsKinematic(true);
}
}
/// <summary>
/// Gets the position of the Rigidbody
/// </summary>
/// <returns><see cref="Vector3"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3 GetPosition()
{
if (m_IsRigidbody2D)
{
return m_Rigidbody2D.position;
}
else
{
return m_Rigidbody.position;
}
}
/// <summary>
/// Gets the rotation of the Rigidbody
/// </summary>
/// <returns><see cref="Quaternion"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Quaternion GetRotation()
{
if (m_IsRigidbody2D)
{
var quaternion = Quaternion.identity;
var angles = quaternion.eulerAngles;
angles.z = m_Rigidbody2D.rotation;
quaternion.eulerAngles = angles;
return quaternion;
}
else
{
return m_Rigidbody.rotation;
}
}
/// <summary>
/// Moves the rigid body
/// </summary>
/// <param name="position">The <see cref="Vector3"/> position to move towards</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void MovePosition(Vector3 position)
{
if (m_IsRigidbody2D)
{
m_Rigidbody2D.MovePosition(position);
}
else
{
m_Rigidbody.MovePosition(position);
}
}
/// <summary>
/// Directly applies a position (like teleporting)
/// </summary>
/// <param name="position"><see cref="Vector3"/> position to apply to the Rigidbody</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetPosition(Vector3 position)
{
if (m_IsRigidbody2D)
{
m_Rigidbody2D.position = position;
}
else
{
m_Rigidbody.position = position;
}
}
/// <summary>
/// Applies the rotation and position of the <see cref="GameObject"/>'s <see cref="Transform"/>
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ApplyCurrentTransform()
{
if (m_IsRigidbody2D)
{
m_Rigidbody2D.position = transform.position;
m_Rigidbody2D.rotation = transform.eulerAngles.z;
}
else
{
m_Rigidbody.position = transform.position;
m_Rigidbody.rotation = transform.rotation;
}
}
/// <summary>
/// Rotatates the Rigidbody towards a specified rotation
/// </summary>
/// <param name="rotation">The rotation expressed as a <see cref="Quaternion"/></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void MoveRotation(Quaternion rotation)
{
if (m_IsRigidbody2D)
{
m_Rigidbody2D.MoveRotation(rotation);
}
else
{
m_Rigidbody.MoveRotation(rotation);
}
}
/// <summary>
/// Applies a rotation to the Rigidbody
/// </summary>
/// <param name="rotation">The rotation to apply expressed as a <see cref="Quaternion"/></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetRotation(Quaternion rotation)
{
if (m_IsRigidbody2D)
{
m_Rigidbody2D.rotation = rotation.eulerAngles.z;
}
else
{
m_Rigidbody.rotation = rotation;
}
}
/// <summary>
/// Sets the original interpolation of the Rigidbody while taking the Rigidbody type into consideration
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SetOriginalInterpolation()
{
if (m_IsRigidbody2D)
{
switch (m_Rigidbody2D.interpolation)
{
case RigidbodyInterpolation2D.None:
{
m_OriginalInterpolation = InterpolationTypes.None;
break;
}
case RigidbodyInterpolation2D.Interpolate:
{
m_OriginalInterpolation = InterpolationTypes.Interpolate;
break;
}
case RigidbodyInterpolation2D.Extrapolate:
{
m_OriginalInterpolation = InterpolationTypes.Extrapolate;
break;
}
}
}
else
{
switch (m_Rigidbody.interpolation)
{
case RigidbodyInterpolation.None:
{
m_OriginalInterpolation = InterpolationTypes.None;
break;
}
case RigidbodyInterpolation.Interpolate:
{
m_OriginalInterpolation = InterpolationTypes.Interpolate;
break;
}
case RigidbodyInterpolation.Extrapolate:
{
m_OriginalInterpolation = InterpolationTypes.Extrapolate;
break;
}
}
}
}
/// <summary>
/// Wakes the Rigidbody if it is sleeping
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WakeIfSleeping()
{
if (m_IsRigidbody2D)
{
if (m_Rigidbody2D.IsSleeping())
{
m_Rigidbody2D.WakeUp();
}
}
else
{
if (m_Rigidbody.IsSleeping())
{
m_Rigidbody.WakeUp();
}
}
}
/// <summary>
/// Puts the Rigidbody to sleep
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SleepRigidbody()
{
if (m_IsRigidbody2D)
{
m_Rigidbody2D.Sleep();
}
else
{
m_Rigidbody.Sleep();
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsKinematic()
{
if (m_IsRigidbody2D)
{
return m_Rigidbody2D.isKinematic;
}
else
{
return m_Rigidbody.isKinematic;
}
}
/// <summary>
/// Sets the kinematic state of the Rigidbody and handles updating the Rigidbody's
/// interpolation setting based on the Kinematic state.
/// </summary>
/// <remarks>
/// When using the Rigidbody for <see cref="NetworkTransform"/> motion, this automatically
/// adjusts from extrapolation to interpolation if:
/// - The Rigidbody was originally set to extrapolation
/// - The NetworkTransform is set to interpolate
/// When the two above conditions are true:
/// - When switching from non-kinematic to kinematic this will automatically
/// switch the Rigidbody from extrapolation to interpolate.
/// - When switching from kinematic to non-kinematic this will automatically
/// switch the Rigidbody from interpolation back to extrapolation.
/// </remarks>
/// <param name="isKinematic"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetIsKinematic(bool isKinematic)
{
if (m_IsRigidbody2D)
{
m_Rigidbody2D.isKinematic = isKinematic;
}
else
{
m_Rigidbody.isKinematic = isKinematic;
}
// If we are not spawned, then exit early
if (!IsSpawned)
{
return;
}
if (UseRigidBodyForMotion)
{
// Only if the NetworkTransform is set to interpolate do we need to check for extrapolation
if (m_NetworkTransform.Interpolate && m_OriginalInterpolation == InterpolationTypes.Extrapolate)
{
if (IsKinematic())
{
// If not already set to interpolate then set the Rigidbody to interpolate
if (m_Rigidbody.interpolation == RigidbodyInterpolation.Extrapolate)
{
// Sleep until the next fixed update when switching from extrapolation to interpolation
SleepRigidbody();
SetInterpolation(InterpolationTypes.Interpolate);
}
}
else
{
// Switch it back to the original interpolation if non-kinematic (doesn't require sleep).
SetInterpolation(m_OriginalInterpolation);
}
}
}
else
{
SetInterpolation(m_IsAuthority ? m_OriginalInterpolation : (m_NetworkTransform.Interpolate ? InterpolationTypes.None : m_OriginalInterpolation));
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SetInterpolation(InterpolationTypes interpolationType)
{
switch (interpolationType)
{
case InterpolationTypes.None:
{
if (m_IsRigidbody2D)
{
m_Rigidbody2D.interpolation = RigidbodyInterpolation2D.None;
}
else
{
m_Rigidbody.interpolation = RigidbodyInterpolation.None;
}
break;
}
case InterpolationTypes.Interpolate:
{
if (m_IsRigidbody2D)
{
m_Rigidbody2D.interpolation = RigidbodyInterpolation2D.Interpolate;
}
else
{
m_Rigidbody.interpolation = RigidbodyInterpolation.Interpolate;
}
break;
}
case InterpolationTypes.Extrapolate:
{
if (m_IsRigidbody2D)
{
m_Rigidbody2D.interpolation = RigidbodyInterpolation2D.Extrapolate;
}
else
{
m_Rigidbody.interpolation = RigidbodyInterpolation.Extrapolate;
}
break;
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ResetInterpolation()
{
SetInterpolation(m_OriginalInterpolation);
}
protected override void OnOwnershipChanged(ulong previous, ulong current)
{
UpdateOwnershipAuthority();
base.OnOwnershipChanged(previous, current);
}
/// <summary>
/// Sets the authority based on whether it is server or owner authoritative
/// </summary>
/// <remarks>
/// Distributed authority sessions will always be owner authoritative.
/// </remarks>
internal void UpdateOwnershipAuthority()
{
if (NetworkManager.DistributedAuthorityMode)
{
// When in distributed authority mode, always use HasAuthority
m_IsAuthority = HasAuthority;
}
else
{
if (m_NetworkTransform.IsServerAuthoritative())
{
m_IsAuthority = NetworkManager.IsServer;
}
else
{
m_IsAuthority = IsOwner;
}
}
if (AutoUpdateKinematicState)
{
SetIsKinematic(!m_IsAuthority);
}
}
/// <inheritdoc />
public override void OnNetworkSpawn()
{
UpdateOwnershipAuthority();
}
/// <inheritdoc />
public override void OnNetworkDespawn()
{
// If we are automatically handling the kinematic state...
if (AutoUpdateKinematicState || AutoSetKinematicOnDespawn)
{
// Turn off physics for the rigid body until spawned, otherwise
// non-owners can run fixed updates before the first full
// NetworkTransform update and physics will be applied (i.e. gravity, etc)
SetIsKinematic(true);
}
SetInterpolation(m_OriginalInterpolation);
}
/// <summary>
/// When <see cref="UseRigidBodyForMotion"/> is enabled, the <see cref="NetworkTransform"/> will update Kinematic instances using
/// the Rigidbody's move methods allowing Rigidbody interpolation settings to be taken into consideration by the physics simulation.
/// </summary>
/// <remarks>
/// This will update the associated <see cref="NetworkTransform"/> during FixedUpdate which also avoids the added expense of adding
/// a FixedUpdate to all <see cref="NetworkTransform"/> instances where some might not be using a Rigidbody.
/// </remarks>
private void FixedUpdate()
{
if (!IsSpawned || m_NetworkTransform == null || !UseRigidBodyForMotion)
{
return;
}
m_NetworkTransform.OnFixedUpdate();
}
}
}
#endif // COM_UNITY_MODULES_PHYSICS