Hello everyone!
I’ve been working on this module for a couple hours to see how much I could get done, and this is the end result.
This module allows you to tween objects on the client, from the server!
Tweening objects on the server is usually a practice that most people do without thinking much about, which is actually pretty bad! Tweening doesn’t have much a lot of strain on the server, but once you begin tweening a lot of objects at once, things get messy.
So, what would the solution be? Let the client handle it!
As some people say, the client can “take a beating” when it comes to performance, unlike the server. This allows you to run some stuff that could usually slow down the server by a bit, but would barely affect the client! Obviously, the client would have some delay when it comes to sending stuff from server to client. I go about this by calculating how long it took, and just adding that to the start value, syncing it as much as possible with the server.
Okay Pyseph, but what about all the other modules that have been released, doing the exact same thing?
Well, the main reason I’ve worked on this is due to the fact that they haven’t been updated for quite a while, and are usually overcomplicated in the source. This module doesn’t have as many functionalities as them (yet ) such as Pause(), Stop() etc, but I plan to add them in the future if you guys really want it. This does support properties like TweenInfo.RepeatCount
, TweenInfo.Reverses
, TweenInfo.DelayTime
etc!
I’ve made this module as easy to use as possible for beginners - if you don’t understand anything or have questions, feel free to ask!
Documentation
*/ StreamTween, by PysephDEV
# Documentation
Module:CreateTween(Object, TweenInformation, TweenData)
# Description
Creates a new StreamTween object.
# Return
StreamTween
StreamTween:PlayAllClients()
# Description
Plays the tween on all clients
StreamTween:PlayClient(Player)
# Description
Plays tween only for specific player
Example script
local StreamTween = require(game:GetService('ServerStorage').StreamTween)
local ExampleTween = StreamTween:CreateTween(workspace.Part, TweenInfo.new(3), {
Size = Vector3.new(10, 10, 10)
})
ExampleTween:PlayAllClients()
Setup
To set this up, you need to add one localscript and a RemoteEvent.
The ModuleScript you can put anywhere, but make sure to set the Remote
ObjectValue inside it to the remote object it’s going to use. The remote has to be accessible by both the client and the server, so make sure it’s not in ServerStorage
for instance, where the client can’t access it.
Both the scripts automatically let you know if you haven’t set them
Once setup, you’re free to go! use the module in any script you want.
Source
ModuleScript
--[[
*/ StreamTween, by PysephDEV
# Documentation
Module:CreateTween(Object, TweenInformation, TweenData)
# Description
Creates a new StreamTween object.
# Return
StreamTween
StreamTween:PlayAllClients()
# Description
Plays the tween on all clients
StreamTween:PlayClient(Player)
# Description
Plays tween only for specific player
]]--
local Network = {}
local StreamTween = {}
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local Players = game:GetService('Players')
local StreamRemote = script.Remote.Value
assert(StreamRemote and StreamRemote.ClassName == 'RemoteEvent', 'No remote has been set for StreamTween! have you made sure to set the Remote ObjectValue to a RemoteEvent?')
StreamTween.__index = StreamTween
function StreamTween:PlayAllClients()
StreamRemote:FireAllClients(os.time(), self.Instance, self.TweenInfo, self.Properties)
end
function StreamTween:PlayClient(Client)
StreamRemote:FireClient(Client, os.time(), self.Instance, self.TweenInfo, self.Properties)
end
function Network:CreateTween(Object, TweenInformation, TweenData)
local Tween = setmetatable({
Instance = Object,
TweenInfo = tostring(TweenInformation),
Properties = TweenData
}, StreamTween)
return Tween
end
return Network
LocalScript
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local TweenService = game:GetService('TweenService')
local RunService = game:GetService('RunService')
local Stepped = RunService.Stepped
function LerpObj(a, b, t)
local Class = type(a)
if a == 'bool' then
return true
elseif a == 'number' then
return a * (1-t) + b * t
elseif a.Lerp then
return a:Lerp(b, t)
end
end
local Order = {
Time = 1,
EasingStyle = 2,
EasingDirection = 3,
RepeatCount = 4,
Reverses = 5,
DelayTime = 6
}
local SerializedCases = setmetatable({
False = false,
True = true
}, {
__index = function(self, key)
return tonumber(key)
end
})
for _, EnumHolder in next, {Enum.EasingStyle, Enum.EasingDirection} do
for _, EnumObj in next, EnumHolder:GetEnumItems() do
SerializedCases[EnumObj.Name] = EnumObj
end
end
function DecodeTween(SerializedInfo)
local Struct = {}
for Name, Idx in next, Order do
local DeserializedVal = SerializedCases[string.match(SerializedInfo, Name .. ':(%S+)')]
Struct[Idx] = DeserializedVal
end
return TweenInfo.new(unpack(Struct))
end
local StreamRemote = script.Remote.Value
assert(StreamRemote and StreamRemote.ClassName == 'RemoteEvent', 'No remote has been set for StreamTween! have you made sure to set the Remote ObjectValue to a RemoteEvent?')
StreamRemote.OnClientEvent:Connect(function(ServerSync, Object, TweenInformation, Properties)
TweenInformation = DecodeTween(TweenInformation)
local Delay = os.time() - ServerSync
local UselessVar
local Time = TweenInformation.Time
local EasingStyle = TweenInformation.EasingStyle
local EasingDir = TweenInformation.EasingDirection
local Alpha = TweenService:GetValue(Delay / Time, EasingStyle, EasingDir)
local StartValues = {}
for PropName in next, Properties do
StartValues[PropName] = Object[PropName]
end
local function TweenObj(InReverse)
Alpha = TweenService:GetValue(Delay / Time, EasingStyle, EasingDir)
for PropName, PropVal in next, Properties do
Object[PropName] = LerpObj(StartValues[PropName], PropVal, Alpha)
end
end
for i = 1 * math.sign(TweenInformation.RepeatCount), TweenInformation.RepeatCount do
while Alpha < 1 do
TweenObj()
local Time, NewDelay = Stepped:Wait()
Delay += NewDelay
end
if TweenInformation.Reverses then
Alpha = 1
while Alpha > 0 do
TweenObj(true)
local Time, NewDelay = Stepped:Wait()
Delay -= NewDelay
end
end
Alpha = 0
if TweenInformation.DelayTime then
wait(TweenInformation.DelayTime)
end
end
end)
ClientTween.rbxl (24.1 KB)