What can I do to improve this script?

Have you tried using .TouchEnded instead of a .Magnitude check every frame?

Hitbox.Touched:Connect(function(Human)
	if not Human.Parent:FindFirstChildWhichIsA("Humanoid") or Subject then
		return
	end
	
	--print("Touched")
	Subject = Human.Parent
	NotificationUI.Enabled = true
	
	if script:GetAttribute("enableNotification") then
		NotificationText_In:Play()
	end
	
	ContextActionService:BindAction("OpenBox", handleAction, true, Enum.KeyCode.E, Enum.KeyCode.ButtonR1)
	ContextActionService:SetPosition("OpenBox", UDim2.new(1, -70, 0, 10))
	ContextActionService:SetImage("OpenBox", "rbxassetid://12768386698")
end)
	
Hitbox.TouchEnded:Connect(function(hit)
	if not hit.Parent:FindFirstChildWhichIsA("Humanoid") or not Subject then
		return
	end
	
	EndDebounce = true
	
	if NotificationText_In.PlaybackState == Enum.PlaybackState.Playing then
		NotificationText_In.Completed:Wait()
	end
	
	if script:GetAttribute("enableNotification") then
		NotificationText_Out:Play()
	end
	
	ContextActionService:UnbindAction("OpenBox")
	
	task.wait(0.5)
	NotificationUI.Enabled = false
	EndDebounce = false
	Subject = nil
end)

I have tried .TouchEnded before, it was performing REALLY badly. I remember when we originally made the script and used that, it was incredibly unstable and also wasteful when it came to performance because it kept firing indefinitely.

Overall, I really don’t trust .TouchEnded. Sometimes it malfunctioned (not work at all or was firing constantly)

Ah, don’t mind if you try this?

local player = game.Players.LocalPlayer
local countdown = player.PlayerGui:WaitForChild("InGame").Assets.Countdown
local icon = countdown.Icon
local ui = player.PlayerGui:WaitForChild("Notification")
local ts = game:GetService("TweenService")
local text = ui:WaitForChild("Notification")
local runservice = game:GetService("RunService")
local context = game:GetService("ContextActionService")
local sound = workspace.Sound.SFX.BoxSound
local ticksound = workspace.Sound.UI.TickSound
local EndDebounce = false
local debounce = false
local GlobalUISpring = require(game:GetService("ReplicatedFirst").Modules.EzUISpring.GlobalPreset)

text.BackgroundTransparency = 1
text.TextTransparency = 1
local Subject

-- Tweens
local tweenInfo = TweenInfo.new(
    0.2, 
    Enum.EasingStyle.Linear,
    Enum.EasingDirection.In
)

local tweenInfo2 = TweenInfo.new(
    0.5, 
    Enum.EasingStyle.Linear,
    Enum.EasingDirection.In
)

local opennotif1 = {}
opennotif1.BackgroundTransparency = 0
opennotif1.Position = UDim2.new(0.373, 0, 0.892, 0)

local textnotif1 = {}
textnotif1.TextTransparency = 0

local closenotif1 = {}
closenotif1.BackgroundTransparency = 1
closenotif1.Position = UDim2.new(0.373, 0, 1, 0)

local textnotif2 = {}
textnotif2.TextTransparency = 1

local framein = {}
framein.Position = UDim2.new(0.015, 0, 0.18, 0)

local frameout = {}
frameout.Position = UDim2.new(-1, 0, 0.18, 0)

local vignetteblack = {}
vignetteblack.ImageColor3 = Color3.fromRGB(0, 0, 0)

local vignetteblue = {}
vignetteblue.ImageColor3 = Color3.fromRGB(82, 134, 255)

local vignettegreen = {}
vignettegreen.ImageColor3 = Color3.fromRGB(154, 255, 111)

-- Open Tweens
local opentweens = ts:Create(text, tweenInfo, opennotif1)
local opentweent = ts:Create(text, tweenInfo, textnotif1)
local fin = ts:Create(countdown, tweenInfo2, framein)

