LogoLogo
  • SWNetwork SDK Overview
  • Installation
    • Custom Unity Package
  • Tutorials
    • Third-Person Shooter
      • Starter Project Introduction
      • Install SWNetwork
      • Setting up the NetworkClient
      • Sync Player Transform
      • Setting up the Scene Spawner
      • Test and Play
      • Remote Events
      • SyncProperties
      • Player Respawn
      • Updating Room States
      • Winning the Game
    • Basic Lobby
      • Lobby-start
      • Installing SWNetwork SDK and configuring NetworkClient
      • Registering Player
      • Room CRUD
      • Managing Teams
      • Chat
  • SDK
    • Network Client
      • Check-in
      • Game Servers
      • Network Status Event (beta)
      • Classes
        • NetworkClient Class
      • Methods
        • CheckIn() Method
        • ConnectToRoom(Action<bool>) Method
        • DisconnectFromRoom () Method
        • FindSpawner(ushort) Method
    • Game Play
      • Network ID
      • Realtime Agent
      • Remote Event
      • Sync Property
        • Restore Sync Properties
        • Conflict Resolution
      • SceneSpawner
      • RoomPropertyAgent
      • RoomRemoteEventAgent
    • Lobby
      • Register Player
      • Message Player
      • Create Room
      • Change Room Settings
      • Get Rooms
      • Filter Rooms
      • Join Room
      • Message Room
      • Get Players in Room
      • Get Room Custom Data
      • Change Room Custom Data
      • Kick Players
      • Start Room
      • Leave Room
      • Lobby Room Events
        • OnLobbyConnectedEvent
        • OnPlayerMessageEvent
        • OnRoomCustomDataChangeEvent
        • OnNewPlayerJoinRoomEvent
        • OnPlayerLeaveRoomEvent
        • OnNewRoomOwnerEvent
        • OnRoomStartingEvent
        • OnRoomReadyEvent
        • OnFailedToStartRoomEvent
        • OnKickedEvent
        • OnRoomMessageEvent
      • Classes
        • SWLobby Class
        • SWPlayer Class
        • SWRoom Class
        • SWRegisterReply Class
        • SWGetRoomReply Class
        • SWJoinRoomReply Class
        • SWGetRoomCustomDataReply Class
        • SWGetPlayersReply Class
        • SWLobbyIndexData Class
        • SWLobbyFilterData Class
        • SWGetRoomFilterReply Class
        • SWLobbyError Class
        • SWMessagePlayerEventData Class
        • SWMessageRoomEventData Class
        • SWRoomCustomDataChangeEventData Class
        • SWJoinRoomEventData Class
        • SWLeaveRoomEventData Class
        • SWRoomChangeOwnerEventData Class
        • SWStartRoomEventData Class
        • SWRoomReadyEventData Class
        • SWFailedToStartRoomEventData Class
      • Methods
        • Register(Action<bool, SWRegisterReply, SWLobbyError>) Method
        • MessagePlayer(string, string, Action<bool, SWLobbyError>) Method
        • CreateRoom(bool, int, Action<bool, string, SWLobbyError>) Method
        • ChangeRoomSettings(int, int, Action<bool, SWLobbyError>) Method
        • GetRooms(int, int, Action<bool, SWGetRoomReply, SWLobbyError>) Method
        • FilterRoom(SWLobbyFilterData, byte, Action<bool, SWGetRoomFilterReply, SWLobbyError>) Method
        • JoinRoom(string, Action<bool, SWJoinRoomReply, SWLobbyError>) Method
        • JoinRoomRandomly(Action<bool, SWJoinRoomReply, SWLobbyError>) Method
        • JoinOrCreateRoom(bool, int, int, Action<bool, SWJoinRoomReply, SWLobbyError>) Method
        • MessageRoom(string, Action<bool, SWLobbyError>) Method
        • GetRoomCustomData(Action<bool, SWGetRoomCustomDataReply, SWLobbyError>) Method
        • GetPlayersInRoom(Action<bool, SWGetPlayersReply, SWLobbyError>) Method
        • ChangeRoomCustomData(string, Action<bool, SWLobbyError>) Method
        • StartRoom(Action<bool, SWLobbyError>) Method
        • LeaveRoom(Action<bool, SWLobbyError>) Method
  • Open Source Software Used
    • Credits
Powered by GitBook
On this page
  • RealTime Agent
  • Transform
  • Rotation
  • Updating the PlayerMovement.cs script
  • Updating the PlayerWeapon.cs script

Was this helpful?

  1. Tutorials
  2. Third-Person Shooter

Sync Player Transform

3 - 5 minutes read

PreviousSetting up the NetworkClientNextSetting up the Scene Spawner

Last updated 6 years ago

Was this helpful?

RealTime Agent

Open the game scene, select the Player GameObject in the Hierarchy.

