What's the best way to handle CFrame animations on the client & server?

I’ve figure out how to procedural animations with CFrames on the client and all works fine. However, I’m absolutely stumbled on how I should implement this on the server.

Since the CFrame code is client-sided in this particular case, it doesn’t replicate to the server and other players see the model standing still moving. Obviously, this hurts the experience of the game by a lot.

I attempted to use RemoteEvents to specify what the CFrames of the goal parts would be but, it happens way too slow for the game and it looks rather disconcerting.

Here’s an example of what is seen on the server to other players:
https://streamable.com/f2y06

Here’s an example of what it should look like(currently how it is on the client):
https://streamable.com/tr11x

I use an IK method that was mentioned in WhoBloxedWhos tutorial a while back. Also, it might be worth mentioning that I override the character model with my own.

1 Like

If I have understood you correctly, you have tried sending individual CFrames and found this wasn’t the right solution as it was too much data to send in a short period of time. Usually problems like this are solved by firing a Remote Event to tell the server that an animation wants to be played. Once the server verifies this request, it tells the other clients to play the animation, but instead of on their local character, on the player that requested it.
This is usually enough for basic animations, however I see that you are using procedural animations which would suggest that other clients would need more than just an animation ID to update your character. If so then it is a case of minimising the amount of information that needs to be sent and interpolating during the frames where the client is waiting for new information.
I hope this helps somewhat :slight_smile:

2 Likes

This helps a lot. However, if this were to be third-person at all times, how would I do that? I ran into the data issue as you can tell and what you understand is correct. I thought that individual CFrame positions would be short enough to be sent to the server.

1 Like

Not sure what’s wrong with the video but it doesn’t seem to load for me. Can you try reuploading it so we can see what the problem looks like?

1 Like

I encapsulated the link to show the actual URL. For some odd reason, streamable links act weird on here.

2 Likes

How are you using CFrames for animations here? From the video it’s not quite clear what you want it to look like. Can we see a video of how it looks from the client?

The post has been updated to reflect what it shows on the client as a reference to what should be expected. Completely my fault. I meant to post that earlier.

To solve IK using WhoBloxedWho’s method, I have to encapsulate the goal parts CFrame under Runservice.Stepped to allow it to follow the player model correctly. Unfortunately since it’s under a Stepped call, I have to set the goal part’s CFrame as a variable. Looks similar to this:

-- Local Script
local CFrame2 -- Variable that holds the current CFrame that needs to be lerped

-- CFrame2's value is determined by the character's state that's implemented on the client. 
-- In short, the player's current state determines CFrame2's value. 
Runservice.Stepped:Connect(function()
   Character:WaitForChild("Goal1").CFrame = CFrame1.CFrame:Lerp(CFrame2,0.5)
   RemoteEvent:FireServer(player,character,CFrame2) -- fires the same thing as the line above, just on the server
end)

I’d like to note that IK is solved both on the client and on the server. I know that’s it’s bad practice to do animations on both the client and the server but, from a third-person aspect, I see no other alternative.

I would solve all IK on the client, unless the server needs to specifically see what the clients are doing with the animations - and even then I would find another way to notify the server. Essentially it could might be a good idea to try and make your IK work locally on all clients and use the following method to reduce the amount of data being sent:

Usually problems like this are solved by firing a Remote Event to tell the server that an animation wants to be played. Once the server verifies this request, it tells the other clients to play the animation, but instead of on their local character, on the player that requested it.

In other words, each client does their own and everyone else’s animations locally. In your example where you shoot the gun you only need to tell the other clients that you have started a shot. The other clients can then handle the rest from there, ensuring it looks smooth, have relatively low delays as well as minimal network impact.