-- Close Tweens
local closetweens = ts:Create(text, tweenInfo, closenotif1)
local closetweent = ts:Create(text, tweenInfo, textnotif2)
local fout = ts:Create(countdown, tweenInfo2, frameout)
local vignettereturn = ts:Create(player.PlayerGui:WaitForChild("InGame").Vignette, tweenInfo, vignetteblack)
local vignetteblue = ts:Create(player.PlayerGui:WaitForChild("InGame").Vignette, tweenInfo, vignetteblue)
local vignettegreen = ts:Create(player.PlayerGui:WaitForChild("InGame").Vignette, tweenInfo, vignettegreen)

-- Person In Box
local function SetUpTouched(Object)
    local handleAction, runConn

    local Hitbox =  Object:WaitForChild("hitbox")

    local EXIT_RADIUS = Hitbox:GetAttribute("ExitRadius") or 12 -- how far away player needs to be for

    Hitbox.Touched:Connect(function(hit)
        if hit.Parent:FindFirstChild("Humanoid") and Subject == nil then
            --print("Touched")
            Subject = hit
            ui.Enabled = true
            if script:GetAttribute("enableNotification", true) then
                opentweens:Play()
                opentweent:Play()
            end
            context:BindAction("OpenBox", handleAction, true, Enum.KeyCode.E, Enum.KeyCode.ButtonR1)
            context:SetPosition("OpenBox", UDim2.new(1, -70, 0, 10))
            context:SetImage("OpenBox", "rbxassetid://12768386698")

            runConn = runservice.Heartbeat:Connect(function()
                local inRadius = true
                if Subject.Parent == nil then
                    inRadius = false
                else
                    local Distance = (Hitbox.Position - Subject.Position).Magnitude
                    if Distance >= EXIT_RADIUS then
                        inRadius = false
                    end
                end

                if inRadius == false then
                    runConn:Disconnect()
                    --print("TouchEnded")
                    EndDebounce = true
                    if opentweens.PlaybackState == Enum.PlaybackState.Playing then
                        opentweens.Completed:Wait()
                    end
                    if script:GetAttribute("enableNotification", true) then
                        closetweens:Play()
                        closetweent:Play()
                    end
                    context:UnbindAction("OpenBox")
                    task.wait(0.5)
                    ui.Enabled = false
                    EndDebounce = false
                    Subject = nil
                end
            end)
        end
    end)

    local PowerUp = Hitbox:GetAttribute("PowerUp")
    if PowerUp == "JumpBoost" then
        handleAction = function(actionName, inputState, _inputObject)
            if actionName == "OpenBox" and inputState == Enum.UserInputState.Begin then
                context:UnbindAction("OpenBox")
                local cvalue = Hitbox:GetAttribute("Countdown")
                player.Character:WaitForChild("Humanoid").Died:Connect(function()
                    cvalue = 0
                    closetweens:Play()
                    closetweent:Play()
                    fout:Play()
                    countdown.Visible = false
                    countdown.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
                end)
                sound:Play()
                countdown.Visible = true
                player:SetAttribute("PowerUp", PowerUp)
                fin:Play()
                vignettegreen:Play()
                icon.Image = "rbxassetid://14495774882"
                local highlight = Instance.new("Highlight")
                highlight.Parent = player.Character
                highlight.OutlineTransparency = 0.1
                highlight.FillTransparency = 1
                highlight.OutlineColor = Color3.fromRGB(179, 255, 107)
                highlight.OutlineTransparency = 1
                local tween1 = ts:Create(highlight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 0})
                local tween0 = ts:Create(highlight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 1})
                tween1:Play()
                player.Character:WaitForChild("Humanoid").UseJumpPower = true
                player.Character:FindFirstChild("Humanoid").JumpPower = 95
                Object:FindFirstChild("box").Transparency = 1
                Object:FindFirstChild("box"):FindFirstChild("PointLight").Enabled = false
                Object:FindFirstChild("box"):FindFirstChild("ParticleEmitter").Enabled = false
                Hitbox.CanTouch = false
                closetweens:Play()
                closetweent:Play()
                ui.Enabled = false
                repeat
                    if Object:FindFirstChild("hitbox") == nil then
                        return
                    end
                    countdown.TextLabel.Text = Object:FindFirstChild("hitbox"):GetAttribute("Countdown")
                    cvalue = cvalue - 1
                    if cvalue <= 4 then
                        countdown.TextLabel.TextColor3 = Color3.fromRGB(255, 52, 55)
                        ticksound:Play()
                    end
                    Object:FindFirstChild("hitbox"):SetAttribute("Countdown", cvalue)
                    task.wait(1)
                until
                cvalue == 0
                if cvalue == 0 then
                    tween0:Play()
                    fout:Play()
                    fout.Completed:Wait()
                    player:SetAttribute("PowerUp", "")
                    countdown.Visible = false
                    vignettereturn:Play()
                    countdown.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
                    player.Character:FindFirstChild("Humanoid").JumpPower = 50
                    tween0.Completed:Wait()
                    highlight:Destroy()
                end
            end
        end

    elseif PowerUp == "SpeedBoost" then
        handleAction = function(actionName, inputState, _inputObject)
            if actionName == "OpenBox" and inputState == Enum.UserInputState.Begin then
                workspace.Gravity = 150
                context:UnbindAction("OpenBox")
                local cvalue = Object:FindFirstChild("hitbox"):GetAttribute("Countdown")
                sound:Play()
                countdown.Visible = true
                player:SetAttribute("PowerUp", PowerUp)
                fin:Play()
                icon.Image = "rbxassetid://14495573983"
                local highlight = Instance.new("Highlight")
                highlight.Parent = player.Character
                highlight.OutlineColor = Color3.fromRGB(115, 164, 255)
                highlight.FillTransparency = 1
                highlight.OutlineTransparency = 1
                local tween1 = ts:Create(highlight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 0})
                local tween0 = ts:Create(highlight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 1})
                tween1:Play()
                vignetteblue:Play()
                script.Parent.FOV.FOV.Value = script.Parent.FOV.FOV.Value + 10
                player.Character:FindFirstChild("Humanoid").WalkSpeed = 40
                Object:FindFirstChild("box").Transparency = 1
                Object:FindFirstChild("box"):FindFirstChild("PointLight").Enabled = false
                Object:FindFirstChild("box"):FindFirstChild("ParticleEmitter").Enabled = false
                Hitbox.CanTouch = false
                closetweens:Play()
                closetweent:Play()
                ui.Enabled = false
                repeat
                    if Object:FindFirstChild("hitbox") == nil then
                        return
                    end
                    countdown.TextLabel.Text = Hitbox:GetAttribute("Countdown")
                    if cvalue <= 4 then
                        ticksound:Play()
                        countdown.TextLabel.TextColor3 = Color3.fromRGB(255, 52, 55)
                    end
                    cvalue = cvalue - 1
                    Hitbox:SetAttribute("Countdown", cvalue)
                    task.wait(1)
                until
                cvalue == 0
                if cvalue == 0 then
                    tween0:Play()
                    workspace.Gravity = 196.2
                    script.Parent.FOV.FOV.Value = script.Parent.FOV.InitialFOV.Value
                    fout:Play()
                    fout.Completed:Wait()
                    player:SetAttribute("PowerUp", "")
                    countdown.Visible = false
                    vignettereturn:Play()
                    countdown.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
                    player.Character:FindFirstChild("Humanoid").WalkSpeed = 20
                    tween0.Completed:Wait()
                    highlight:Destroy()
                end
            end
        end

        player.Character:WaitForChild("Humanoid").Died:Connect(function()
            workspace.Gravity = 196.2
            local cvalue = Object:FindFirstChild("hitbox"):GetAttribute("Countdown")
            fout:Play()
            fout.Completed:Wait()
            countdown.Visible = false
            cvalue = 0
            return
        end)
    end
