Hello there! I’ve been trying to recreate the game Diep.io in roblox mainly for fun and because an Old Roblox Diep.io broke (due to roblox updates I’m assuming)
I’m currently changing from depreciated BodyPosition to AlignPosition and decided to improve the current movement system I have.
This is the current movement I have
And this is the new movement system I’m working on
I want it to be like the real diep.io movement system
Example of the real movement system
and so far it works by tweening the position value of the Align Position. However my concern is the efficiency of the code below
repeat
if plr ~= nil then
local BasePosWithoutY = Vector3.new(Base.Position.X,SpawnedYValue,Base.Position.Z)
if LastSavedMoveMagnitude == 0 then -- if the player is moving for the first time the speed should be faster
local TweenInformation = TweenInfo.new(1,Enum.EasingStyle.Linear,Enum.EasingDirection.Out)
local TweenGoal = {Position = BasePosWithoutY + (plr.Character.Humanoid.MoveDirection*50)}
local TweenGo = TweenService:Create(BodyP,TweenInformation,TweenGoal)
TweenGo:Play()
else
local TweenInformation = TweenInfo.new(2,Enum.EasingStyle.Linear,Enum.EasingDirection.Out)
local TweenGoal = {Position = BasePosWithoutY + (plr.Character.Humanoid.MoveDirection*50)}
local TweenGo = TweenService:Create(BodyP,TweenInformation,TweenGoal)
TweenGo:Play()
end
task.wait()
end
until CurrentMoveDirection ~= plr.Character.Humanoid.MoveDirection or plr.Character.Humanoid.MoveDirection.Magnitude == 0 or plr == nil
if plr ~= nil then
LastSavedMoveMagnitude = plr.Character.Humanoid.MoveDirection.Magnitude
end
My main concern is that every task.wait() we are stopping the tween and starting a new one which i feel like is not efficient but so far has only been the solution to recreate the movement system.
So is this code fine or is there better ways to do this?
They’re great for smoothing movement like this. The basic idea is you set the goal of the spring to be the position you want to “tween” towards, then you update the spring and set the object position to the springs current position. Using a damping value greater than 1 should give you that nice slow down behavior too.
The code demo is in StarterPlayerScripts: springs demo.rbxl (34.9 KB)
If you wanted to have this smooth “joystick” / directional movement instead of the direct position then you would just have the spring solve for that direction vector instead of the final position goal vector. Apply that solved spring as velocity to your character and you should still get a similar effect.
This is indeed very interesting but unfortunately, I cannot configure it to work the way I want it to. Currently when standing still it causes my tank to infinitely float upwards and it also doesn’t provide the smooth motion as expected
the code below is what i used to test this method
local playersService = game:GetService("Players")
local runService = game:GetService("RunService")
local player = playersService[script.Parent.Name]
local part = script.Parent.Base
local positionSpring = require(script.Springs).new(5, 2, part.Position)
local humanoid = workspace[script.Parent.Name].Humanoid
runService.Heartbeat:Connect(function(dt)
-- set the speed spring to the new mouse position
positionSpring:SetGoal(part.Position + Vector3.new(humanoid.MoveDirection.X,0,humanoid.MoveDirection.Z)*20)
-- update the spring and set the debut part
local pos = positionSpring:Update(dt)
part.CFrame = CFrame.new(pos)
end)
This might be more camera desync than an issue with the springs. Instead of runService.Heartbeat try runService:BindToRenderStep() with the order value being before the camera enum Enum.RenderPriority.Camera.Value - 1
If it’s still choppy after that then it might be an issue elsewhere.
For the floating issue you can just clamp the Y height of the spring goal you’re setting. If you needed something a little more dynamic for height finding you could always raycast to find it too.
local HEIGHT = 5
-- in the loop
local origin = Vector3.new(part.Position.X, HEIGHT, part.Position.Z)
local offset = humanoid.MoveDirection * Vector3.new(20, 0, 20)
positionSpring:SetGoal(origin + offset)
local playersService = game:GetService("Players")
local runService = game:GetService("RunService")
local player = playersService[script.Parent.Name]
local part = script.Parent.Base
local height = part.Position.Y
local positionSpring = require(script.Springs).new(5, 2, part.Position)
local humanoid = workspace[script.Parent.Name].Humanoid
function spring()
--
local origin = Vector3.new(part.Position.X,height,part.Position.Z)
local offset = humanoid.MoveDirection * Vector3.new(20,0,20)
--
--
-- set the speed spring to the new mouse position
positionSpring:SetGoal(origin + offset)
-- update the spring and set the debut part
local pos = positionSpring:Update()
part.CFrame = CFrame.new(pos)
end
runService:BindToRenderStep("spring",Enum.RenderPriority.Camera.Value - 1)