Yeah, I know. I realized my mistake in my code but there’s this weird bug that only tweens the color of a specific cloud for some reason and I don’t know why
local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SoundService = game:GetService("SoundService")
local Debris = game:GetService("Debris")
local LIGHTNING_STRIKE_SOUND = ReplicatedStorage:WaitForChild("Sounds"):WaitForChild("Lightning Strike 3")
local LIGHTNING_MODEL = ReplicatedStorage:WaitForChild("Models"):WaitForChild("Lightning")
local function CLOUD_COLOR_TOGGLE(CLOUD_MESH)
TweenService:Create(CLOUD_MESH, TweenInfo.new(3, Enum.EasingStyle.Linear), {Color = Color3.fromRGB(0, 0, 0)}):Play()
task.wait(math.random(5, 10))
TweenService:Create(CLOUD_MESH, TweenInfo.new(3, Enum.EasingStyle.Linear), {Color = Color3.fromRGB(255, 255, 255)}):Play()
task.wait(1)
end
local function STRIKE_PLAYER(Humanoid, Head, Cloud)
local Lightning_Model_Clone = LIGHTNING_MODEL:Clone()
local Lightning_Sound_Clone = LIGHTNING_STRIKE_SOUND:Clone()
Lightning_Model_Clone.Parent = game.Workspace
Lightning_Model_Clone:PivotTo(CFrame.new(Head.Position + Vector3.new(0, 60, 0)))
Lightning_Sound_Clone.Parent = Head
Lightning_Sound_Clone:Play()
Humanoid.Sit = true
Humanoid:TakeDamage(20)
Debris:AddItem(Lightning_Model_Clone, 2)
Debris:AddItem(Lightning_Sound_Clone, 2)
task.wait(5)
Cloud:SetAttribute("Lightning", false)
end
for i, v in script.Parent:GetDescendants() do
if v:IsA("Folder") or v:IsA("Model") or v:IsA("SpecialMesh") or v:IsA("WeldConstraint") or v:IsA("TouchTransmitter") or v:IsA("Script") or v.Name == "Cloud" then continue end
for ii, CLOUD_MESH in script.Parent:GetDescendants() do
if CLOUD_MESH:IsA("Folder") or CLOUD_MESH:IsA("Model") or CLOUD_MESH:IsA("SpecialMesh") or CLOUD_MESH:IsA("WeldConstraint") or CLOUD_MESH:IsA("TouchTransmitter") or CLOUD_MESH:IsA("Script") or CLOUD_MESH.Name == "CloudPlatform" then continue end
v.Touched:Connect(function(hit)
if not hit.Parent:FindFirstChild("Humanoid") or v:GetAttribute("Touched", true) or v:GetAttribute("Lightning", false) then return end
v:SetAttribute("Touched", true)
if math.random(1, 100) <= 100 then
v:SetAttribute("Lightning", true)
task.spawn(CLOUD_COLOR_TOGGLE, CLOUD_MESH)
task.spawn(STRIKE_PLAYER, hit.Parent:FindFirstChild("Humanoid"), hit.Parent:FindFirstChild("Head"), v)
task.wait(1)
v:SetAttribute("Touched", false)
else
task.wait(1)
v:SetAttribute("Touched", false)
end
end)
end
end
This is the code I’m using for my obby script thing and Idk why but it’s bugging out
I notice that you only refer to Lightning Strike 3
and nothing else.
Pardon the constant message changes. I’m still reading the situation.
There’s Cloud1, Cloud2, and Cloud3. Whatever cloud I touch it will always be that same one.
For one thing, task.spawn
probably doesn’t forward arguments. I know that spawn
doesn’t.
local val = 6
function f(val)
print(val)
end
spawn(f, 12)
It’ll print 6.
It does forward arguments you pass into it
task.spawn
does pass varargs through to the function as parameters (this is different behavior than the deprecated spawn
function)
The intention of the logic with the nested loop and the mountain of conditions for the loops is unclear to me, so it’s hard to help here.
Also, :GetAttribute()
only takes 1 parameter
Is Touched
attribute supposed to be a local debounce for that cloud?
What is Lightning
attribute used for, and why is it never set back to true?
Is each cloud mesh a single MeshPart named “cloud”?
Whats the difference between cloud and cloudplatform?
The cloud is just the mesh and the cloud platform is just what the player stands on.
If I’ve understood correctly, this might be a better approach:
local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Things in ReplicatedStorage are guaranteed to exist at runtime (assuming StreamingEnabled is false), no need to WaitForChild
local lightningStrikeSoundTemplate = ReplicatedStorage.Sounds:FindFirstChild("Lightning Strike 3")
local lightningModelTemplate = ReplicatedStorage.Models.Lightning
local LIGHTNING_CHANCE_PERCENT = 100 -- 0% to 100%
local MIN_SECONDS_BETWEEN_STRIKES = 5
local CLOUD_STRIKE_COLOR_TIME = {
Min = 5,
Max = 10
}
local random = Random.new()
local tweenInfo = TweenInfo.new(3, Enum.EasingStyle.Linear)
local CLOUD_STRIKE_COLOR = Color3.fromRGB(0, 0, 0)
local CLOUD_NORMAL_COLOR = Color3.fromRGB(255, 255, 255)
local LIGHTNING_OFFSET = Vector3.new(0, 60, 0)
local strikeColorTween = nil
local function tweenCloudColor(cloudMesh: MeshPart)
strikeColorTween = TweenService:Create(cloudMesh, tweenInfo, { Color = CLOUD_STRIKE_COLOR })
strikeColorTween.Completed:Once(function(tweenStatus: Enum.TweenStatus)
if tweenStatus ~= Enum.TweenStatus.Completed then
return
end
local thisStrikeColorTween = strikeColorTween
task.wait(random:NextInteger(CLOUD_STRIKE_COLOR_TIME.Min, CLOUD_STRIKE_COLOR_TIME.Max))
if thisStrikeColorTween ~= strikeColorTween then
return
end
TweenService:Create(cloudMesh, tweenInfo, { Color = CLOUD_NORMAL_COLOR }):Play()
end)
strikeColorTween:Play()
end
local function strikePlayer(humanoid, head)
local lightningModel = lightningModelTemplate:Clone()
local lightningSound = lightningStrikeSoundTemplate:Clone()
local lightningCFrame = CFrame.new(head.Position + LIGHTNING_OFFSET)
lightningModel:PivotTo(lightningCFrame)
lightningModel.Parent = Workspace
lightningSound.Parent = head
lightningSound:Play()
lightningSound.Ended:Once(function()
lightningSound:Destroy()
lightningModel:Destroy()
end)
humanoid.Sit = true
humanoid:TakeDamage(20)
end
local function createLightningStrike(cloudPlatform: BasePart, humanoid: Humanoid)
local head = humanoid.Parent:FindFirstChild("Head")
if not head then
return
end
local cloudMesh = cloudPlatform:FindFirstChild("cloud")
tweenCloudColor(cloudMesh)
strikePlayer(humanoid, head)
end
local function isCloudPlatform(instance: Instance)
-- A better way to do this is tag your cloud platforms with a "CloudPlatform" tag and check instance:HasTag("CloudPlatform") here; or, iterate over CollectionService:GetTagged("CloudPlatform") instead of filtering descendants like this
return instance.Name == "CloudPlatform"
end
for _, descendant in script.Parent:GetDescendants() do
if not isCloudPlatform(descendant) then
continue
end
local cloudPlatform = descendant :: BasePart
local debounce = false
cloudPlatform.Touched:Connect(function(hit: BasePart)
if debounce then
return
end
local humanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
if not humanoid then
return
end
debounce = true
local shouldStrike = random:NextInteger(1, 100) <= LIGHTNING_CHANCE_PERCENT
if shouldStrike then
createLightningStrike(cloudPlatform, humanoid)
task.wait(MIN_SECONDS_BETWEEN_STRIKES)
else
task.wait(1)
end
debounce = false
end)
end
I think I understand most of it but why is there a variable for strikeColorTween? Why not just tween it in the function and I don’t know what StreamingEnabled is.
It looked like your code wanted some delay between when the cloud turns dark and when it turns back to white. Because tweenCloudColor
could be called during that delay, it needs to check after the delay if it was called again at some point during the delay. Put another way, it needs to know if it’s still the most recent call. Because if it isn’t, then it shouldn’t set the color back to white. A second cloud strike during the delay should basically cancel the first strike’s delayed set-to-white operation.
The way that it knows if it’s the most recent call is by storing the created tween in a global variable that changes each time the function is called. So it is then able to compare “thisStrikeColorTween” with “strikeColorTween” (the global one) to see if the global one still matches “this” one. If it does, then it knows it’s still the latest call, and so it does not need to cancel turning it to white.