end

local function FindBoxesRecurring(Object)
    if Object.Name == "Box" and Object:isA("Model") then
        SetUpTouched(Object)
    end
    for _, child in pairs(Object:GetChildren()) do
        FindBoxesRecurring(child)
    end
end

workspace.DescendantAdded:Connect(function(Object)
    if Object.Name == "Box" and Object:isA("Model") then
        SetUpTouched(Object)
    end
end)

FindBoxesRecurring(workspace)

Are there any changes prior to my original script if you don’t mind me asking? :0

If so, I’ll implement it to the current script.

The reason why I’m asking is because I’ve heavily reconstructed the script now, as you can probably see from later posts. :slight_smile:

The problem you’re having is that the magnitude check fires that the player is out of the box, even when they are still in the box (which means they can’t fire .Touched again to show the notification). Try increasing the EXIT_RADIUS and telling me what happens.

1 Like

Yes, there have been significant improvements made to the original script to enhance its readability and maintainability. These changes were made with the aim of creating a more efficient and reliable script. Here’s a summary of the key modifications:

  1. Removal of pcall(): The unnecessary pcall() function has been removed as it was not being used for error handling and could potentially hide issues. This ensures that errors are not concealed and can be addressed more effectively.
  2. Code Formatting: The script has undergone a thorough formatting update. Proper indentation and spacing have been applied, resulting in a much cleaner and more readable codebase.
  3. Variable Organization: Variable declarations have been moved to the top of the script to improve code organization. Related variables, such as tween settings and tweens, have been grouped together for clarity.
  4. Comment and Print Reduction: Redundant comments and print statements have been removed. This declutters the code and streamlines its structure.
  5. Simplified Structure: The script’s structure has been simplified to make it easier to follow, even for those new to the codebase.
  6. Event Handling: Event connections and function calls have been properly indented and organized for better code management.
  7. Comments Added: Comments have been added to describe the purpose of different sections of the code, making it more understandable for both you and other developers who may collaborate on this project.

