Is this how I should loop my code?

I’ve recently been trying to make something like a fireball, and today I was successful in doing it. However, my code isn’t looped and its just changing the position once, waiting for a tenth of a second, going again… and so on. Here is my code:

local fireball = script.Parent

fireball.Transparency = 0.5

wait(10)

print("First move")

fireball.Position = Vector3.new(-67, 2, 65)

wait(0.1)

print("Second move")

fireball.Position = Vector3.new(-67, 2, 60)

wait(0.1)

print("Third Move")

fireball.Position = Vector3.new(-67, 2, 40)

I know that if I want to make this work correctly that I would need a loop, so here is what I think I should do for the loop:

local fireball = script.Parent
local increment = 3
local currentPos = [currentPos.X, currentPos.Y, currentPos.Z)
for wait(5), wait(10), 3 do
     fireball.Position = Vector3.new(currentPos[0], currentPos[1], currentPos[2] + increment)
--Did I reference the array positions correctly?
end

However, I don’t know if I put the code correctly in the way I wanted. To explain what’s happening in the for loop, you wait 5 seconds for the fireball to start moving, then you run that for 10 seconds then stop, then the value is 3 because that’s what I want the increment to be. Is this correct??

1 Like

If you want to make this a quick fix, just put all your original code in a loop.

As for your new code:
-line 3: tables are made using { }
-line 4: this will cause an error - take a look at making loop here:
https://developer.roblox.com/en-us/articles/Roblox-Coding-Basics-Loops
-line5: tables in Lua are 1 based, so start at currentPos[1]

2 Likes

Wouldn’t that just make the code run once still though?

No, it will loop if it’s in a loop.

It should be a for loop right? Also, would the wait’s work where they are?

Yes, a for loop would be fine, and the waits would still work.

local fireball = script.Parent

This doesn’t matter too much, but I would keep this declaration before the loop.

I did:
local i = 3

for wait(5), wait(10), i + 3 do

fireball.Position = Vector3.new(-67, 2, i)

end

It didn’t work…

There is a lot better way to move objects smoothly than using these sorts of loops. It is called TweenService. TweenService allows you to create smooth movements with little lag and no stuttering. Here is a little example:

local TweenService = game:GetService("TweenService") -- Gets TweenService
local MovingPart = workspace.MovingPart -- The part you want moved

local tweenInfo = TweenInfo.new(
	10, -- The time it takes for the object to move
	Enum.EasingStyle.Linear, -- How you want the object to move
	Enum.EasingDirection.Out, -- The easing direction
	0, -- How many times you want to tween to play
	false, -- If you want the tween to reverse
	0 -- The delay between each tween
)

local Tween = TweenService:Create(
	MovingPart, -- The part you want to be tweened
	tweenInfo, -- The tweenInfo
	{Position = Vector3.new(13, 0.5, 15)} -- What properties you want to be tweened
)

Tween:Play() -- Plays the tween

In the example above there is a part in workspace that moves from one position to another in 10 seconds. You may be wondering how am I going to implement this in my current code so I will walk you through it.

First we will need to set up our variables as shown below:

local TweenService = game:GetService("TweenService") -- Accesses TweenService
local fireball = script.Parent -- Where the fireball is located
local EndPosition = Vector3.new(-67, 2, 40) -- The end position

Next we will need to set up our TweenInfo

local tweenInfo = TweenInfo.new(
	10, -- The time is takes for the tween to complete
	Enum.EasingStyle.Linear, -- The tween style
	Enum.EasingDirection.Out, -- The easing direction
	0, -- How many times you want it to run
	false, -- If you want it to reverse
	0 -- The delay between each tween
)

lastly we will need to set up out tween as shown below:

local Tween = TweenService:Create(fireball,tweenInfo,{Position = EndPosition})
Tween:Play() -- Use this each time you want the tween to play

Here is the full code:

local TweenService = game:GetService("TweenService")
local fireball = script.Parent
local EndPosition = Vector3.new(-67, 2, 40)

local tweenInfo = TweenInfo.new(
	10,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.Out,
	0,
	false,
	0
)

local Tween = TweenService:Create(fireball,tweenInfo,{Position = EndPosition})
Tween:Play()
3 Likes

Thank you so much! The code above is using a touch of OOP right?

It sort of is because roblox’s API system is set up in an OOP style I believe. Here is a sample of how to set this code up in an OOP style(I am new to OOP so I may be doing a few things wrong, also this scrips will need a lot more work done to it):

ModuleScript

local TweenService = game:GetService("TweenService")

local module = {}
module.__index = module

function module.new(FireBall)
	local self = setmetatable({},module)
	self.FireBall = FireBall
	return self
end

function module:Fire(StartPos, EndPos)
	print("Firing")
	local tweenInfo = TweenInfo.new(
		10,
		Enum.EasingStyle.Linear,
		Enum.EasingDirection.Out,
		0,
		false,
		0
	)
	self.FireBall.Position = StartPos
	local Tween = TweenService:Create(self.FireBall,tweenInfo,{Position = EndPos})
	Tween:Play()
end

return module

Server Script

local FireBallModule = require(script.Parent.FireBallModule)

local FireBall = FireBallModule.new(workspace.fireball)
FireBall:Fire(Vector3.new(0,0,0),Vector3.new(20,20,20))

I made this set up very quickly so it will need a lot of work as I only made this as an example.

1 Like

Why would you put it in a moduleScript… also what is ._index?

This is starting to go a little off topic so I can follow you up in a private message if you would like.

__index is used when you use metatables as it is a metamethod. I will need someone else to explain how to use __index properly as I am new to metatables and OOP. ModuleScripts are used to make your code more organised and readable and they allow you to run the same code in multiple places.