Smooth Sync: Sync your Transforms Smoothly across the network

@TacoShank
They will not collide like normal physics if they are owned by two separate systems, but it will not desynchronize.

Like if one car is sitting still and another hits it, the car sitting still will not fly across the road as if the two cars are owned by the same system. The sitting still car may even still be sitting still or may be hit but more lightly. I basically don’t handle situations like that specifically, it’s just what happens when the position is determined by separate owners. The moving car may not collide on the sitting car’s system because in order to collide, it would have to go into a position the sitting still car is, which the sitting still car’s position is only determined by the sitting car’s owner and it won’t move until the moving car goes into a position the sitting car is. Gets kind of confusing to think about and even more to talk about.

Let me know if you have more questions about it. Sending over an RPC yourself on collision and AddForce() is probably the best way to handle separate owner collisions with SmoothSync.

The plugin does not do anything with the replication graph or the steam online subsystems. It’ll take into account Net Cull Distance Squared though. I didn’t even know the replication graph existed, thanks for letting me know about it. I’ll have to look into that, but it won’t be any time soon.

Hello,
does your plugin works on ios devices?

@IronSuit
Yes. I just noticed that the Marketplace page doesn’t reflect this. Thanks for letting me know!

Hello @**. **Does your plugin replicates position, rotation etc. by using property replication or using RPC calls?

@fanaticguy
RPC calls, but we do try to save on bandwidth as much as possible if that’s your worry. It won’t send position when at positional rest and it does the same with rotation, scale, velocity, and angular velocity. It also takes into account NetCullDistanceSquared.

Let me know if you have any more questions.

@** **
Out of programmer curiosity. Can I know why didn’t you used replicated properties? Anyway good work, I will buy your plugin.

@fanaticguy
Using only replicated properties wouldn’t allow client determined transforms if I remember correctly.

Hi , sorry to bother you again.
Since the prototype is now more or less finished I’m currently at rewriting everything in C++, in Editor it works finde, but as soon as I package the game (cooked) I get these errors related to SmoothSync:


