sure
(ignore extra to fill in the space)
Here you go
MainScript:
--- Variables ---
local DialogueEvent = game.ReplicatedStorage.RemoteEvents.GuiEvents.DialogueEvent
local ObjectiveEvent = game.ReplicatedStorage.RemoteEvents.GuiEvents.ObjectiveEvent
local ToggleDialogueEvent = game.ReplicatedStorage.RemoteEvents.ToggleEvents.ToggleDialogueEvent
local ToggleObjectiveEvent = game.ReplicatedStorage.RemoteEvents.ToggleEvents.ToggleObjectiveEvent
local TransitionEvent = game.ReplicatedStorage.RemoteEvents.GuiEvents.TransitionEvent
local Objectives = game.ReplicatedStorage.Objectives
local TelportPoints = game.Workspace.TeleportPoints
local Sound = game.Workspace.Sounds
local scriptST = game.StarterPlayer.StarterPlayerScripts.RainScript
--- Npc Settings ---
local NpcModel = game.Workspace.Npc.Models.Kevin
local WalkToPoints = game.Workspace.Npc.WalkToPoints
local NpcImage = "rbxassetid://10691814554"
local NpcName = NpcModel.Name
--- Random Player ---
local PlayerImage
local PlayerName
local function RandomPlayer()
local Players = game.Players:GetPlayers()
local PlayerNum = math.random(1, #Players)
local ChosenPlayer = Players[PlayerNum]
PlayerImage = game.Players:GetUserThumbnailAsync(ChosenPlayer.UserId, Enum.ThumbnailType.AvatarBust, Enum.ThumbnailSize.Size420x420)
PlayerName = ChosenPlayer.Name
end
--- Functions ---
local function Teleport(TeleportPosition)
for i, Players in pairs(game.Players:GetPlayers()) do
Players.Character:FindFirstChild("HumanoidRootPart").CFrame = TeleportPosition
end
end
--- Game Functions ---
local function Part1() -- Look around places
game.Workspace.Sounds.DaySound:Play()
wait(2)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Hello everyone, Welcome to the Take a Rest Story, I'am Park Ranger Kevin, I work here for 7 years, so you don't have to worry about anything ;) !")
wait(15)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "I'am so excited!")
wait(3)
game.Workspace.InvisibleWalls.Part.CanCollide = false
DialogueEvent:FireAllClients(NpcImage, NpcName, "Let me show you all, follow me.")
wait(3)
NpcModel.Humanoid:MoveTo(WalkToPoints.HousePoint.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(2)
DialogueEvent:FireAllClients(NpcImage, NpcName, "This is our house, let go in!")
wait(2)
NpcModel.Humanoid:MoveTo(WalkToPoints.HousePoint1.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.HousePoint2.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.HousePoint3.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.HousePoint4.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(1)
DialogueEvent:FireAllClients(NpcImage, NpcName, "This is a kitchen.")
wait(2)
NpcModel.Humanoid:MoveTo(WalkToPoints.BedRoomPoint.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.BedRoomPoint1.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.BedRoomPoint2.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(1)
DialogueEvent:FireAllClients(NpcImage, NpcName, "This is a bedroom, you will sleep here tonight.")
wait(5)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Follow me to the next place.")
wait(3)
NpcModel.Humanoid:MoveTo(WalkToPoints.OutsidePoint.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.OutsidePoint1.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.OutsidePoint2.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.OutsidePoint3.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.OutsidePoint4.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.OutsidePoint5.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.OutsidePoint6.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.OutsidePoint7.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
game.Workspace.InvisibleWalls.Part2.CanCollide = false
NpcModel.Humanoid:MoveTo(WalkToPoints.PicnicPoint.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.PicnicPoint2.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
NpcModel.Humanoid:MoveTo(WalkToPoints.PicnicPoint1.Position)
NpcModel.Humanoid.MoveToFinished:Wait()
wait(0.1)
DialogueEvent:FireAllClients(NpcImage, NpcName, "This is picnic, here we will eat and relax.")
wait(18)
end
local function Part2() --Night 1
local Lighting = game.Lighting
local Atmosphere = game.Lighting.Atmosphere
local Shadow = game.Workspace.Shadow
DialogueEvent:FireAllClients(NpcImage, NpcName, "Night is approaching..")
wait(4)
TransitionEvent:FireAllClients()
wait(2)
Teleport(TelportPoints.Night1Tp.CFrame)
NpcModel:SetPrimaryPartCFrame(TelportPoints.Night1Tp.CFrame)
game.Workspace.Sounds.DaySound:Stop()
wait(0.1)
game.Workspace.Maps.House.Door.Part123.CanCollide = true
Lighting.Ambient = Color3.fromRGB(0,0,0)
Lighting.Brightness = 3.43
Lighting.ColorShift_Top = Color3.fromRGB(94,94,94)
Lighting.EnvironmentDiffuseScale = 0.443
Lighting.EnvironmentSpecularScale = 0.629
Lighting.ClockTime = 0
Lighting.TimeOfDay = 0
Lighting.ExposureCompensation = -0.39
Atmosphere.Color = Color3.fromRGB(102,113,135)
Atmosphere.Decay = Color3.fromRGB(211,176,176)
Atmosphere.Haze = 2.21
game.Lighting.ColorCorrection.Contrast = 0.2
game.Lighting.ColorCorrection.TintColor = Color3.fromRGB(255,252,224)
game.Lighting.Blur.Size = 2
game.Lighting.Bloom.Intensity = 0.35
game.Lighting.Bloom.Size = 22
game.Lighting.Bloom.Threshold = 0.8
game.Lighting.SunRays.Intensity = 0.117
game.Workspace.Sounds.NightSound:Play()
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Do you want to tell scary stories?")
wait(3)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "Sure!")
wait(3)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Do you know any story, I don't know any good ones.")
wait(6)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "I know one with clowns!")
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Oh no, I forgot something at the picnic, I'll be back in a minute.")
wait(6)
NpcModel:SetPrimaryPartCFrame(TelportPoints.NightNPCPicnicTP.CFrame)
wait(1)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "What now?")
wait(3)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "Idk, let's wait.")
wait(4)
game.Workspace.Sounds.NightSound:Stop()
wait(0.1)
Sound.DirtFootsteps:Play()
wait(5)
Sound.DirtFootsteps:Stop()
wait(0.1)
game.Workspace.Sounds.NightSound:Play()
wait(0.1)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "Guys, did you hear that?")
wait(4)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "Yes,we did!")
wait(3)
Shadow.Head.Transparency = 0
Shadow.HumanoidRootPart.Transparency = 0
Shadow["Left Arm"].Transparency = 0
Shadow["Left Leg"].Transparency = 0
Shadow["Right Arm"].Transparency = 0
Shadow["Right Leg"].Transparency = 0
Shadow.Torso.Transparency = 0
Shadow.Head.Beam.Transparency = NumberSequence.new(0.5)
Shadow.Head.Eye.Transparency = 0
Shadow.Head.Eye2.Transparency = 0
Shadow["Left Arm"].Beam.Transparency = NumberSequence.new(0.5)
Shadow["Left Leg"].Beam.Transparency = NumberSequence.new(0.5)
Shadow["Right Arm"].Beam.Transparency = NumberSequence.new(0.5)
Shadow["Right Leg"].Beam.Transparency = NumberSequence.new(0.5)
wait(0.1)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "OMG, look at window!!")
wait(5)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "IT IS A MONSTER!")
wait(4)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "RUN TO THE BEDROOM!!")
wait(3)
Shadow.Head.Transparency = 1
Shadow.HumanoidRootPart.Transparency = 1
Shadow["Left Arm"].Transparency = 1
Shadow["Left Leg"].Transparency = 1
Shadow["Right Arm"].Transparency = 1
Shadow["Right Leg"].Transparency = 1
Shadow.Torso.Transparency = 1
Shadow.Head.Beam.Transparency = NumberSequence.new(1)
Shadow.Head.Eye.Transparency = 1
Shadow.Head.Eye2.Transparency = 1
Shadow["Left Arm"].Beam.Transparency = NumberSequence.new(1)
Shadow["Left Leg"].Beam.Transparency = NumberSequence.new(1)
Shadow["Right Arm"].Beam.Transparency = NumberSequence.new(1)
Shadow["Right Leg"].Beam.Transparency = NumberSequence.new(1)
wait(0.1)
NpcModel:SetPrimaryPartCFrame(TelportPoints.NPChouseNight1TP.CFrame)
wait(5)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Guys Im back, where are you?")
wait(4)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "We are in bedroom..")
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Why are you guys in bedroom come upstairs.")
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "What happend?")
wait(3)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "We saw monster! It is black with white eyes..")
wait(7)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Are you guys trying to scare me or what?")
wait(5)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "No, we're serious!")
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "You probably need some sleep.")
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Good night.")
wait(2)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "Good night.")
wait(4)
TransitionEvent:FireAllClients()
wait(2)
game.Workspace.Maps.House.Door.Part123.CanCollide = false
Lighting.Ambient = Color3.fromRGB(112,112,112)
Lighting.Brightness = 3.93
Lighting.ColorShift_Top = Color3.fromRGB(118,117,101)
Lighting.EnvironmentDiffuseScale = 0.343
Lighting.EnvironmentSpecularScale = 1
Lighting.OutdoorAmbient = Color3.fromRGB(141,141,141)
Lighting.ShadowSoftness = 0.1
Lighting.ClockTime = 13
Lighting.GeographicLatitude = 32
Lighting.TimeOfDay = 13
Lighting.ExposureCompensation = 0.34
Atmosphere.Density = 0.348
Atmosphere.Offset = 0.199
Atmosphere.Color = Color3.fromRGB(216,255,250)
Atmosphere.Glare = 0.68
Atmosphere.Haze = 0.36
game.Lighting.ColorCorrection.Contrast = 0.2
game.Lighting.ColorCorrection.TintColor = Color3.fromRGB(255,252,224)
game.Lighting.Blur.Size = 2
game.Lighting.Bloom.Size = 0
game.Lighting.Bloom.Threshold = 4
game.Lighting.SunRays.Intensity = 0.117
game.Workspace.Sounds.NightSound:Stop()
wait(4)
game.Workspace.Sounds.DaySound:Play()
DialogueEvent:FireAllClients(NpcImage, NpcName, "Good morning y'all!")
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Let's go eat breakfast at picnic!")
wait(4)
TransitionEvent:FireAllClients()
wait(2)
Teleport(TelportPoints.PicnicTP.CFrame)
NpcModel:SetPrimaryPartCFrame(TelportPoints.PicnicTP.CFrame)
wait(5)
end
local function Part3() -- Breakfast, rain, night 2
local Lighting = game.Lighting
local Atmosphere = game.Lighting.Atmosphere
local Shadow = game.Workspace.Shadow2
local Blood = game.Workspace.Blood
game.Workspace.InvisibleWalls.NikoInista.CanCollide = true
DialogueEvent:FireAllClients(NpcImage, NpcName, "Did anyone bring any food?")
wait(4)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "No, we didn't.")
wait(3)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Then let's find some.")
wait(3)
ToggleDialogueEvent:FireAllClients(false) --False = Invisible, True = Visible
ToggleObjectiveEvent:FireAllClients(true) --False = Invisible, True = Visible
local ApplesFound = Objectives.AppleObjective.ApplesFound
local ApplesModel = Objectives.AppleObjective.ApplesModel
ApplesModel:Clone().Parent = game.Workspace
while wait() do
ObjectiveEvent:FireAllClients("Find Apples:" ..ApplesFound.Value.."/10")
if ApplesFound.Value == 10 then
wait(1)
break
end
end
ToggleDialogueEvent:FireAllClients(true) --False = Invisible, True = Visible
ToggleObjectiveEvent:FireAllClients(false) --False = Invisible, True = Visible
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "We found some apples!")
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Great! Let's eat!")
wait(1)
game.Workspace.Maps.PicnicBasket.Apple.Transparency = 0
game.Workspace.Maps.PicnicBasket.Apple1.Transparency = 0
game.Workspace.Maps.PicnicBasket.Apple2.Transparency = 0
game.Workspace.Maps.PicnicBasket.Apple3.Transparency = 0
wait(0.1)
game.Workspace.ToolGiverPart.CanTouch = true
wait(1.5)
game.Workspace.ToolGiverPart.CanTouch = false
wait(3)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Enjoy your apples!")
wait(6)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Today, we are not sleeping in house, we are sleeping here!")
wait(4)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "That's cool.")
wait(3)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "But we need materials for campfire.")
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Oh yea!")
wait(3)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Then let's find some rocks and wood!")
wait(4)
ToggleDialogueEvent:FireAllClients(false) --False = Invisible, True = Visible
ToggleObjectiveEvent:FireAllClients(true) --False = Invisible, True = Visible
local ApplesFound = Objectives.CampfireObjective.WoodAndRockFound
local ApplesModel = Objectives.CampfireObjective.WoodAndRockModel
ApplesModel:Clone().Parent = game.Workspace
while wait() do
ObjectiveEvent:FireAllClients("Find Wood and Rocks:" ..ApplesFound.Value.."/10")
if ApplesFound.Value == 10 then
wait(1)
break
end
end
ToggleDialogueEvent:FireAllClients(true) --False = Invisible, True = Visible
ToggleObjectiveEvent:FireAllClients(false) --False = Invisible, True = Visible
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "We found rocks and wood! Now all is ready.")
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Night is approaching..")
wait(4)
TransitionEvent:FireAllClients()
wait(2)
Teleport(TelportPoints.PicnicTP.CFrame)
NpcModel:SetPrimaryPartCFrame(TelportPoints.PicnicTP.CFrame)
game.Workspace.Sounds.DaySound:Stop()
wait(0.1)
Lighting.Ambient = Color3.fromRGB(0,0,0)
Lighting.Brightness = 3.43
Lighting.ColorShift_Top = Color3.fromRGB(94,94,94)
Lighting.EnvironmentDiffuseScale = 0.443
Lighting.EnvironmentSpecularScale = 0.629
Lighting.ClockTime = 0
Lighting.TimeOfDay = 0
Lighting.ExposureCompensation = -0.39
Atmosphere.Color = Color3.fromRGB(102,113,135)
Atmosphere.Decay = Color3.fromRGB(211,176,176)
Atmosphere.Haze = 2.21
game.Lighting.ColorCorrection.Contrast = 0.2
game.Lighting.ColorCorrection.TintColor = Color3.fromRGB(255,252,224)
game.Lighting.Blur.Size = 2
game.Lighting.Bloom.Intensity = 0.35
game.Lighting.Bloom.Size = 22
game.Lighting.Bloom.Threshold = 0.8
game.Lighting.SunRays.Intensity = 0.117
game.Workspace.Sounds.NightSound:Play()
wait(0.1)
for i,v in pairs(workspace.Campfire:GetChildren()) do
v.Transparency = 0
end
wait(0.1)
game.Workspace.Campfire.Fire.Particles.Transparency = NumberSequence.new(0)
game.Workspace.Campfire.Fire.Transparency = 1
wait(0.1)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Sit and relax.")
wait(4)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "What are we going to do?")
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "We can play games.")
wait(3)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "I know we can play hide and seek!")
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Good idea!")
wait(3)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "Let's play!")
wait(3)
DialogueEvent:FireAllClients(NpcImage, NpcName, "WAIT WAIT!")
wait(2)
DialogueEvent:FireAllClients(NpcImage, NpcName, "WHAT IS THAT BLACK THING ABOVE FIRE!")
wait(3)
Shadow.Head.Transparency = 0
Shadow.HumanoidRootPart.Transparency = 0
Shadow["Left Arm"].Transparency = 0
Shadow["Left Leg"].Transparency = 0
Shadow["Right Arm"].Transparency = 0
Shadow["Right Leg"].Transparency = 0
Shadow.Torso.Transparency = 0
Shadow.Head.Beam.Transparency = NumberSequence.new(0.5)
Shadow.Head.Eye.Transparency = 0
Shadow.Head.Eye2.Transparency = 0
Shadow["Left Arm"].Beam.Transparency = NumberSequence.new(0.5)
Shadow["Left Leg"].Beam.Transparency = NumberSequence.new(0.5)
Shadow["Right Arm"].Beam.Transparency = NumberSequence.new(0.5)
Shadow["Right Leg"].Beam.Transparency = NumberSequence.new(0.5)
game.Workspace.InvisibleWalls.NikoInista.CanCollide = false
wait(0.1)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "IT IS A MONSTER!!!")
wait(3)
DialogueEvent:FireAllClients(NpcImage, NpcName, "RUN TO THE HOUSE!!")
wait(26)
Teleport(TelportPoints.Night1Tp.CFrame)
NpcModel:SetPrimaryPartCFrame(TelportPoints.Night1Tp.CFrame)
game.Workspace.Maps.House.Door.Part123.CanCollide = true
wait(1)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "That's the monster we saw last night!")
Shadow.Head.Transparency = 1
Shadow.HumanoidRootPart.Transparency = 1
Shadow["Left Arm"].Transparency = 1
Shadow["Left Leg"].Transparency = 1
Shadow["Right Arm"].Transparency = 1
Shadow["Right Leg"].Transparency = 1
Shadow.Torso.Transparency = 1
Shadow.Head.Beam.Transparency = NumberSequence.new(1)
Shadow.Head.Eye.Transparency = 1
Shadow.Head.Eye2.Transparency = 1
Shadow["Left Arm"].Beam.Transparency = NumberSequence.new(1)
Shadow["Left Leg"].Beam.Transparency = NumberSequence.new(1)
Shadow["Right Arm"].Beam.Transparency = NumberSequence.new(1)
Shadow["Right Leg"].Beam.Transparency = NumberSequence.new(1)
wait(4)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Okay guys, now I believe you.")
wait(3)
for i,v in pairs(game.Players:GetChildren()) do
local PlayerScripts = v:WaitForChild("PlayerScripts")
PlayerScripts.RainScript.Disabled = false
end
wait(0.1)
game.Workspace.Sounds.NightSound:Stop()
wait(0.1)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "Oh great, rain is here..")
game.Workspace.Campfire.Fire.Particles.Transparency = NumberSequence.new(1)
wait(3)
DialogueEvent:FireAllClients(NpcImage, NpcName, "I can't do this anymore!")
wait(3)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "Let's go sleep, we need to rest.")
wait(3)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Good night.")
wait(4)
TransitionEvent:FireAllClients()
wait(2)
game.Workspace.Maps.House.Door.Part123.CanCollide = false
Lighting.Ambient = Color3.fromRGB(112,112,112)
Lighting.Brightness = 3.93
Lighting.ColorShift_Top = Color3.fromRGB(118,117,101)
Lighting.EnvironmentDiffuseScale = 0.343
Lighting.EnvironmentSpecularScale = 1
Lighting.OutdoorAmbient = Color3.fromRGB(141,141,141)
Lighting.ShadowSoftness = 0.1
Lighting.ClockTime = 13
Lighting.GeographicLatitude = 32
Lighting.TimeOfDay = 13
Lighting.ExposureCompensation = 0.34
Atmosphere.Density = 0.348
Atmosphere.Offset = 0.199
Atmosphere.Color = Color3.fromRGB(216,255,250)
Atmosphere.Glare = 0.68
Atmosphere.Haze = 0.36
game.Lighting.ColorCorrection.Contrast = 0.2
game.Lighting.ColorCorrection.TintColor = Color3.fromRGB(255,252,224)
game.Lighting.Blur.Size = 2
game.Lighting.Bloom.Size = 0
game.Lighting.Bloom.Threshold = 4
game.Lighting.SunRays.Intensity = 0.117
for i,v in pairs(game.Players:GetChildren()) do
local PlayerScripts = v:WaitForChild("PlayerScripts")
PlayerScripts.RainScript.Disabled = true
end
wait(0.1)
game.Workspace.Sounds.DaySound:Play()
Blood.Part.Transparency = 0
Blood.Part1.Transparency = 0
Blood.Part2.Transparency = 0
Blood.Part3.Transparency = 0
Blood.Part4.Transparency = 0
Blood.Part5.Transparency = 0
Blood.Part6.Transparency = 0
Blood.Part7.Transparency = 0
Blood.Part8.Transparency = 0
Blood.Part9.Transparency = 0
wait(0.1)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Guys let's go see what's going on at picnic.")
wait(4)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "Im scared..")
wait(2)
DialogueEvent:FireAllClients(NpcImage, NpcName, "Don't be, when it is day we are safe.")
wait(4)
TransitionEvent:FireAllClients()
wait(2)
Teleport(TelportPoints.PicnicTP.CFrame)
NpcModel:SetPrimaryPartCFrame(TelportPoints.PicnicTP.CFrame)
wait(3)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "Look there is a blood...")
wait(3)
DialogueEvent:FireAllClients(NpcImage, NpcName, "That's weird..")
wait(4)
for i,v in pairs(game.Players:GetChildren()) do
local PlayerScripts = v:WaitForChild("PlayerScripts")
PlayerScripts.RainScript.Disabled = false
end
wait(0.1)
RandomPlayer() DialogueEvent:FireAllClients(PlayerImage, PlayerName, "Not the rain again!")
wait(3)
DialogueEvent:FireAllClients(NpcImage, NpcName, "This time we will be wet, RUN HOME!")
wait(15)
-- When I finish with rain I will complete script
end
wait(10)
Part1() -- Look around place
Part2() -- Night 1
Part3() -- Breakfast, rain, night 2
In function3 is rain
RainScript:
local Rain = require(script.Rain)
Rain:SetColor(Color3.fromRGB(script.Color.Value.x, script.Color.Value.y, script.Color.Value.z))
Rain:SetDirection(script.Direction.Value)
Rain:SetTransparency(script.Transparency.Value)
Rain:SetSpeedRatio(script.SpeedRatio.Value)
Rain:SetIntensityRatio(script.IntensityRatio.Value)
Rain:SetLightInfluence(script.LightInfluence.Value)
Rain:SetLightEmission(script.LightEmission.Value)
Rain:SetVolume(script.Volume.Value)
Rain:SetSoundId(script.SoundId.Value)
Rain:SetStraightTexture(script.StraightTexture.Value)
Rain:SetTopDownTexture(script.TopDownTexture.Value)
Rain:SetSplashTexture(script.SplashTexture.Value)
local threshold = script.TransparencyThreshold.Value
if script.TransparencyConstraint.Value and script.CanCollideConstraint.Value then
Rain:SetCollisionMode(
Rain.CollisionMode.Function,
function(p)
return p.Transparency <= threshold and p.CanCollide
end
)
elseif script.TransparencyConstraint.Value then
Rain:SetCollisionMode(
Rain.CollisionMode.Function,
function(p)
return p.Transparency <= threshold
end
)
elseif script.CanCollideConstraint.Value then
Rain:SetCollisionMode(
Rain.CollisionMode.Function,
function(p)
return p.CanCollide
end
)
end
Rain:Enable()
Then inside the rainscript I have this:
And Rain Module Script:
local MIN_SIZE = Vector3.new(0.05,0.05,0.05) -- Size of main emitter part when rain inactive
local RAIN_DEFAULT_COLOR = Color3.new(1,1,1) -- Default color3 of all rain elements
local RAIN_DEFAULT_TRANSPARENCY = 0 -- Default transparency scale ratio of all rain elements
local RAIN_DEFAULT_SPEEDRATIO = 1 -- Default speed scale ratio of falling rain effects
local RAIN_DEFAULT_INTENSITYRATIO = 1 -- Default intensity ratio of all rain elements
local RAIN_DEFAULT_LIGHTEMISSION = 0.05 -- Default LightEmission of all rain elements
local RAIN_DEFAULT_LIGHTINFLUENCE = 0.9 -- Default LightInfluence of all rain elements
local RAIN_DEFAULT_DIRECTION = Vector3.new(0,-1,0) -- Default direction for rain to fall into
local RAIN_TRANSPARENCY_T1 = .25 -- Define the shape (time-wise) of the transparency curves for emitters
local RAIN_TRANSPARENCY_T2 = .75
local RAIN_SCANHEIGHT = 1000 -- How many studs to scan up from camera position to determine whether occluded
local RAIN_EMITTER_DIM_DEFAULT = 40 -- Size of emitter block to the side/up
local RAIN_EMITTER_DIM_MAXFORWARD = 100 -- Size of emitter block forwards when looking at the horizon
local RAIN_EMITTER_UP_MODIFIER = 20 -- Maximum vertical displacement of emitter (when looking fully up/down)
local RAIN_SOUND_ASSET = "rbxassetid://1516791621"
local RAIN_SOUND_BASEVOLUME = 0.2 -- Starting volume of rain sound effect when not occluded
local RAIN_SOUND_FADEIN_TIME = 1 -- Tween in/out times for sound volume
local RAIN_SOUND_FADEOUT_TIME = 1
local RAIN_STRAIGHT_ASSET = "rbxassetid://1822883048" -- Some properties of the straight rain particle effect
local RAIN_STRAIGHT_ALPHA_LOW = 0.7 -- Minimum particle transparency for the straight rain emitter
local RAIN_STRAIGHT_SIZE = NumberSequence.new(10)
local RAIN_STRAIGHT_LIFETIME = NumberRange.new(0.8)
local RAIN_STRAIGHT_MAX_RATE = 600 -- Maximum rate for the straight rain emitter
local RAIN_STRAIGHT_MAX_SPEED = 60 -- Maximum speed for the straight rain emitter
local RAIN_TOPDOWN_ASSET = "rbxassetid://1822856633" -- Some properties of the top-down rain particle effect
local RAIN_TOPDOWN_ALPHA_LOW = 0.85 -- Minimum particle transparency for the top-down rain emitter
local RAIN_TOPDOWN_SIZE = NumberSequence.new {
NumberSequenceKeypoint.new(0, 5.33, 2.75);
NumberSequenceKeypoint.new(1, 5.33, 2.75);
}
local RAIN_TOPDOWN_LIFETIME = NumberRange.new(0.8)
local RAIN_TOPDOWN_ROTATION = NumberRange.new(0,360)
local RAIN_TOPDOWN_MAX_RATE = 600 -- Maximum rate for the top-down rain emitter
local RAIN_TOPDOWN_MAX_SPEED = 60 -- Maximum speed for the top-down rain emitter
local RAIN_SPLASH_ASSET = "rbxassetid://1822856633" -- Some properties of the splash particle effect
local RAIN_SPLASH_ALPHA_LOW = 0.6 -- Minimum particle transparency for the splash emitters
local RAIN_SPLASH_SIZE = NumberSequence.new {
NumberSequenceKeypoint.new(0, 0);
NumberSequenceKeypoint.new(.4, 3);
NumberSequenceKeypoint.new(1, 0);
}
local RAIN_SPLASH_LIFETIME = NumberRange.new(0.1, 0.15)
local RAIN_SPLASH_ROTATION = NumberRange.new(0,360)
local RAIN_SPLASH_NUM = 20 -- Amount of splashes per frame
local RAIN_SPLASH_CORRECTION_Y = .5 -- Offset from impact position for visual reasons
local RAIN_SPLASH_STRAIGHT_OFFSET_Y = 50 -- Offset against rain direction for straight rain particles from splash position
local RAIN_NOSPLASH_STRAIGHT_OFFSET_Y_MIN = 20 -- Min/max vertical offset from camera height for straight rain particles
local RAIN_NOSPLASH_STRAIGHT_OFFSET_Y_MAX = 100 -- when no splash position could be found (i.e. no floor at that XZ-column)
local RAIN_OCCLUDED_MINSPEED = 70 -- Minimum speed for the occluded straight rain emitters
local RAIN_OCCLUDED_MAXSPEED = 100 -- Maximum speed for the occluded straight rain emitters
local RAIN_OCCLUDED_SPREAD = Vector2.new(10,10) -- Spread angle for the occluded straight rain emitters
local RAIN_OCCLUDED_MAXINTENSITY = 2 -- How many occluded straight rain particles are emitted for every splash for max intensity
local RAIN_OCCLUDECHECK_OFFSET_Y = 500 -- Vertical offset from camera height to start scanning downward from for splashes
local RAIN_OCCLUDECHECK_OFFSET_XZ_MIN = -100 -- Range of possible XZ offset values from camera XZ position for the splashes
local RAIN_OCCLUDECHECK_OFFSET_XZ_MAX = 100
local RAIN_OCCLUDECHECK_SCAN_Y = 550 -- Scan magnitude along rain path
local RAIN_UPDATE_PERIOD = 6 -- Update the transparency of the main emitters + volume of rain inside every X frames
local RAIN_VOLUME_SCAN_RADIUS = 35 -- Defining grid for checking how far the camera is away from a spot exposed to rain
local RAIN_VOLUME_SCAN_GRID = { -- Unit range grid for scanning how far away user is from rain space
-- range 0.2, 4 pts
Vector3.new(0.141421363, 0, 0.141421363);
Vector3.new(-0.141421363, 0, 0.141421363);
Vector3.new(-0.141421363, 0, -0.141421363);
Vector3.new(0.141421363, 0, -0.141421363);
-- range 0.4, 8 pts
Vector3.new(0.400000006, 0, 0);
Vector3.new(0.282842726, 0, 0.282842726);
Vector3.new(2.44929371e-17, 0, 0.400000006);
Vector3.new(-0.282842726, 0, 0.282842726);
Vector3.new(-0.400000006, 0, 4.89858741e-17);
Vector3.new(-0.282842726, 0, -0.282842726);
Vector3.new(-7.34788045e-17, 0, -0.400000006);
Vector3.new(0.282842726, 0, -0.282842726);
-- range 0.6, 10 pts
Vector3.new(0.600000024, 0, 0);
Vector3.new(0.485410213, 0, 0.352671146);
Vector3.new(0.185410202, 0, 0.570633948);
Vector3.new(-0.185410202, 0, 0.570633948);
Vector3.new(-0.485410213, 0, 0.352671146);
Vector3.new(-0.600000024, 0, 7.34788112e-17);
Vector3.new(-0.485410213, 0, -0.352671146);
Vector3.new(-0.185410202, 0, -0.570633948);
Vector3.new(0.185410202, 0, -0.570633948);
Vector3.new(0.485410213, 0, -0.352671146);
-- range 0.8, 12 pts
Vector3.new(0.772740662, 0, 0.207055241);
Vector3.new(0.565685451, 0, 0.565685451);
Vector3.new(0.207055241, 0, 0.772740662);
Vector3.new(-0.207055241, 0, 0.772740662);
Vector3.new(-0.565685451, 0, 0.565685451);
Vector3.new(-0.772740662, 0, 0.207055241);
Vector3.new(-0.772740662, 0, -0.207055241);
Vector3.new(-0.565685451, 0, -0.565685451);
Vector3.new(-0.207055241, 0, -0.772740662);
Vector3.new(0.207055241, 0, -0.772740662);
Vector3.new(0.565685451, 0, -0.565685451);
Vector3.new(0.772740662, 0, -0.207055241);
}
-- Enumerators:
local CollisionMode = {
None = 0;
Whitelist = 1;
Blacklist = 2;
Function = 3;
}
-- Variables & setup:
-- services
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local GlobalModifier = Instance.new("NumberValue") -- modifier for rain visibility for disabling/enabling over time span
GlobalModifier.Value = 1 -- 0 = fully visible, 1 = invisible
local connections = {} -- Stores connections to RunService signals when enabled
local disabled = true -- Value to figure out whether we are moving towards a disabled state (useful during tweens)
local rainDirection = RAIN_DEFAULT_DIRECTION -- Direction that rain falls into
local currentCeiling = nil -- Y coordinate of ceiling (if present)
local collisionMode = CollisionMode.None -- Collision mode (from Rain.CollisionMode) for raycasting
local collisionList = nil -- Blacklist/whitelist for raycasting
local collisionFunc = nil -- Raycasting test function for when collisionMode == Rain.CollisionMode.Function
local straightLowAlpha = 1 -- Current transparency for straight rain particles
local topdownLowAlpha = 1 -- Current transparency for top-down rain particles
local intensityOccludedRain = 0 -- Current intensity of occluded rain particles
local numSplashes = 0 -- Current number of generated splashes per frame
local volumeTarget = 0 -- Current (target of tween for) sound volume
-- shorthands
local v3 = Vector3.new
local NSK010 = NumberSequenceKeypoint.new(0, 1, 0)
local NSK110 = NumberSequenceKeypoint.new(1, 1, 0)
local volumeScanGrid = {} -- Pre-generate grid used for raining area distance scanning
for _,v in pairs(RAIN_VOLUME_SCAN_GRID) do
table.insert(volumeScanGrid, v * RAIN_VOLUME_SCAN_RADIUS)
end
table.sort(volumeScanGrid, function(a,b) -- Optimization: sort from close to far away for fast evaluation if closeby
return a.magnitude < b.magnitude
end)
-- sound group for easy main volume tweaking
local SoundGroup = Instance.new("SoundGroup")
SoundGroup.Name = "__RainSoundGroup"
SoundGroup.Volume = RAIN_SOUND_BASEVOLUME
SoundGroup.Archivable = false
local Sound = Instance.new("Sound")
Sound.Name = "RainSound"
Sound.Volume = volumeTarget
Sound.SoundId = RAIN_SOUND_ASSET
Sound.Looped = true
Sound.SoundGroup = SoundGroup
Sound.Parent = SoundGroup
Sound.Archivable = false
-- emitter block around camera used when outside
local Emitter do
Emitter = Instance.new("Part")
Emitter.Transparency = 1
Emitter.Anchored = true
Emitter.CanCollide = false
Emitter.Locked = false
Emitter.Archivable = false
Emitter.TopSurface = Enum.SurfaceType.Smooth
Emitter.BottomSurface = Enum.SurfaceType.Smooth
Emitter.Name = "__RainEmitter"
Emitter.Size = MIN_SIZE
Emitter.Archivable = false
local straight = Instance.new("ParticleEmitter")
straight.Name = "RainStraight"
straight.LightEmission = RAIN_DEFAULT_LIGHTEMISSION
straight.LightInfluence = RAIN_DEFAULT_LIGHTINFLUENCE
straight.Size = RAIN_STRAIGHT_SIZE
straight.Texture = RAIN_STRAIGHT_ASSET
straight.LockedToPart = true
straight.Enabled = false
straight.Lifetime = RAIN_STRAIGHT_LIFETIME
straight.Rate = RAIN_STRAIGHT_MAX_RATE
straight.Speed = NumberRange.new(RAIN_STRAIGHT_MAX_SPEED)
straight.EmissionDirection = Enum.NormalId.Bottom
straight.Parent = Emitter
straight.Orientation = Enum.ParticleOrientation.FacingCameraWorldUp
local topdown = Instance.new("ParticleEmitter")
topdown.Name = "RainTopDown"
topdown.LightEmission = RAIN_DEFAULT_LIGHTEMISSION
topdown.LightInfluence = RAIN_DEFAULT_LIGHTINFLUENCE
topdown.Size = RAIN_TOPDOWN_SIZE
topdown.Texture = RAIN_TOPDOWN_ASSET
topdown.LockedToPart = true
topdown.Enabled = false
topdown.Rotation = RAIN_TOPDOWN_ROTATION
topdown.Lifetime = RAIN_TOPDOWN_LIFETIME
topdown.Rate = RAIN_TOPDOWN_MAX_RATE
topdown.Speed = NumberRange.new(RAIN_TOPDOWN_MAX_SPEED)
topdown.EmissionDirection = Enum.NormalId.Bottom
topdown.Parent = Emitter
end
local splashAttachments, rainAttachments do
splashAttachments = {}
rainAttachments = {}
for i = 1, RAIN_SPLASH_NUM do
-- splashes on ground
local splashAttachment = Instance.new("Attachment")
splashAttachment.Name = "__RainSplashAttachment"
local splash = Instance.new("ParticleEmitter")
splash.LightEmission = RAIN_DEFAULT_LIGHTEMISSION
splash.LightInfluence = RAIN_DEFAULT_LIGHTINFLUENCE
splash.Size = RAIN_SPLASH_SIZE
splash.Texture = RAIN_SPLASH_ASSET
splash.Rotation = RAIN_SPLASH_ROTATION
splash.Lifetime = RAIN_SPLASH_LIFETIME
splash.Transparency = NumberSequence.new {
NSK010;
NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T1, RAIN_SPLASH_ALPHA_LOW, 0);
NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T2, RAIN_SPLASH_ALPHA_LOW, 0);
NSK110;
}
splash.Enabled = false
splash.Rate = 0
splash.Speed = NumberRange.new(0)
splash.Name = "RainSplash"
splash.Parent = splashAttachment
splashAttachment.Archivable = false
table.insert(splashAttachments, splashAttachment)
-- occluded rain particle generation
local rainAttachment = Instance.new("Attachment")
rainAttachment.Name = "__RainOccludedAttachment"
local straightOccluded = Emitter.RainStraight:Clone()
straightOccluded.Speed = NumberRange.new(RAIN_OCCLUDED_MINSPEED, RAIN_OCCLUDED_MAXSPEED)
straightOccluded.SpreadAngle = RAIN_OCCLUDED_SPREAD
straightOccluded.LockedToPart = false
straightOccluded.Enabled = false
straightOccluded.Parent = rainAttachment
local topdownOccluded = Emitter.RainTopDown:Clone()
topdownOccluded.Speed = NumberRange.new(RAIN_OCCLUDED_MINSPEED, RAIN_OCCLUDED_MAXSPEED)
topdownOccluded.SpreadAngle = RAIN_OCCLUDED_SPREAD
topdownOccluded.LockedToPart = false
topdownOccluded.Enabled = false
topdownOccluded.Parent = rainAttachment
rainAttachment.Archivable = false
table.insert(rainAttachments, rainAttachment)
end
end
-- Helper methods:
local ignoreEmitterList = { Emitter }
local raycastFunctions = {
[CollisionMode.None] = function(ray, ignoreCharacter)
return workspace:FindPartOnRayWithIgnoreList(ray, ignoreCharacter and {Emitter, Players.LocalPlayer and Players.LocalPlayer.Character} or ignoreEmitterList)
end;
[CollisionMode.Blacklist] = function(ray)
return workspace:FindPartOnRayWithIgnoreList(ray, collisionList)
end;
[CollisionMode.Whitelist] = function(ray)
return workspace:FindPartOnRayWithWhitelist(ray, collisionList)
end;
[CollisionMode.Function] = function(ray)
local destination = ray.Origin + ray.Direction
-- draw multiple raycasts concatenated to each other until no hit / valid hit found
while ray.Direction.magnitude > 0.001 do
local part, pos, norm, mat = workspace:FindPartOnRayWithIgnoreList(ray, ignoreEmitterList)
if not part or collisionFunc(part) then
return part, pos, norm, mat
end
local start = pos + ray.Direction.Unit * 0.001
ray = Ray.new(start, destination - start)
end
end;
}
local raycast = raycastFunctions[collisionMode]
local function connectLoop()
local rand = Random.new()
local inside = true -- Whether camera is currently in a spot occluded from the sky
local frame = RAIN_UPDATE_PERIOD -- Frame counter, and force update cycle right now
-- Update Emitter on RenderStepped since it needs to be synced to Camera
table.insert(connections, RunService.RenderStepped:connect(function()
-- Check if camera is outside or inside
local part, position = raycast(Ray.new(workspace.CurrentCamera.CFrame.p, -rainDirection * RAIN_SCANHEIGHT), true)
if (not currentCeiling or workspace.CurrentCamera.CFrame.p.y <= currentCeiling) and not part then
-- Camera is outside and under ceiling
if volumeTarget < 1 and not disabled then
volumeTarget = 1
TweenService:Create(Sound, TweenInfo.new(.5), {Volume = 1}):Play()
end
frame = RAIN_UPDATE_PERIOD
local t = math.abs(workspace.CurrentCamera.CFrame.lookVector:Dot(rainDirection))
local center = workspace.CurrentCamera.CFrame.p
local right = workspace.CurrentCamera.CFrame.lookVector:Cross(-rainDirection)
right = right.magnitude > 0.001 and right.unit or -rainDirection
local forward = rainDirection:Cross(right).unit
Emitter.Size = v3(
RAIN_EMITTER_DIM_DEFAULT,
RAIN_EMITTER_DIM_DEFAULT,
RAIN_EMITTER_DIM_DEFAULT + (1 - t)*(RAIN_EMITTER_DIM_MAXFORWARD - RAIN_EMITTER_DIM_DEFAULT)
)
Emitter.CFrame =
CFrame.new(
center.x, center.y, center.z,
right.x, -rainDirection.x, forward.x,
right.y, -rainDirection.y, forward.y,
right.z, -rainDirection.z, forward.z
)
+ (1 - t) * workspace.CurrentCamera.CFrame.lookVector * Emitter.Size.Z/3
- t * rainDirection * RAIN_EMITTER_UP_MODIFIER
Emitter.RainStraight.Enabled = true
Emitter.RainTopDown.Enabled = true
inside = false
else
-- Camera is inside / above ceiling
Emitter.RainStraight.Enabled = false
Emitter.RainTopDown.Enabled = false
inside = true
end
end))
-- Do the other effects on Stepped
local signal = RunService:IsRunning() and RunService.Stepped or RunService.RenderStepped
table.insert(connections, signal:connect(function()
frame = frame + 1
-- Only do some updates once every few frames
if frame >= RAIN_UPDATE_PERIOD then
-- Measure of how much camera is facing down (0-1)
local t = math.abs(workspace.CurrentCamera.CFrame.lookVector:Dot(rainDirection))
-- More looking down = see straight particles less and see top-down particles more
local straightSequence = NumberSequence.new {
NSK010;
NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T1, (1 - t)*straightLowAlpha + t, 0);
NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T2, (1 - t)*straightLowAlpha + t, 0);
NSK110;
}
local topdownSequence = NumberSequence.new {
NSK010;
NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T1, t*topdownLowAlpha + (1 - t), 0);
NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T2, t*topdownLowAlpha + (1 - t), 0);
NSK110;
}
-- Find desired rotation for the straight rain particles
local mapped = workspace.Camera.CFrame:inverse() * (workspace.Camera.CFrame.p - rainDirection)
local straightRotation = NumberRange.new(math.deg(math.atan2(-mapped.x, mapped.y)))
if inside then
-- Update emitter properties
for _,v in pairs(rainAttachments) do
v.RainStraight.Transparency = straightSequence
v.RainStraight.Rotation = straightRotation
v.RainTopDown.Transparency = topdownSequence
end
if not disabled then
-- Only do occluded volume check if not moving towards disabled state
local volume = 0
if (not currentCeiling or workspace.CurrentCamera.CFrame.p.y <= currentCeiling) then
-- Check how far away camera is from a space open to the sky using volume scan grid
local minDistance = RAIN_VOLUME_SCAN_RADIUS
local rayDirection = -rainDirection * RAIN_SCANHEIGHT
for i = 1, #volumeScanGrid do -- In order, so first hit is closest
if not raycast(Ray.new(workspace.CurrentCamera.CFrame * volumeScanGrid[i], rayDirection), true) then
minDistance = volumeScanGrid[i].magnitude
break
end
end
-- Volume is inversely proportionate to minimum distance
volume = 1 - minDistance / RAIN_VOLUME_SCAN_RADIUS
end
if math.abs(volume - volumeTarget) > .01 then
-- Value is sufficiently different from previous target, overwrite it
volumeTarget = volume
TweenService:Create(Sound, TweenInfo.new(1), {Volume = volumeTarget}):Play()
end
end
else
-- Update emitter properties
Emitter.RainStraight.Transparency = straightSequence
Emitter.RainStraight.Rotation = straightRotation
Emitter.RainTopDown.Transparency = topdownSequence
end
-- Reset frame counter
frame = 0
end
local center = workspace.CurrentCamera.CFrame.p
local right = workspace.CurrentCamera.CFrame.lookVector:Cross(-rainDirection)
right = right.magnitude > 0.001 and right.unit or -rainDirection
local forward = rainDirection:Cross(right).unit
local transform = CFrame.new(
center.x, center.y, center.z,
right.x, -rainDirection.x, forward.x,
right.y, -rainDirection.y, forward.y,
right.z, -rainDirection.z, forward.z
)
local rayDirection = rainDirection * RAIN_OCCLUDECHECK_SCAN_Y
-- Splash and occlusion effects
for i = 1, numSplashes do
local splashAttachment = splashAttachments[i]
local rainAttachment = rainAttachments[i]
-- Sample random splash position
local x = rand:NextNumber(RAIN_OCCLUDECHECK_OFFSET_XZ_MIN, RAIN_OCCLUDECHECK_OFFSET_XZ_MAX)
local z = rand:NextNumber(RAIN_OCCLUDECHECK_OFFSET_XZ_MIN, RAIN_OCCLUDECHECK_OFFSET_XZ_MAX)
local part, position, normal = raycast(Ray.new(transform * v3(x, RAIN_OCCLUDECHECK_OFFSET_Y, z), rayDirection))
if part then
-- Draw a splash at hit
splashAttachment.Position = position + normal * RAIN_SPLASH_CORRECTION_Y
splashAttachment.RainSplash:Emit(1)
if inside then
-- Draw occlusion rain particles a little bit above the splash position
local corrected = position - rainDirection * RAIN_SPLASH_STRAIGHT_OFFSET_Y
if currentCeiling and corrected.Y > currentCeiling and rainDirection.Y < 0 then
corrected = corrected + rainDirection * (currentCeiling - corrected.Y) / rainDirection.Y
end
rainAttachment.CFrame = transform - transform.p + corrected
rainAttachment.RainStraight:Emit(intensityOccludedRain)
rainAttachment.RainTopDown:Emit(intensityOccludedRain)
end
elseif inside then
-- Draw occlusion rain particles on the XZ-position at around the camera's height
local corrected = transform * v3(x, rand:NextNumber(RAIN_NOSPLASH_STRAIGHT_OFFSET_Y_MIN, RAIN_NOSPLASH_STRAIGHT_OFFSET_Y_MAX), z)
if currentCeiling and corrected.Y > currentCeiling and rainDirection.Y < 0 then
corrected = corrected + rainDirection * (currentCeiling - corrected.Y) / rainDirection.Y
end
rainAttachment.CFrame = transform - transform.p + corrected
rainAttachment.RainStraight:Emit(intensityOccludedRain)
rainAttachment.RainTopDown:Emit(intensityOccludedRain)
end
end
end))
end
local function disconnectLoop()
-- If present, disconnect all RunService connections
if #connections > 0 then
for _,v in pairs(connections) do
v:disconnect()
end
connections = {}
end
end
local function disableSound(tweenInfo)
-- Tween the rain sound to be mute over a given easing function
volumeTarget = 0
local tween = TweenService:Create(Sound, tweenInfo, {Volume = 0})
tween.Completed:connect(function(state)
if state == Enum.PlaybackState.Completed then
Sound:Stop()
end
tween:Destroy()
end)
tween:Play()
end
local function disable()
disconnectLoop()
-- Hide Emitter
Emitter.RainStraight.Enabled = false
Emitter.RainTopDown.Enabled = false
Emitter.Size = MIN_SIZE
-- Disable sound now if not tweened into disabled state beforehand
if not disabled then
disableSound(TweenInfo.new(RAIN_SOUND_FADEOUT_TIME))
end
end
-- Shorthand for creating a tweenable "variable" using value object
local function makeProperty(valueObjectClass, defaultValue, setter)
local valueObject = Instance.new(valueObjectClass)
if defaultValue then
valueObject.Value = defaultValue
end
valueObject.Changed:connect(setter)
setter(valueObject.Value)
return valueObject
end
local Color = makeProperty("Color3Value", RAIN_DEFAULT_COLOR, function(value)
local value = ColorSequence.new(value)
Emitter.RainStraight.Color = value
Emitter.RainTopDown.Color = value
for _,v in pairs(splashAttachments) do
v.RainSplash.Color = value
end
for _,v in pairs(rainAttachments) do
v.RainStraight.Color = value
v.RainTopDown.Color = value
end
end)
local function updateTransparency(value)
local opacity = (1 - value) * (1 - GlobalModifier.Value)
local transparency = 1 - opacity
straightLowAlpha = RAIN_STRAIGHT_ALPHA_LOW * opacity + transparency
topdownLowAlpha = RAIN_TOPDOWN_ALPHA_LOW * opacity + transparency
local splashSequence = NumberSequence.new {
NSK010;
NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T1, opacity*RAIN_SPLASH_ALPHA_LOW + transparency, 0);
NumberSequenceKeypoint.new(RAIN_TRANSPARENCY_T2, opacity*RAIN_SPLASH_ALPHA_LOW + transparency, 0);
NSK110;
}
for _,v in pairs(splashAttachments) do
v.RainSplash.Transparency = splashSequence
end
end
local Transparency = makeProperty("NumberValue", RAIN_DEFAULT_TRANSPARENCY, updateTransparency)
GlobalModifier.Changed:connect(updateTransparency)
local SpeedRatio = makeProperty("NumberValue", RAIN_DEFAULT_SPEEDRATIO, function(value)
Emitter.RainStraight.Speed = NumberRange.new(value * RAIN_STRAIGHT_MAX_SPEED)
Emitter.RainTopDown.Speed = NumberRange.new(value * RAIN_TOPDOWN_MAX_SPEED)
end)
local IntensityRatio = makeProperty("NumberValue", RAIN_DEFAULT_INTENSITYRATIO, function(value)
Emitter.RainStraight.Rate = RAIN_STRAIGHT_MAX_RATE * value
Emitter.RainTopDown.Rate = RAIN_TOPDOWN_MAX_RATE * value
intensityOccludedRain = math.ceil(RAIN_OCCLUDED_MAXINTENSITY * value)
numSplashes = RAIN_SPLASH_NUM * value
end)
local LightEmission = makeProperty("NumberValue", RAIN_DEFAULT_LIGHTEMISSION, function(value)
Emitter.RainStraight.LightEmission = value
Emitter.RainTopDown.LightEmission = value
for _,v in pairs(rainAttachments) do
v.RainStraight.LightEmission = value
v.RainTopDown.LightEmission = value
end
for _,v in pairs(splashAttachments) do
v.RainSplash.LightEmission = value
end
end)
local LightInfluence = makeProperty("NumberValue", RAIN_DEFAULT_LIGHTINFLUENCE, function(value)
Emitter.RainStraight.LightInfluence = value
Emitter.RainTopDown.LightInfluence = value
for _,v in pairs(rainAttachments) do
v.RainStraight.LightInfluence = value
v.RainTopDown.LightInfluence = value
end
for _,v in pairs(splashAttachments) do
v.RainSplash.LightInfluence = value
end
end)
local RainDirection = makeProperty("Vector3Value", RAIN_DEFAULT_DIRECTION, function(value)
if value.magnitude > 0.001 then
rainDirection = value.unit
end
end)
-- Exposed API:
local Rain = {}
Rain.CollisionMode = CollisionMode
function Rain:Enable(tweenInfo)
if tweenInfo ~= nil and typeof(tweenInfo) ~= "TweenInfo" then
error("bad argument #1 to 'Enable' (TweenInfo expected, got " .. typeof(tweenInfo) .. ")", 2)
end
disconnectLoop() -- Just in case :Enable(..) is called multiple times on accident
Emitter.RainStraight.Enabled = true
Emitter.RainTopDown.Enabled = true
Emitter.Parent = workspace.CurrentCamera
for i = 1, RAIN_SPLASH_NUM do
splashAttachments[i].Parent = workspace.Terrain
rainAttachments[i].Parent = workspace.Terrain
end
if RunService:IsRunning() then -- don't need sound in studio preview, it won't work anyway
SoundGroup.Parent = game:GetService("SoundService")
end
connectLoop()
if tweenInfo then
TweenService:Create(GlobalModifier, tweenInfo, {Value = 0}):Play()
else
GlobalModifier.Value = 0
end
if not Sound.Playing then
Sound:Play()
Sound.TimePosition = math.random()*Sound.TimeLength
end
disabled = false
end
function Rain:Disable(tweenInfo)
if tweenInfo ~= nil and typeof(tweenInfo) ~= "TweenInfo" then
error("bad argument #1 to 'Disable' (TweenInfo expected, got " .. typeof(tweenInfo) .. ")", 2)
end
if tweenInfo then
local tween = TweenService:Create(GlobalModifier, tweenInfo, {Value = 1})
tween.Completed:connect(function(state)
if state == Enum.PlaybackState.Completed then
-- Only disable the rain completely once the visual effects are faded out
disable()
end
tween:Destroy()
end)
tween:Play()
-- Start tweening out sound now as well
disableSound(tweenInfo)
else
GlobalModifier.Value = 1
disable()
end
disabled = true
end
function Rain:SetColor(value, tweenInfo)
if typeof(value) ~= "Color3" then
error("bad argument #1 to 'SetColor' (Color3 expected, got " .. typeof(value) .. ")", 2)
elseif tweenInfo ~= nil and typeof(tweenInfo) ~= "TweenInfo" then
error("bad argument #2 to 'SetColor' (TweenInfo expected, got " .. typeof(tweenInfo) .. ")", 2)
end
if tweenInfo then
TweenService:Create(Color, tweenInfo, {Value = value}):Play()
else
Color.Value = value
end
end
local function makeRatioSetter(methodName, valueObject)
-- Shorthand because most of the remaining property setters are very similar
return function(_, value, tweenInfo)
if typeof(value) ~= "number" then
error("bad argument #1 to '" .. methodName .. "' (number expected, got " .. typeof(value) .. ")", 2)
elseif tweenInfo ~= nil and typeof(tweenInfo) ~= "TweenInfo" then
error("bad argument #2 to '" .. methodName .. "' (TweenInfo expected, got " .. typeof(tweenInfo) .. ")", 2)
end
value = math.clamp(value, 0, 1)
if tweenInfo then
TweenService:Create(valueObject, tweenInfo, {Value = value}):Play()
else
valueObject.Value = value
end
end
end
Rain.SetTransparency = makeRatioSetter("SetTransparency", Transparency)
Rain.SetSpeedRatio = makeRatioSetter("SetSpeedRatio", SpeedRatio)
Rain.SetIntensityRatio = makeRatioSetter("SetIntensityRatio", IntensityRatio)
Rain.SetLightEmission = makeRatioSetter("SetLightEmission", LightEmission)
Rain.SetLightInfluence = makeRatioSetter("SetLightInfluence", LightInfluence)
function Rain:SetVolume(volume, tweenInfo)
if typeof(volume) ~= "number" then
error("bad argument #1 to 'SetVolume' (number expected, got " .. typeof(volume) .. ")", 2)
elseif tweenInfo ~= nil and typeof(tweenInfo) ~= "TweenInfo" then
error("bad argument #2 to 'SetVolume' (TweenInfo expected, got " .. typeof(tweenInfo) .. ")", 2)
end
if tweenInfo then
TweenService:Create(SoundGroup, tweenInfo, {Volume = volume}):Play()
else
SoundGroup.Volume = volume
end
end
function Rain:SetDirection(direction, tweenInfo)
if typeof(direction) ~= "Vector3" then
error("bad argument #1 to 'SetDirection' (Vector3 expected, got " .. typeof(direction) .. ")", 2)
elseif tweenInfo ~= nil and typeof(tweenInfo) ~= "TweenInfo" then
error("bad argument #2 to 'SetDirection' (TweenInfo expected, got " .. typeof(tweenInfo) .. ")", 2)
end
if not (direction.unit.magnitude > 0) then -- intentional statement formatting since NaN comparison
warn("Attempt to set rain direction to a zero-length vector, falling back on default direction = (" .. tostring(RAIN_DEFAULT_DIRECTION) .. ")")
direction = RAIN_DEFAULT_DIRECTION
end
if tweenInfo then
TweenService:Create(RainDirection, tweenInfo, {Value = direction}):Play()
else
RainDirection.Value = direction
end
end
function Rain:SetCeiling(ceiling)
if ceiling ~= nil and typeof(ceiling) ~= "number" then
error("bad argument #1 to 'SetCeiling' (number expected, got " .. typeof(ceiling) .. ")", 2)
end
currentCeiling = ceiling
end
function Rain:SetStraightTexture(asset)
if typeof(asset) ~= "string" then
error("bad argument #1 to 'SetStraightTexture' (string expected, got " .. typeof(asset) .. ")", 2)
end
Emitter.RainStraight.Texture = asset
for _,v in pairs(rainAttachments) do
v.RainStraight.Texture = asset
end
end
function Rain:SetTopDownTexture(asset)
if typeof(asset) ~= "string" then
error("bad argument #1 to 'SetStraightTexture' (string expected, got " .. typeof(asset) .. ")", 2)
end
Emitter.RainTopDown.Texture = asset
for _,v in pairs(rainAttachments) do
v.RainTopDown.Texture = asset
end
end
function Rain:SetSplashTexture(asset)
if typeof(asset) ~= "string" then
error("bad argument #1 to 'SetStraightTexture' (string expected, got " .. typeof(asset) .. ")", 2)
end
for _,v in pairs(splashAttachments) do
v.RainSplash.Texture = asset
end
end
function Rain:SetSoundId(asset)
if typeof(asset) ~= "string" then
error("bad argument #1 to 'SetSoundId' (string expected, got " .. typeof(asset) .. ")", 2)
end
Sound.SoundId = asset
end
function Rain:SetCollisionMode(mode, param)
if mode == CollisionMode.None then
-- Regular mode needs no white/blacklist or test function
collisionList = nil
collisionFunc = nil
elseif mode == CollisionMode.Blacklist then
if typeof(param) == "Instance" then
-- Add Emitter anyway, since users will probably not expect collisions with emitter block regardless
collisionList = {param, Emitter}
elseif typeof(param) == "table" then
for i = 1, #param do
if typeof(param[i]) ~= "Instance" then
error("bad argument #2 to 'SetCollisionMode' (blacklist contained a " .. typeof(param[i]) .. " on index " .. tostring(i) .. " which is not an Instance)", 2)
end
end
collisionList = {Emitter} -- see above
for i = 1, #param do
table.insert(collisionList, param[i])
end
else
error("bad argument #2 to 'SetCollisionMode (Instance or array of Instance expected, got " .. typeof(param) .. ")'", 2)
end
-- Blacklist does not need a test function
collisionFunc = nil
elseif mode == CollisionMode.Whitelist then
if typeof(param) == "Instance" then
collisionList = {param}
elseif typeof(param) == "table" then
for i = 1, #param do
if typeof(param[i]) ~= "Instance" then
error("bad argument #2 to 'SetCollisionMode' (whitelist contained a " .. typeof(param[i]) .. " on index " .. tostring(i) .. " which is not an Instance)", 2)
end
end
collisionList = {}
for i = 1, #param do
table.insert(collisionList, param[i])
end
else
error("bad argument #2 to 'SetCollisionMode (Instance or array of Instance expected, got " .. typeof(param) .. ")'", 2)
end
-- Whitelist does not need a test function
collisionFunc = nil
elseif mode == CollisionMode.Function then
if typeof(param) ~= "function" then
error("bad argument #2 to 'SetCollisionMode' (function expected, got " .. typeof(param) .. ")", 2)
end
-- Test function does not need a list
collisionList = nil
collisionFunc = param
else
error("bad argument #1 to 'SetCollisionMode (Rain.CollisionMode expected, got " .. typeof(param) .. ")'", 2)
end
collisionMode = mode
raycast = raycastFunctions[mode]
end
return Rain
Its a lot bc its a realistic rain
And thanks for helping me!
Maybe change
for i,v in pairs(game.Players:GetChildren()) do
local PlayerScripts = v:WaitForChild("PlayerScripts")
PlayerScripts.RainScript.Disabled = false
end
to
for i,v in pairs(game.Players:GetChildren()) do
v:FindFirstChild("RainScript", true).Disabled = false
end
Honestly I can’t think of any other way, there is nothing really out of the open that looks wrong
If the script is already disabled, are you trying to disable it again? Also, what part about the script isn’t working?
It is disabled and I am trying to undisable it in script
INSIDE The rain script or OUTSIDE?
also please use task.wait()
instead of wait()
In output it says, ServerScriptService.Scripts.MainScript:479: attempt to index nil with ‘Disabled’
outside, scroll up so you can see rain script and main script
for whatever reason the script thinks that There is no PlayerScripts in the player
You can’t disable starterplayer scripts server-sided due to this.
The starterplayer is created locally.
your best option is remote events.
On your main script (serversided) try this
game.ReplicatedStorage.Event:FireAllClients() -- replace "Event" with any remote event that server can access.
and your localscript do this (make sure its in starterplayerscript, optional btw)
game.ReplicatedStorage.Event.OnClientEvent:Connect(function()
script.Parent.RainScript.Disabled = false
end)
Each player’s ‘PlayerScripts’ container isn’t replicated to the server.
If you want to stop the rain effect, require the module on the client and call the :Disable() method. To enable it again, use the :Enable() method.
This is described in the module’s documentation.
You’ll need to require and call the method on the client instead of on the server.
Please, make sure to read the documentation. The post above by @weakroblox35 should be unmarked as solution because it is plainly wrong usage for this library, and they could have known also if they read the documentation of the module.
disabling scripts don’t end them
They asked for a localscript to be disabled, i helped them, i see no mentions of a modulescript anywhere…?
Besides , it helped them disable the raineffect anyways.
The module pointed out in the thread (Rain Module + Plugin) has clear API documentation that can be used to achieve the intended effect of OP. Disabling the script instance that set up the rain is a bad and hacky solution in this context considering there is a very clear API available to enable/disable the rain effect through the library module itself.
In #help-and-feedback:scripting-support , it’s important to recognize when someone is posing an XY problem and guide them toward the better (simpler) solution. What the first poster is asking for may be due to a misunderstanding of how things work. It’s also part of the first poster’s fault for not doing due dilligence reading documentation and asking a badly posed question, FWIW.
Well i wasn’t really aware that it was a plugin, thanks for clarifying it out.