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

Sprites are moving when they shouldn't?

(Yes, I'm making a sprite-based game. Don't ask why.)

local label = script.Parent
local RunService = game:GetService("RunService")
local Debris = game:GetService("Debris")
local length = label:WaitForChild("Length")
local width = label:WaitForChild("Width")
local angle = label:WaitForChild("Angle")
local delaytime = label:WaitForChild("Delay")
local life = label:WaitForChild("Lifetime")
local t = label:WaitForChild("Transparency")

local delayLine = Instance.new("Frame")
delayLine.Parent = label
delayLine.Name = "DelayLine"
delayLine.Size = UDim2.new(0, 1, length.Value, 0)
delayLine.AnchorPoint = Vector2.new(0, 0)
delayLine.BorderSizePixel = 0
delayLine.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
delayLine.BackgroundTransparency = 0.5
delayLine.Position = UDim2.new(0, 0, 0, 0)

local hitbox = Instance.new("Frame")
hitbox.Parent = label
hitbox.AnchorPoint = Vector2.new(0.5, 0.5)
hitbox.Size = UDim2.new(0.33, 0, 1, 0)
hitbox.Position = UDim2.new(0.5, 0, 0.5, 0)
hitbox.BackgroundTransparency = 1

local hitboxScript = game.ReplicatedStorage.BulletScripts:WaitForChild("LinearHitboxScript"):Clone()
hitboxScript.Parent = hitbox
hitboxScript.Disabled = true

delay(delaytime.Value, function()
	label:TweenSize(UDim2.new(0, width.Value, 0, length.Value), "Out", "Quad", 0.25, false, function()
		Debris:AddItem(label, life.Value)
	end)
end)

function getRealAngle(a)
	local val = math.abs(a - 180)
	
	if a > 180 then
		val = val * -1
	end
	
	return val
end

label:GetPropertyChangedSignal("Size"):Connect(function()
	if label.Size == UDim2.new(0, 1, 0, 1) then
		delayLine.Visible = true
		label.ImageTransparency = 1
		hitboxScript.Disabled = true
	else
		delayLine.Visible = false
		label.ImageTransparency = t.Value
		hitboxScript.Disabled = false
	end
end)

RunService.RenderStepped:Connect(function()
	label.Rotation = getRealAngle(angle.Value)
end)

When the sprite is created, its size is set to UDim2.new(0, 1, 0, 1). After a certain amount of time passes, the sprite expands to its true size, determined by the values of Length and Width.

However, when the sprite's size changes, it moves towards the bottom of the screen, even though I don't have anything that changes the position in the script. Is there a way to fix it?

Here's the function that creates these sprites, in case it helps with figuring out the problem:

function lib:CreateStraightLaser(x, y, angle, length, width, delaytime, graphic, timer)
	local RealLaser = getShotData(graphic)
	local BoundBox = RealLaser.Bound
	local sLaserScript = ExtraScriptsDirectory:WaitForChild("StraightLaserScript")
	
	local sLaser = Instance.new("ImageLabel")
	sLaser.Name = RealLaser.Name
	sLaser.Position = UDim2.new(0, x, 0, y)
	sLaser.Size = UDim2.new(0, 1, 0, 1)
	sLaser.AnchorPoint = Vector2.new(0.5, 0)
	sLaser.BackgroundTransparency = 1
	sLaser.Image = ShotSheetImage
	sLaser.ImageRectOffset = BoundBox.Min
	sLaser.ImageRectSize = Vector2.new(BoundBox.Width, BoundBox.Height)
	sLaser.ImageTransparency = 1
	
	local l = Instance.new("NumberValue")
	l.Parent = sLaser
	l.Name = "Length"
	l.Value = length
	
	local a = Instance.new("NumberValue")
	a.Parent = sLaser
	a.Name = "Angle"
	a.Value = angle
	
	local w = Instance.new("NumberValue")
	w.Parent = sLaser
	w.Name = "Width"
	w.Value = width
	
	local d = Instance.new("NumberValue")
	d.Parent = sLaser
	d.Name = "Delay"
	d.Value = delaytime
	
	local life = Instance.new("NumberValue")
	life.Parent = sLaser
	life.Name = "Lifetime"
	life.Value = timer
	
	local t = Instance.new("NumberValue")
	t.Parent = sLaser
	t.Name = "Transparency"
	t.Value = RealLaser.Transparency
	
	local newLaserScript = sLaserScript:Clone()
	newLaserScript.Parent = sLaser
	newLaserScript.Disabled = false
	
	sLaser.Parent = getLocalPlayerGui()
	
	return sLaser