These improvements should contribute to a more stable and maintainable script. Feel free to implement these changes into your current script to enjoy the benefits. If you have any questions or require further assistance, please don’t hesitate to ask!

increased radius (streamable.com)

It’s a bit laggy to see so I’ll try to explain as best as I can.

You have to get around a similar distance to activate the Press 'E' to Activate notification. However, for it to get out of view again, you have to go out around a slightly higher distance from the box for it to disappear. The issue is a bit harder to replicate with that said, though it’s also somewhat far for a hit radius, which isn’t ideal I would say.

By any chance, did you use ChatGPT?

Thank you for your inquiry! While I appreciate your curiosity, I did not use ChatGPT for the improvements made to the script. The changes were based on my personal experience and expertise in script optimization and best practices.

1 Like

Yea, the best thing you can do is try getting that EXIT_RADIUS to perfectly match the part’s size + a tiny offset. .TouchEnded would most likely be the best solution though, if you could show me your old code with it, I could debug it for you.

Thanks for the time to rewrite the code! However, as I’ve mentioned earlier, I have completely renovated how the script functions structure-wise, from top to bottom. If you have made any changes, can you please point them out to me by quoting, so I can adapt them to the new structure? I hope you don’t mind and sorry for the trouble!

Yikes, that’s going to be a problem. I’ve made the script months ago. Retrieving the old script would be very difficult, possibly impossible, considering I’ve moved the game to a group since then. I’m sorry. :frowning:

I’ll try messing with the EXIT_RADIUS and see what fits best, hopefully it works out well.

1 Like

If you could show me a picture of the Hitbox and it’s size dimensions that would help.

Totally! Here’s a picture:


Hope this helps!

Could you show the exact size dimensions?

Ah! Woops, let me do that.

Size: Vector3.new(14.943, 14.755, 18.367)

Update:
The bug is much harder to replicate now, though it can still be done if timed properly.

And I’m assuming 18.367 is the length of the top side right? (Not sure if your drawing is accurate to scale or not)

The way to get the correct ExitRadius, is to divide the Hitbox’s length (18.367) by 2, and add like 1 or some offset.

Indeed! I’m sorry for the poor drawing, but yes that’s to scale.

Could you try what I edited in, and tell me how it worked?

What have you edited, please?

(I’ll be right back, I have to eat. :])