Fish-Net: Networking Evolved
  • Introduction
    • Getting Started
    • Showcase
      • Upcoming Releases
    • Legal Restrictions
    • Pro, Projects, and Support
    • Business Support
    • Branding
  • Manual
    • General
      • Unity Compatibility
      • Changelog
        • Development Road Map
        • Major Version Update Solutions
      • Development
      • Performance
        • Benchmark Setup
        • Fish-Networking Vs Mirror
      • Terminology
        • Miscellaneous
        • Communicating
        • Server, Client, Host
      • Transports
      • Add-ons
        • Edgegap and other Hosting
        • Fish-Network-Discovery
      • Feature Comparison
      • Upgrading To Fish-Networking
    • Guides
      • Frequently Asked Questions (FAQ)
      • Creating Bug Reports
        • Report Example
      • Technical Limitations
      • Third-Party
      • Getting Started
        • Commonly Used Guides
        • Ownership - Moving Soon
        • Step-by-Step
          • Getting Connected
          • Preparing Your Player
      • Components
        • Managers
          • NetworkManager
          • TimeManager
          • PredictionManager
          • ServerManager
          • ClientManager
          • SceneManager
          • TransportManager
            • IntermediateLayer
          • StatisticsManager
          • ObserverManager
            • HashGrid
          • RollbackManager (Pro Feature)
        • Transports
          • FishyWebRTC
          • Bayou
          • FishyEOS (Epic Online Services)
          • FishyFacepunch (Steam)
          • FishyRealtime
          • FishySteamworks (Steam)
          • FishyUnityTransport
          • Multipass
          • Tugboat
          • Yak (Pro Feature)
        • Prediction
          • Network Collider
            • NetworkCollision
            • NetworkCollision2D
            • NetworkTrigger
            • NetworkTrigger2D
          • OfflineRigidbody
          • PredictedOwner
          • PredictedSpawn
        • Utilities
          • Tick Smoothers
            • NetworkTickSmoother
            • OfflineTickSmoother
          • MonoTickSmoother [Obsolete]
          • DetachableNetworkTickSmoother [Obsolete]
          • BandwidthDisplay
          • DefaultScene
          • PingDisplay
        • Authenticator
        • ColliderRollback
        • NetworkAnimator
        • NetworkBehaviour
        • NetworkTransform
        • NetworkObject
        • NetworkObserver
      • InstanceFinder
      • Ownership
        • Using Ownership To Read Values
      • Spawning and Despawning
        • Predicted Spawning
        • Nested NetworkObjects
        • Object Pooling
      • Components
      • NetworkBehaviour
      • NetworkObjects
      • Attributes, Quality of Life
      • Remote Procedure Calls
        • Broadcast
      • SyncTypes
        • Customizing Behavior
        • SyncVar
        • SyncList
        • SyncHashSet
        • SyncDictionary
        • SyncTimer
        • SyncStopwatch
        • Custom SyncType
      • Observers
        • Modifying Conditions
        • Custom Conditions
      • Automatic Serializers
      • Custom Serializers
        • Interface Serializers
        • Inheritance Serializers
      • Addressables
      • Scene Management
        • Scene Events
        • Scene Data
          • SceneLookupData
          • SceneLoadData
          • SceneUnloadData
        • Loading Scenes
        • Unloading Scenes
        • Scene Stacking
        • Scene Caching
        • Scene Visibility
        • Persisting NetworkObjects
        • Custom Scene Processors
          • Addressables
      • Transports
        • Multipass
      • Prediction
        • What Is Client-Side Prediction
        • Configuring PredictionManager
        • Configuring TimeManager
        • Configuring NetworkObject
        • Offline Rigidbodies
        • Interpolations
        • Creating Code
          • Controlling An Object
          • Non-Controlled Object
          • Understanding ReplicateState
            • Using States In Code
            • Predicting States In Code
          • Advanced Controls
        • Custom Comparers
        • PredictionRigidbody
        • Using NetworkColliders
      • Lag Compensation
        • States
        • Raycast
        • Projectiles
    • Server Hosting
      • Edgegap - Official Partner
        • Getting Started with Edgegap
      • Hathora
        • Getting Started with Hathora
      • Amazon Web Services (AWS)
        • Getting Started with AWS
    • API
