Fish-Net: Networking Evolved
  • Overview
    • What is FishNet?
      • Features
        • Unity Compatibility
        • Performance
          • Benchmark Setup
          • Fish-Networking Vs Mirror
      • Pro, Projects, and Support
      • Business Support
      • Development
        • Changelog
        • Roadmap
      • Branding
      • Legal Restrictions
    • Showcase
      • Upcoming Releases
    • Asset Integrations
      • Fish-Network-Discovery
    • Community Resources
  • Guides
    • Getting Started
      • Installing Fish-Networking
      • Getting Connected
      • Preparing Your Player
      • Moving Your Player Around
      • Spawning and Despawning Items
      • Using SyncVars to Sync Colors
      • Connecting to Remote Devices
      • Beyond the Basics
    • High-Level Overview
      • Fundamentals
      • Networking Models
      • Terminology
        • Server, Client, Host
        • Communicating
        • Miscellaneous
      • Transports
    • Features
      • Server and Client Identification
        • Executing on Server or Client
        • NetworkConnections
      • Networked GameObjects and Scripts
        • NetworkObjects
        • NetworkBehaviour
        • Spawning and Despawning
          • Predicted Spawning
          • Nested NetworkObjects
          • Object Pooling
      • Network State Events
      • Network Communication
        • Remote Procedure Calls
        • SyncTypes
          • Customizing Behavior
          • SyncVar
          • SyncList
          • SyncHashSet
          • SyncDictionary
          • SyncTimer
          • SyncStopwatch
          • Custom SyncType
        • Broadcasts
      • Data Serialization
        • Custom Serializers
          • Interface Serializers
          • Inheritance Serializers
      • Ownership
        • Using Ownership To Read Values
      • Area of Interest (Observer System)
        • Modifying Conditions
        • Custom Conditions
      • Scene Management
        • Scene Events
        • Scene Data
          • SceneLookupData
          • SceneLoadData
          • SceneUnloadData
        • Loading Scenes
          • Automatic Online and Offline Scenes
        • Unloading Scenes
        • Scene Stacking
        • Scene Caching
        • Scene Visibility
        • Persisting NetworkObjects
        • Custom Scene Processors
          • Addressables
      • InstanceFinder
      • 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
    • Upgrading API
    • Server Hosting
      • Edgegap - Official Partner
        • Getting Started with Edgegap
      • Hathora
        • Getting Started with Hathora
      • Amazon Web Services (AWS)
        • Getting Started with AWS
    • Upgrading To Fish-Networking
    • Troubleshooting
      • Technical Limitations
      • Creating Bug Reports
        • Report Example
      • FAQ
  • FishNet Building Blocks
    • Components
      • Managers
        • NetworkManager
        • TimeManager
        • PredictionManager
        • ServerManager
        • ClientManager
        • SceneManager
        • TransportManager
          • IntermediateLayer
        • StatisticsManager
        • ObserverManager
          • HashGrid
        • RollbackManager (Pro Feature)
      • Prediction
        • Network Collider
          • NetworkCollision
          • NetworkCollision2D
          • NetworkTrigger
          • NetworkTrigger2D
        • OfflineRigidbody
        • PredictedOwner
        • PredictedSpawn
      • Utilities
        • PingDisplay
        • BandwidthDisplay
        • Tick Smoothers
          • NetworkTickSmoother
          • OfflineTickSmoother
          • MonoTickSmoother [Obsolete]
          • DetachableNetworkTickSmoother [Obsolete]
      • PlayerSpawner
      • DefaultScene
      • ServerSpawner
      • Authenticator
      • ColliderRollback
      • NetworkAnimator
      • NetworkBehaviour
      • NetworkTransform
      • NetworkObject
      • NetworkObserver
    • Prefabs
      • NetworkManager
      • NetworkHudCanvas
    • ScriptableObjects
      • ObserverConditions
        • DistanceCondition
        • GridCondition
        • HostOnlyCondition
        • MatchCondition
        • OwnerOnlyCondition
        • SceneCondition
      • SpawnablePrefabs
        • DefaultPrefabObjects
        • SinglePrefabObjects
        • DualPrefabObjects
      • LevelLoggingConfiguration
    • Transports
      • Tugboat
      • Multipass
      • Yak (Pro Feature)
      • Bayou
      • FishyWebRTC
      • FishyUnityTransport
      • FishySteamworks (Steam)
      • FishyEOS (Epic Online Services)
      • FishyFacepunch (Steam)
      • FishyRealtime (Photon)
  • API Documentation
    • API Reference
Powered by GitBook
On this page
  1. Guides
  2. Getting Started

Moving Your Player Around

Get your player objects moving around and synchronized!

PreviousPreparing Your PlayerNextSpawning and Despawning Items

Last updated 1 day ago

Now that your player object is properly spawned and prepared, it's time to get it moving. In this section, we'll implement a simple client-authoritative movement script and utilize FishNet's component to effortlessly synchronize that movement across all connected devices.

