Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How to make floating orbs follow you without a delay?

I am trying to make a tool that makes 4 floating orbs appear around you when you equip it. These orbs are supposed to follow you at the same speed as your walk speed, but there seems to be a delay and when they follow you.

Here's the part of the script that makes the orb follow you

	while script.equipped.Value == true do
		orb1.CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(4,1,0)
		orb2.CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(2,4,0)
		orb3.CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(-2,4,0)
		orb4.CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(-4,1,0)
		wait()
	end

Here's the entire script

script.orb.OnServerEvent:Connect(function(p) --- "orb" is a remoteEvent triggered when the tool is equipped
	script.equipped.Value = true
------------------ orb creation --------------------
	local orb1 = Instance.new("Part",workspace)
	orb1.Shape = "Ball"
	orb1.Size = Vector3.new(1.1, 1.1, 1.1)
	game.ReplicatedStorage.Particles.MagicThingParticle1:Clone().Parent = orb1
	game.ReplicatedStorage.Particles.MagicThingParticle2:Clone().Parent = orb1
	orb1.CanCollide = false
	orb1.Anchored = true
	orb1.Transparency = 1
	orb1.Name = "orb1"
	---------- orb 2
	local orb2 = Instance.new("Part",workspace)
	orb2.Shape = "Ball"
	orb2.Size = Vector3.new(1.1, 1.1, 1.1)
	game.ReplicatedStorage.Particles.MagicThingParticle1:Clone().Parent = orb2
	game.ReplicatedStorage.Particles.MagicThingParticle2:Clone().Parent = orb2
	orb2.CanCollide = false
	orb2.Anchored = true
	orb2.Transparency = 1
	orb2.Name = "orb2"
	---------- orb 3
	local orb3 = Instance.new("Part",workspace)
	orb3.Shape = "Ball"
	orb3.Size = Vector3.new(1.1, 1.1, 1.1)
	game.ReplicatedStorage.Particles.MagicThingParticle1:Clone().Parent = orb3
	game.ReplicatedStorage.Particles.MagicThingParticle2:Clone().Parent = orb3
	orb3.CanCollide = false
	orb3.Anchored = true
	orb3.Transparency = 1
	orb3.Name = "orb3"
	----------- orb 4
	local orb4 = Instance.new("Part",workspace)
	orb4.Shape = "Ball"
	orb4.Size = Vector3.new(1.1, 1.1, 1.1)
	game.ReplicatedStorage.Particles.MagicThingParticle1:Clone().Parent = orb4
	game.ReplicatedStorage.Particles.MagicThingParticle2:Clone().Parent = orb4
	orb4.CanCollide = false
	orb4.Anchored = true
	orb4.Transparency = 1
	orb4.Name = "orb4"
	
------ this is irrelevant
	local tags = Instance.new("StringValue",orb1)
	tags.Name = "tag"
	tags.Value = p.Character.Name
	local tags = Instance.new("StringValue",orb2)
	tags.Name = "tag"
	tags.Value = p.Character.Name
	local tags = Instance.new("StringValue",orb3)
	tags.Name = "tag"
	tags.Value = p.Character.Name
	local tags = Instance.new("StringValue",orb4)
	tags.Name = "tag"
	tags.Value = p.Character.Name
	
------------- this is the part that makes the orbs follow you
	while script.equipped.Value == true do
		orb1.CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(4,1,0)
		orb2.CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(2,4,0)
		orb3.CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(-2,4,0)
		orb4.CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(-4,1,0)
		wait()
	end
end)

1 comment

1

you could just weld the orb to the player

2 answers

✓ Accepted answer

Another method that does not involve any sort of loops to keep the orbs in position would be to use Welds. You could take your orbs and weld them to the character's HumanoidRootPart (or any other part you want them attached to). Then use the weld's C1 property (Part1 offset) to offset the orbs to whatever position you want around the character.

local orbs = {orb1, orb2, orb3, orb4}
local offsets = {CFrame.new(-4, -1, 0), CFrame.new(-2, -4, 0), CFrame.new(2, 4, 0), CFrame.new(4, -1, 0)}

for i,v in pairs(orbs) do
	local weld = Instance.new("Weld")
	weld.Part0 = character.HumanoidRootPart
	weld.Part1 = v
	weld.C1 = offsets[i]
	weld.Parent = weld.Part0
end

You could even take it a step further and use the TweenService and have the orbs float around like so...

local orbs = {orb1, orb2, orb3, orb4}
local offsets = {CFrame.new(-4, -1, 0), CFrame.new(-2, -4, 0), CFrame.new(2, 4, 0), CFrame.new(4, -1, 0)}

for i,v in pairs(orbs) do
	local weld = Instance.new("Weld")
	weld.Part0 = character.HumanoidRootPart
	weld.Part1 = v
	weld.C1 = offsets[i]
	weld.Parent = weld.Part0

	spawn(function() -- new thread so there is no yield
		-- Using a TweenService wrapper (but you get the idea)
		while character:FindFirstChild("HumanoidRootPart) do
			local goal = {C1 = offsets[i] + Vector3.new(0,1.5,0)
			local properties = {Time = 1, Reverse = true}
			TweenService(weld, goal, properties)
			
			wait(properties.Time * 2) -- x2 for reverse
		end
	end)
end

Just a few things to note:

  • Do not attempt to tween the sizes of the orbs, Roblox currently has an engine issue that will make any object that is welded to the player's character that is being tweened to not replicate the player's position to other players (looks like they are running in place).

  • The orbs must be CanCollide = false, MassLess = true, Anchored = false

This is because you are using wait() which has a minimum value of triggering 30 times a second; far too slow for what you need. What you should use instead is

while script.equipped.Value == true do
    orb1.CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(4,1,0)
    orb2.CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(2,4,0)
    orb3.CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(-2,4,0)
    orb4.CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(-4,1,0)
    game:GetService("RunService").RenderStepped:Wait();
end

This will update every frame, before the frame is rendered, meaning there will be absolutely no delay. This will only work assuming the script is a localscript, which it needs to be, because there is no other way to do this if the script isn't.

If you want the orbs to show for everyone without a delay, then you need to teach yourself about events (https://www.google.com/search?q=events+tutorial+roblox&rlz=1C1CHBF_enUS800US800&oq=events+tutorial+roblox&aqs=chrome..69i57.2092j0j7&sourceid=chrome&ie=UTF-8#kpvalbx=_4GthXvfXHcTi-gSH2L_ACg30). The basic idea for achieving this would be that you use :FireAllClients() to trigger the script above on a localscript for every player.

EDIT: It looks like you already know how events work based on your second script, so this should be totally doable for you if it isn't what you already did.

If you want more info on RenderStepped:Wait() check out (https://developer.roblox.com/en-us/api-reference/event/RunService/RenderStepped) and I also recommend just checking everything out about the RunService, namely how Heartbeat, RenderStepped, and Stepped relate to eachother.

Good luck with your game!

2 comments

1

He could also use networkownership to allow movement of a part by the client. It has to take into account the player could exploit this, so the part should have more aesthetic purposes than a game mechanic purpose, like a projectile.

0

Yup, that's totally another option. I just offered the idea of using events because he seems to have experience with them.

This discussion is preserved as it was. New answers, comments, and votes are closed.