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
1 | while script.equipped.Value = = true do |
2 | orb 1. CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new( 4 , 1 , 0 ) |
3 | orb 2. CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new( 2 , 4 , 0 ) |
4 | orb 3. CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(- 2 , 4 , 0 ) |
5 | orb 4. CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(- 4 , 1 , 0 ) |
6 | wait() |
7 | end |
Here's the entire script
01 | script.orb.OnServerEvent:Connect( function (p) --- "orb" is a remoteEvent triggered when the tool is equipped |
02 | script.equipped.Value = true |
03 | ------------------ orb creation -------------------- |
04 | local orb 1 = Instance.new( "Part" ,workspace) |
05 | orb 1. Shape = "Ball" |
06 | orb 1. Size = Vector 3. new( 1.1 , 1.1 , 1.1 ) |
07 | game.ReplicatedStorage.Particles.MagicThingParticle 1 :Clone().Parent = orb 1 |
08 | game.ReplicatedStorage.Particles.MagicThingParticle 2 :Clone().Parent = orb 1 |
09 | orb 1. CanCollide = false |
10 | orb 1. Anchored = true |
11 | orb 1. Transparency = 1 |
12 | orb 1. Name = "orb1" |
13 | ---------- orb 2 |
14 | local orb 2 = Instance.new( "Part" ,workspace) |
15 | orb 2. Shape = "Ball" |
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.
01 | local orbs = { orb 1 , orb 2 , orb 3 , orb 4 } |
02 | local offsets = { CFrame.new(- 4 , - 1 , 0 ), CFrame.new(- 2 , - 4 , 0 ), CFrame.new( 2 , 4 , 0 ), CFrame.new( 4 , - 1 , 0 ) } |
03 |
04 | for i,v in pairs (orbs) do |
05 | local weld = Instance.new( "Weld" ) |
06 | weld.Part 0 = character.HumanoidRootPart |
07 | weld.Part 1 = v |
08 | weld.C 1 = offsets [ i ] |
09 | weld.Parent = weld.Part 0 |
10 | end |
You could even take it a step further and use the TweenService and have the orbs float around like so...
01 | local orbs = { orb 1 , orb 2 , orb 3 , orb 4 } |
02 | local offsets = { CFrame.new(- 4 , - 1 , 0 ), CFrame.new(- 2 , - 4 , 0 ), CFrame.new( 2 , 4 , 0 ), CFrame.new( 4 , - 1 , 0 ) } |
03 |
04 | for i,v in pairs (orbs) do |
05 | local weld = Instance.new( "Weld" ) |
06 | weld.Part 0 = character.HumanoidRootPart |
07 | weld.Part 1 = v |
08 | weld.C 1 = offsets [ i ] |
09 | weld.Parent = weld.Part 0 |
10 |
11 | spawn( function () -- new thread so there is no yield |
12 | -- Using a TweenService wrapper (but you get the idea) |
13 | while character:FindFirstChild("HumanoidRootPart) do |
14 | local goal = { C 1 = offsets [ i ] + Vector 3. new( 0 , 1.5 , 0 ) |
15 | local properties = { Time = 1 , Reverse = true } |
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
1 | while script.equipped.Value = = true do |
2 | orb 1. CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new( 4 , 1 , 0 ) |
3 | orb 2. CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new( 2 , 4 , 0 ) |
4 | orb 3. CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(- 2 , 4 , 0 ) |
5 | orb 4. CFrame = p.Character.HumanoidRootPart.CFrame * CFrame.new(- 4 , 1 , 0 ) |
6 | game:GetService( "RunService" ).RenderStepped:Wait(); |
7 | 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!