Client-Authoritative Movement Script

For many games, particularly those with real-time player input, client-authoritative movement is the most straightforward approach. This means the client directly controls its own player object and then informs the server (and other clients) about its position and rotation.

Client-authoritative movement makes it easier for the client to cheat with speed hacks, teleportation, and other movement related hacks, but it is a lot easier to implement and understand.

1

Creating a Player Movement Script

Select your Player prefab in the Project window. In the Inspector, click on Add Component and search for New Script. Name the script PlayerMovement and click Create and Add.

2

Editing the Script

Double-click the PlayerMovement script to open it in your code editor. Replace the default code with the following:

Unlike typical single-player scripts that use MonoBehaviour, this script inherits from NetworkBehaviour. This allows for direct access to the IsOwner field. Although you could still check ownership via the component on a MonoBehaviour, provides significant advantages. It enables , , and (akin to Unity's Start, Awake, and OnDestroy but for networked objects).

PlayerMovement.cs
using FishNet.Object;
using UnityEngine;

// Inherit from NetworkBehaviour instead of MonoBehaviour
public class PlayerMovement : NetworkBehaviour
{
    public float moveSpeed = 5f;

    void Update()
    {
        // Only run this code on the object the local client owns.
        // This prevents us from moving other players' objects.
        if (!IsOwner)
            return;

        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        Vector3 moveDirection = new Vector3(horizontal, 0f, vertical);
        if (moveDirection.magnitude > 1f)
            moveDirection.Normalize();

        transform.position += moveSpeed * Time.deltaTime * moveDirection;
    }
}

Since there will be multiple player game objects in the game, we need to determine which one is "our" local player's one and only move that with our input. The IsOwner guard clause handles this.

PlayerMovement.cs
using FishNet.Object;
using UnityEngine;
using UnityEngine.InputSystem;

// Inherit from NetworkBehaviour instead of MonoBehaviour
public class PlayerMovement : NetworkBehaviour
{
    public float moveSpeed = 5f;
    private Vector2 currentMovementInput;

    public override void OnStartClient()
    {
        if (IsOwner)
            GetComponent<PlayerInput>().enabled = true;
    }

    public void OnMove(InputValue value)
    {
        currentMovementInput = value.Get<Vector2>();
    }

    void Update()
    {
        // Only run this code on the object the local client owns.
        // This prevents us from moving other players' objects.
        if (!IsOwner)
            return;

        Vector3 moveDirection = new Vector3(currentMovementInput.x, 0f, currentMovementInput.y);
        if (moveDirection.magnitude > 1f)
            moveDirection.Normalize();

        transform.position += moveSpeed * Time.deltaTime * moveDirection;
    }
}

Since there will be multiple player game objects in the game, we need to determine which one is "our" local player's one and only move that with our input. The IsOwner guard clause in Update handles this. We are also using the NetworkBehaviour OnStartClient callback to enable the PlayerInput component when IsOwner is true. This method runs when the network object is initialized on the network and only on the client side. It's similar to Unity's Start callback and is used here to only send the input to our local player object.

3

Synchronizing the Movement

Now we have code that will allow clients to move only their respective player object, but nothing is yet synchronized over the network This means that we won't ever see other players moving, and they won't see us moving.

To fix this, we will use Fish-Networking's built-in component. This component can be used to synchronize a network object's scale, rotation, position, and parent hierarchy.

Open your Player Prefab and add the NetworkTransform component to it.

This component has quite a few settings, but the most important ones for us right now are the Client Authoritative and the Synchronize Position fields. Both of these should be enabled, which will mean positional changes made by the owner client will automatically be synchronized to the server and then to all other clients.

4

Test Player Movement

Save your scene and press the Play button in Unity's Editor. Your player capsule should now be visible. Use the W, A, S, D keys or arrow keys to move your player around the scene.

To test multi-player movement, you can build and run the game, which will automatically connect as a client to the editor. You should then be able to control your player in the editor, and the second instance will control its own player, seeing both players move independently.

Download the project files with these completed steps here, or explore the repository:

Source Files Repository

If using , you should add the Player Input component to your Player Prefab and be sure to disable it

Unlike typical single-player scripts that use MonoBehaviour, this script inherits from NetworkBehaviour. This allows for direct access to the IsOwner field. Although you could still check ownership via the component on a MonoBehaviour, provides significant advantages. It enables , , and (akin to Unity's Start, Awake, and OnDestroy but for networked objects).

Unity's New Input System
NetworkTransform
NetworkObject
NetworkBehaviour
RPCs
SyncVars
NetworkTransform
NetworkObject
NetworkBehaviour
RPCs
SyncVars
specialized override methods
specialized override methods
Creating the PlayerMovement script
The default settings of the NetworkTransform.
The PlayerInput component added to the Player Prefab and Disabled
An image showing the Player prefab in the Unity Inspector and creating a new script component called "PlayerMovement".
A picture of the NetworkTransform component with its default settings.