Running AutomationTool...
Parsing command line: -ScriptsForProject="C:/Users/Patrick/Documents/Unreal Projects/MyProject/MyProject.uproject" BuildCookRun -project="C:/Users/Patrick/Documents/Unreal Projects/MyProject/MyProject.uproject" -noP4 -clientconfig=Development -serverconfig=Development -nocompile -nocompileeditor -installed -ue4exe=UE4Editor-Cmd.exe -utf8output -platform=Android_ASTC -targetplatform=Android -cookflavor=ASTC -build -cook -map= -unversionedcookedcontent -compressed -stage -deploy -cmdline=" -Messaging" -device=Android_ASTC@041604ad57cf0202 -addcmdline="-SessionId=1AD3B30A4D7996C0A2CD0FB0D1694D2D -SessionOwner='Patrick' -SessionName='SM_G920F (041604ad57cf0202)'  " -run
Setting up ProjectParams for C:\Users\Patrick\Documents\Unreal Projects\MyProject\MyProject.uproject
********** BUILD COMMAND STARTED **********
Running: C:\Program Files\Epic Games\UE_4.21\Engine\Binaries\DotNET\UnrealBuildTool.exe MyProject Android Development -Project="C:\Users\Patrick\Documents\Unreal Projects\MyProject\MyProject.uproject"  "C:\Users\Patrick\Documents\Unreal Projects\MyProject\MyProject.uproject" -NoUBTMakefiles  -remoteini="C:\Users\Patrick\Documents\Unreal Projects\MyProject" -skipdeploy -Manifest="C:\Users\Patrick\Documents\Unreal Projects\MyProject\Intermediate\Build\Manifest.xml" -NoHotReload -log="C:\Users\Patrick\AppData\Roaming\Unreal Engine\AutomationTool\Logs\C+Program+Files+Epic+Games+UE_4.21\UBT-MyProject-Android-Development.txt"
  PLATFORM_ANDROID_NDK_VERSION = 140200
  NDK toolchain: r14b, NDK version: 23, GccVersion: 4.9, ClangVersion: 3.8.275480
  Compiling Native code with NDK API 'android-23'
  Writing manifest to C:\Users\Patrick\Documents\Unreal Projects\MyProject\Intermediate\Build\Manifest.xml
  Building 1 action with 16 processes...
    [1/1] MyProject-arm64-es2.so
    C:/NVPACK/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/lib/gcc/aarch64-linux-android/4.9.x/../../../../aarch64-linux-android/bin\ld: error in C:/Program Files/Epic Games/UE_4.21/Engine/Source/ThirdParty/GooglePlay/gpg-cpp-sdk.v2.3/gpg-cpp-sdk/android/lib/gnustl/arm64-v8a\libgpg.a(.eh_frame); no .eh_frame_hdr table will be created.
    C:/NVPACK/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/lib/gcc/aarch64-linux-android/4.9.x/../../../../aarch64-linux-android/bin\ld: error in C:/Program Files/Epic Games/UE_4.21/Engine/Source/ThirdParty/GooglePlay/gpg-cpp-sdk.v2.3/gpg-cpp-sdk/android/lib/gnustl/arm64-v8a\libgpg.a(.eh_frame); no .eh_frame_hdr table will be created.
    C:/Users/Patrick/Documents/Unreal Projects/MyProject/Intermediate/Build/Android/UE4/Development/MyProject/HoveringVehicle.cppa8.o: In function `USmoothSync::StaticClass()':
    C:/Program Files/Epic Games/UE_4.21/Engine/Plugins/Marketplace/SmoothSync/Source/SmoothSyncPlugin/Public/SmoothSync.h:38: undefined reference to `USmoothSync::GetPrivateStaticClass()'
    C:/Users/Patrick/Documents/Unreal Projects/MyProject/Intermediate/Build/Android/UE4/Development/MyProject/HoveringVehicle.gen.cppa8.o:(.data.rel.ro+0x588): undefined reference to `Z_Construct_UClass_USmoothSync_NoRegister()'
    clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
  ERROR: UBT ERROR: Failed to produce item: C:\Users\Patrick\Documents\Unreal Projects\MyProject\Binaries\Android\MyProject-arm64-es2.so
         (see C:\Users\Patrick\AppData\Roaming\Unreal Engine\AutomationTool\Logs\C+Program+Files+Epic+Games+UE_4.21\UBT-MyProject-Android-Development.txt for full exception trace)
  Total build time: 17,68 seconds (Parallel executor: 0,00 seconds)
Took 17,9194746s to run UnrealBuildTool.exe, ExitCode=5
ERROR: UnrealBuildTool failed. See log for more details. (C:\Users\Patrick\AppData\Roaming\Unreal Engine\AutomationTool\Logs\C+Program+Files+Epic+Games+UE_4.21\UBT-MyProject-Android-Development.txt)
       (see C:\Users\Patrick\AppData\Roaming\Unreal Engine\AutomationTool\Logs\C+Program+Files+Epic+Games+UE_4.21\Log.txt for full exception trace)
AutomationTool exiting with ExitCode=5 (5)
BUILD FAILED


entry in the header:



    UPROPERTY(VisibleDefaultsOnly, BlueprintReadWrite)
    class USmoothSync* SmoothSync;


and in the cpp file:



    // Add SmoothSync and set Networking defaults
    SmoothSync = CreateDefaultSubobject<USmoothSync>(TEXT("SmoothSync"));
    bReplicates = true;
    bReplicateMovement = false;


and I added it in the build.cs



using UnrealBuildTool;

public class MyProject : ModuleRules
{
    public MyProject(ReadOnlyTargetRules Target) : base(Target)
    {
        PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

        PublicDependencyModuleNames.AddRange(new string] { "Core", "CoreUObject", "Engine", "InputCore", "SmoothSyncPlugin" });

        PrivateDependencyModuleNames.AddRange(new string] {  });

        // Uncomment if you are using Slate UI
        // PrivateDependencyModuleNames.AddRange(new string] { "Slate", "SlateCore" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");

        // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
    }
}




Edit:
I copied the SmoothSync folder from the engine’s plugin folder (…/Plugins/Marketplace/) into the projects plugin folder, and now it compiles fine. (Development and Shipping)

But the mixed (c++ & bp) prototyping project did package without the need to do that. I wonder why it worked there and not in the pure c++ project, do you have any clue?

@pDunkl
I’m glad it worked by copying it to your project’s plugin folder because I can’t find anything related to the issue. You’ll just have to go with copying it over for now. I’ll take another look at it later and let you know if I find anything. Let me know if you run into anything else.

@

Hello again, i encountered another problem. the component i have is a Skeletal Mesh Component which has “AnimationBlueprint” assigned to it and “component replicates” checked. the problem is that animations in “Animation state machine” in my “AnimationBlueprint” won’t replicate for the component. all other anims are replicating fine. for example I’m using a float value to get the speed of our character and feeding it to a “BlendSpace” so then the walking animations plays accordingly based on that value for my component and That’s without syncing the scene component and with it synced my component just rotates around it’s self without moving. but my main mesh able to walk around smoothly. so the only problem is the animations not playing because they can’t get their value over network.

could you help me out please, is there any fix or workaround?

EDIT :
found the exact problem, unchecking “Replicate Movement” causes the “Movement Component” to not update its values, like “Velocity”. my component uses that to calculate its speed and play walking animations accordingly. that would be great if smooth sync store some of the important values like “Velocity” from “Movement Component” so i could access it from there. please let me know if it’s possible, thanks.
Also i was wrong about “Animation state machine won’t replicate”, what ever that relies on “Movement Component” values not replicated for my component.

@ATHIEK
If you only need Velocity, I believe the easiest way would be to pass it over as scale since then it won’t matter if you are syncing anything else and scale is probably not being used by you.

Change getScale() to instead get your Movement Component’s velocity. Then comment out the one setScale() call (and that whole section really). Then it will be received as scale in SmoothSync. You can get the targetState’s scale at the end of interpolate() as the currently used State so that the movement lines up with your exact Movement Component velocity.

I’m unfamiliar with movement components, but they don’t have primitive components right? If you need more than velocity, let me know what you’d need and I can take a look at highjacking velocity and angular velocity to being something else when not having primitive components and having a movement component probably.

Let me know if I misinterpreted the issue too, I just got off work so my brain is a bit fried.

@
That worked perfectly thank you, fantastic support too.
I did as you said, i made a new variable


FVector SmoothVelocity;

to store the velocity in plugin’s header file also made that


BlueprintReadOnly

, changed getScale() and setScale then got the velocity at the end of interpolate() using


SmoothVelocity = targetState->scale;

Thanks a lot, it would be nice if the plugin has a separate method for getting velocity in feature versions.
I need one more value from movement component : IsCrouching. it’s a bool where could i get it? possibly the same way?

@ATHIEK
Hmm, I didn’t realize taking off Replicate Movement would cause Movement Component variables to not sync. I’ll have to think some things over and see what I can do and get back to you.

Here’s a dirty fix if you don’t want to wait for me to think of how I want to solve this. This fix won’t send unless position, rotation, velocity, angular velocity, or scale has changed though.
Send over isCrouching in SerializeState() like

copyToBuffer(isCrouching);

Then you read it in ServerSendsTransformToEveryone_Implementation()

bool isCrouching;
readFromBuffer(&(isCrouching));

You have to do them in the same place though so it writes and reads from the buffer correctly. So do them both after the ownerTimestamp part of SerializeState() and ServerSendsTransformToEveryone_Implementation()

A separate dirty fix is sending over isCrouching yourself with the time from UGameplayStatics::GetRealTimeSeconds(GetOwner()->GetWorld()) and timing it up with interpolationTime in InterpolateOrExtrapolate().

Both of those dirty fixes aren’t great so I’ll be back in touch soon after I think about how I want to approach the issue.

@
I Have a few suggestions, maybe there can be an array of key/value (map) and then add whatever variable we want to it and it sync those variables. i think this could work. another approach would be to Implement/Inherent from “Movement Component” and sync it’s variables and methods. as of right now without movement component I’ve taken some alternative way to work without it but encountered some ugly bugs and glitches.

@ATHIEK
Hi, I just wanted to give you an update that I haven’t forgotten about you. I’m still not sure which direction I’ll take but I’ve got some time free over the next few days and I’ll reach out then with hopefully the solution.

Select the SmoothSync Component and under the "Important category, set the checkbox “Set Owner to Server” to true.
Why I can’t find this check box item??

@重庆集佳
Hi, I think I replied to you on youtube already but I wanted to respond here too in case that wasn’t you.

It is no longer needed to have an owner so that variable no longer exists. Smooth Sync now handles non-ownership by having the server control the position.

Where are you seeing
"Select the SmoothSync Component and under the “Important category, set the checkbox “Set Owner to Server” to true.”
?

I thought I had erased that from all docs and videos.

@ATHIEK
OK, I think I’ve finally got a grip on what I’m doing but it’s been rough going in C++ for me and crashing Unreal all the time. It will allow syncing of any variables that you can add. It will also be able to automatically sync all MovementComponent variables and set them on the other side, but you will be able to turn off the ones you don’t need. It’ll also not send this information if it’s not changed so bandwidth should be as low as if replicate movement was checked.

I’m hesitant to provide a timeline but I’m hoping by the end of this weekend or early next week.

@
That is great to hear! with the said new features it’s going to be even more powerful plugin, i appreciate the time you put into it.

@

Hi there. I’ve been using your smoothsync plugin for a little bit, and it’s very nice, but I’ve encountered a problem I’m hoping you can shed some light on.

I have a character that needs to both walk and fly. For walking I’m using the default character movement component, but for flying I’m disabling that and moving the character through physics forces. Running two windows of local multiplayer everything always works great, smoothsync does a perfect job. However when I run the project on two separate computers the smoothsync on the client has serious trouble sending its position and rotations to the server in some situations, namely when the client is a slower computer or in a heavy rendering scene. This is on LAN btw, so latency is not an issue.

If I run both machines using the very lightweight default third person map everything works perfectly all the time. If I have a complex map it works smoothly for about 10 to 30 seconds on the client, and after that the server only sees very jerky updates from the client. They will freeze in place for up to 2 or 3 seconds and only update position on the server after they stop moving entirely. Other RPCs are getting through immediately though, such as animation state changes and object interactions, from the client to server, just none of the movement data provided by smoothsync.

I tested this with a few friends over greater distances last night and everything was fine until one client had their framerate drop just a little from 60. Smoothsync immediately stopped sending their updates for a minute, though it eventually did recover once their fps was back up to normal. The server (not me in the test) also dropped their position data entirely from time to time, resulting in their character just stopping in space, though that also recovered eventually.

I tried removing smoothsync and just going back to the default character movement component for some further tests, and that movement always replicates to the server correctly, no matter how bad the framerate might get. When using smoothsync I have the movement replication of the character movement component disabled as per your instructions.

Do you have any suggestions on how I might get this working better? It seems like Unreal is just putting smoothsync on hold entirely when it gets too busy doing its own stuff.

Thanks very much!