For example, my players are Ghost, but I need to use the client’s data for the player’s Position, and the server only needs to transfer it. How to use it?
you can use a specific variant and that can work, if the client has complete full authority over the its position. However, you should pay some attention to rollback and resimulate logic (for both partial and full ticks).
When you receive a new snapshot for player ghost from the server, the client rollback and resimulate that ghost from starting from the received tick up to the current simulated tick (i.e from 100 to 106).
When doing that, the data of the ghost is reset to the “replicated state” at tick 100. This state only contains replicated components and for these, only the replicated fields.
That means, position is never rollback to its past value.
If your simulation logic that calculate the player position MUST not depend on the previous value of this variable, and should be able to calculate the player position from other replicated fields.
If that is not the case (i.e position += velocity * deltaTime) you need to also include the position as part for the state sent by server.
That does not mean the client cannot have control over it. You can still send the position of the player as part for the command, and pretend the client has authority over it. The server will trust the client and use position you passed to set the current value, and this will be resent to all clients, include the one that sent the position as well.
This still allow a correct prediction-correction loop logic.
If you don’t want a component to be replicated to the owner of a ghost, you can also specify this behavior by using the [GhostComponentAttribute(OwnerSendType = SendToOwnerType.SendToNonOwner)] in your component declaration.
Again, this will prevent the component to be restored when new data is received and for partial ticks. The latter is quite important: The component is considered as “non replicated” and as such, the value set by the user are left untouched.
If let’s say I have component X with field Y, usually for partial ticks it works like this (the number in parenthesis is the value at the last full tick)
Tick 100 X.Y = 100
Tick 101.3 X.Y = X.Y(100) + 1= 101
Tick 101.7 X.Y = X.Y(100) + 1= 101
Tick 101[full] X.Y = X.Y(100) + 1= 101
If you set SendToOwnerType.SendToNonOwner
Tick 100 X.Y = 100
Tick 101.3 X.Y = X.Y + 1= 101
Tick 101.7 X.Y = X.Y + 1= 102
Tick 101[full] X.Y = X.Y + 1= 103