Powered by GitBook
On this page
  1. Manual
  2. Guides
  3. Prediction
  4. Creating Code

Non-Controlled Object

A very simple script for keeping non-controlled objects in synchronization with the prediction system.

PreviousControlling An ObjectNextUnderstanding ReplicateState

Last updated 2 months ago

Many games will require physics bodies to be networked, even if not controlled by players or the server. These objects can also work along-side the new state system by adding a basic prediction script on them.

It's worth noting that you can also 'control' non-owned objects on the server by using base.HasAuthority. This was discussed previously .

Sample Script

Below is a full example script to synchronize a non-controlled rigidbody. Since the rigidbody is only reactive, input polling is not needed. Otherwise you'll find the data structures are near identical to the ones where we took input.

It is strongly recommended to review the guide for additional notes in understanding the code below.

public class RigidbodySync : NetworkBehaviour
{
    //Replicate structure.
    public struct ReplicateData : IReplicateData
    {
        //The uint isn't used but Unity C# version does not
        //allow parameter-less constructors we something
        //must be set as a parameter.
        public ReplicateData(uint unused) : this() {}
        private uint _tick;
        public void Dispose() { }
        public uint GetTick() => _tick;
        public void SetTick(uint value) => _tick = value;
    }
    //Reconcile structure.
    public struct ReconcileData : IReconcileData
    {
        public PredictionRigidbody PredictionRigidbody;
        
        public ReconcileData(PredictionRigidbody pr) : this()
        {
            PredictionRigidbody = pr;
        }
    
        private uint _tick;
        public void Dispose() { }
        public uint GetTick() => _tick;
        public void SetTick(uint value) => _tick = value;
    }

    //Forces are not applied in this example but you
    //could definitely still apply forces to the PredictionRigidbody
    //even with no controller, such as if you wanted to bump it
    //with a player.
    private PredictionRigidbody PredictionRigidbody;
    
    private void Awake()
    {
        PredictionRigidbody = ResettableObjectCaches<PredictionRigidbody>.Retrieve();
        PredictionRigidbody.Initialize(GetComponent<Rigidbody>());
    }
    private void OnDestroy()
    {
        ResettableObjectCaches<PredictionRigidbody>.StoreAndDefault(ref PredictionRigidbody);
    }

    //In this example we do not need to use OnTick, only OnPostTick.
    //Because input is not processed on this object you only
    //need to pass in default for RunInputs, which can safely
    //be done in OnPostTick.
    public override void OnStartNetwork()
    {
        base.TimeManager.OnPostTick += TimeManager_OnPostTick;
    }

    public override void OnStopNetwork()
    {
        base.TimeManager.OnPostTick -= TimeManager_OnPostTick;
    }

    private void TimeManager_OnPostTick()
    {
        RunInputs(default);
        CreateReconcile();
    }

    [Replicate]
    private void RunInputs(ReplicateData md, ReplicateState state = ReplicateState.Invalid, Channel channel = Channel.Unreliable)
    {
        //If this object is free-moving and uncontrolled then there is no logic.
        //Just let physics do it's thing.	
    }

    //Create the reconcile data here and call your reconcile method.
    public override void CreateReconcile()
    {
        ReconcileData rd = new ReconcileData(PredictionRigidbody);
        ReconcileState(rd);
    }

    [Reconcile]
    private void ReconcileState(ReconcileData data, Channel channel = Channel.Unreliable)
    {
        //Call reconcile on your PredictionRigidbody field passing in
        //values from data.
        PredictionRigidbody.Reconcile(data.PredictionRigidbody);
    }
}
here
controlling objects