end

1 comment

0

use TweenSizeAndPosition to change the item's size and position simultaneosly. It needs to change position to because it, by default, expands the iterm towards the bottom of the screen.

1 answer

✓ Accepted answer

When you change the size of a GUI object, it by default expands towards the bottom right corner of the screen. Therefore, you not only have to tween the size, but also the position. To do this, I used TweenSizeAndPosition, with another parameter after the endSize being the endPosition. The endPosition I set to the original position minus half of the width and half of the length to "center" it. Let me know if it works!

local label = script.Parent
local RunService = game:GetService("RunService")
local Debris = game:GetService("Debris")
local length = label:WaitForChild("Length")
local width = label:WaitForChild("Width")
local angle = label:WaitForChild("Angle")
local delaytime = label:WaitForChild("Delay")
local life = label:WaitForChild("Lifetime")
local t = label:WaitForChild("Transparency")

local delayLine = Instance.new("Frame")
delayLine.Parent = label
delayLine.Name = "DelayLine"
delayLine.Size = UDim2.new(0, 1, length.Value, 0)
delayLine.AnchorPoint = Vector2.new(0, 0)
delayLine.BorderSizePixel = 0
delayLine.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
delayLine.BackgroundTransparency = 0.5
delayLine.Position = UDim2.new(0, 0, 0, 0)

local hitbox = Instance.new("Frame")
hitbox.Parent = label
hitbox.AnchorPoint = Vector2.new(0.5, 0.5)
hitbox.Size = UDim2.new(0.33, 0, 1, 0)
hitbox.Position = UDim2.new(0.5, 0, 0.5, 0)
hitbox.BackgroundTransparency = 1

local hitboxScript = game.ReplicatedStorage.BulletScripts:WaitForChild("LinearHitboxScript"):Clone()
hitboxScript.Parent = hitbox
hitboxScript.Disabled = true

delay(delaytime.Value, function()
    label:TweenSizeAndPosition(UDim2.new(0, width.Value, 0, length.Value), label.Position-UDim2.new(0, width.Value *0.5, 0, length.Value * 0.5),  "Out", "Quad", 0.25, false, function()
        Debris:AddItem(label, life.Value)
    end)
end)

function getRealAngle(a)
    local val = math.abs(a - 180)

    if a > 180 then
        val = val * -1
    end

    return val
end

label:GetPropertyChangedSignal("Size"):Connect(function()
    if label.Size == UDim2.new(0, 1, 0, 1) then
        delayLine.Visible = true
        label.ImageTransparency = 1
        hitboxScript.Disabled = true
    else
        delayLine.Visible = false
        label.ImageTransparency = t.Value
        hitboxScript.Disabled = false
    end
end)

RunService.RenderStepped:Connect(function()
    label.Rotation = getRealAngle(angle.Value)
end)

2 comments

0

That prevents it from moving to the bottom of the screen, but now the sprite moves backwards when it resizes, when it's supposed to stay in one place.

0

I tried doing this with a GUI object in Studio and I noticed that my solution works with Scale but not with Offset. Offset is a bit more finnicky so if you want to stick with offset, you'll have to do a lot of tests to figure out what the right endPosition is.

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