Click the Add Component button and Search "Agent", select Realtime Agent to attach it to the Player GameObject.

You will see that a Network ID component was attached to Player GameObject automatically. Network ID component helps SWNetwork to identify a GameObject. Set its Type to "Player" as the GameObject will be controlled by the player.

Transform

The RealTime Agent send GameObject's position, rotation updates to its remote duplicates.

The Player GameObject moves in X, Y, Z directions, we need to enable all of them.

The Min, Max, and Resolution settings are used to compress the X, Y, Z values.

In this game, the player moves between -20 to 20 in the X-axis, 0 to 3 in the Y-axis, and -20 to 20 in the Z-axis. You can use these limits to set the compression settings.

Rotation

The Player GameObject rotates around the Y-axis. We should enable Y for Rotation. We can set the resolution to Ten as we do not need high precision for rotation. The Y rotation value that remote duplicates receive will be like: 0, 10, 20 ... 360.

Interpolate field controls the interpolation of rotation and scale updates. The larger the number the faster the GameObject interpolates to the target rotation and scale.

Smooth Level field controls the smoothness of position updates. The larger the number the smoother the GameObject moves to the target position. However, a larger smooth level will affect the GameObjects responsiveness.

Read Function field controls in which function the remote duplicates will read the position updates.

You can use the settings in the below screenshot to config the RealTime Agent.

Updating the PlayerMovement.cs script

You need to update the PlayerMovement.cs script so that only the source Player GameObject receives user inputs. Use the IsMine property of NetworkID to find out if the Player GameObject is the source GameObject.

Also, set the camera to follow the source Player GameObject.

The PlayerMovement.cs script should look like.

using UnityEngine;
using SWNetwork;

/// <summary>
/// Player movement.
/// </summary>
public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed = 6.0F;
    public float gravity = -15f;
    private float verticalVelocity;
    public float jumpForce = 7.0f;

    private CharacterController characterController;

    NetworkID networkId;

    void Start()
    {
        characterController = GetComponent<CharacterController>();
        networkId = GetComponent<NetworkID>();

        if (networkId.IsMine)
        {
            // set CameraFollow target
            Camera m_MainCamera = Camera.main;
            CameraFollow cameraFollow = m_MainCamera.GetComponent<CameraFollow>();
            cameraFollow.target = gameObject;
        }
    }

    void Update()
    {
        if (networkId.IsMine)
        {
            // get keyboard inputs
            float speedX = Input.GetAxis("Horizontal") * moveSpeed;
            float speedZ = Input.GetAxis("Vertical") * moveSpeed;

            if (characterController.isGrounded)
            {
                verticalVelocity = gravity;
                if (Input.GetKeyDown(KeyCode.Space))
                {
                    Jump();
                }
            }
            else
            {
                verticalVelocity += gravity * Time.deltaTime;
            }

            Vector3 movement = new Vector3(speedX, verticalVelocity, speedZ);
            characterController.Move(movement * Time.deltaTime);
        }
    }

    public void Jump()
    {
        verticalVelocity = jumpForce;
    }
}

Updating the PlayerWeapon.cs script

Make sure only the source Player GameObject receives mouse movement as well.

The PlayerWeapon.cs script should look like.

using UnityEngine;
using SWNetwork;

public class PlayerWeapon : MonoBehaviour
{
    // aimable layers
    public LayerMask layerMask;

    private Vector3 currentLookTarget = Vector3.zero;
    public Gun gun;

    // launch position of bulletes
    public Transform launchPosition;

    NetworkID networkId;

    private void Start()
    {
        networkId = GetComponent<NetworkID>();
    }

    void FixedUpdate()
    {
        if (networkId.IsMine)
        {
            // find player's cursor position in the environment
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            Debug.DrawRay(ray.origin, ray.direction * 1000, Color.green);
            if (Physics.Raycast(ray, out hit, 1000, layerMask, QueryTriggerInteraction.Ignore))
            {
                if (hit.point != currentLookTarget)
                {
                    currentLookTarget = hit.point;
                }
            }

            // ignore cursor position's y value.
            Vector3 targetPosition = new Vector3(hit.point.x, transform.position.y, hit.point.z);

            // calculate player's new rotation
            Quaternion rotation = Quaternion.LookRotation(targetPosition - transform.position);

            // lerp
            transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * 10.0f);
        }
    }

    void Update()
    {
        // get mouse inputs
        if (Input.GetMouseButtonDown(0))
        {
            // 0.5 seconds interval between shots
            if (!IsInvoking("FireBullet"))
            {
                InvokeRepeating("FireBullet", 0f, 0.5f);
            }
        }

        if (Input.GetMouseButtonUp(0))
        {
            CancelInvoke("FireBullet");
        }
    }

    void FireBullet()
    {
        gun.FireBullet(launchPosition.position, transform.forward);
    }
}