Error in Output - attempt to perform arithmetic (mul) on Vector3 and table

I’ve sort of recoded a free model script to fit my style, this model is a rain script.

The issue I’m getting is on line 149: attempt to perform arithmetic (mul) on Vector3 and table, and have no idea why.

image

This is the server script.

local rain = require(script.Rain)

rain:setColor(Color3.fromRGB(script.Color.Value.x, script.Color.Value.y, script.Color.Value.z))

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:setDirection(script.Direction.Value)

rain:setStraightTexture(script.StraightTexture.Value)
rain:setTopDownTexture(script.TopDownTexture.Value)
rain:setSplashTexture(script.SplashTexture.Value)

rain:setSoundId(script.SoundId.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()

This is the module script that handles the main events.

local min_Size = Vector3.new(.1, .1, .1)

local rain_Default_Color = Color3.new(255, 255, 255)
local rain_Default_Transparency = 0
local rain_Default_Speedratio = 1
local rain_Default_Intensityratio = 1
local rain_Default_Lightemission = .05
local rain_Default_Lightinfluence = .9
local rain_Default_Direction = Vector3.new(0, -1, 0)

local rain_Transparency_T1 = .25
local rain_Transparency_T2 = .75

local rain_Scanheight = 1000

local rain_Emitter_Dim_Default = 40
local rain_Emitter_Dim_Maxforward = 100
local rain_Emitter_Up_Modifier = 20

local rain_Sound_Asset = "rbxassetid://1516791621"
local rain_Sound_Basevolume = .2
local rain_Sound_Fadein_Time = 10
local rain_Sound_Fadeout_Time = 10

local rain_Straight_Asset = "rbxassetid://1822883048"
local rain_Straight_Alpha_Low = .7
local rain_Straight_Size = NumberSequence.new(15)
local rain_Straight_Lifetime = NumberRange.new(.8)
local rain_Straight_Max_Rate = 750
local rain_Straight_Max_Speed = 75

local rain_Topdown_Asset = "rbxassetid://1822856633"
local rain_Topdown_Alpha_Low = .85
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(.8)
local rain_Topdown_Rotation = NumberRange.new(0, 360)
local rain_Topdown_Max_Rate = 750
local rain_Topdown_Max_Speed = 75

local rain_Splash_Asset = "rbxassetid://1822856633"
local rain_Splash_Alpha_Low = .6
local rain_Splash_Size = NumberSequence.new{
	NumberSequenceKeypoint.new(0, 0);
	NumberSequenceKeypoint.new(.4, 3);
	NumberSequenceKeypoint.new(1, 0);
}
local rain_Splash_Lifetime = NumberRange.new(.1, .15)
local rain_Splash_Rotation = NumberRange.new(0, 360)
local rain_Splash_Number = 20
local rain_Splash_Correction_Y = .5
local rain_Splash_Straight_Offset_Y = 50
local rain_Nosplash_Straight_Offset_Y_Min = 20
local rain_Nosplash_Straight_Offset_Y_Max = 100

local rain_Occluded_Minspeed = 70
local rain_Occluded_Maxspeed = 100
local rain_Occluded_Spread = Vector2.new(10, 10)
local rain_Occluded_Maxintensity = 2

local rain_Occludecheck_Offset_Y = 500
local rain_Occludecheck_Offset_XZ_Min = -100
local rain_Occludecheck_Offset_XZ_Max = 100
local rain_Occludecheck_Scan_Y = 550

local rain_Update_Period = 6

local rain_Volume_Scan_Radius = 50
local rain_Volume_Scan_Grid = {
	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);

	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);

	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);

	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);
}

local collisionMode = {
	None = 0;
	Whitelist = 1;
	Blacklist = 2;
	Function = 3;
}

local players = game:GetService("Players")
local tweenService = game:GetService("TweenService")
local runService = game:GetService("RunService")

local globalModifier = Instance.new("NumberValue")
globalModifier.Value = 1

local connections = {}

local disabled = true

local rainDirection = rain_Default_Direction

local currentCeiling = nil

local collisionMode = collisionMode.None
local collisionList = nil
local collisionFunc = nil

local straightLowAlpha = 1
local topdownLowAlpha = 1
local intensityOccludedRain = 0
local numberSplashes = 0
local volumeTarget = 0

local v3 = Vector3.new
local numberSequenceKeypoint1 = NumberSequenceKeypoint.new(0, 1, 0)
local numberSequenceKeypoint2 = NumberSequenceKeypoint.new(1, 1, 0)

local volumeScanGrid = {}
for _, v in pairs(rain_Volume_Scan_Grid) do
	table.insert(volumeScanGrid, v * rain_Volume_Scan_Grid)
end
table.sort(volumeScanGrid, function(a, b)
	return a.magnitude < b.magnitude
end)

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

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 = false
	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 = false
	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_Number do
		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{
			numberSequenceKeypoint1;
			NumberSequenceKeypoint.new(rain_Transparency_T1, rain_Splash_Alpha_Low, 0);
			NumberSequenceKeypoint.new(rain_Transparency_T2, rain_Splash_Alpha_Low, 0);
			numberSequenceKeypoint2;
		}
		splash.Enabled = false
		splash.Rate = 0
		splash.Speed = NumberRange.new(0)
		splash.Name = "RainSplash"
		splash.Parent = splashAttachment
		splashAttachment.Archivable = false
		table.insert(splashAttachments, splashAttachment)
		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

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
		while ray.Direction.magnitude > .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
	local frame = rain_Update_Period
	table.insert(connections, runService.RenderStepped:connect(function()
		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
			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 > .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
			emitter.RainStraight.Enabled = false
			emitter.RainTopDown.Enabled = false
			inside = true
		end
	end))
	local signal = runService:IsRunning() and runService.Stepped or runService.RenderStepped
	table.insert(connections, signal:connect(function()
		frame = frame + 1
		if frame >= rain_Update_Period then
			local t = math.abs(workspace.CurrentCamera.CFrame.lookVector:Dot(rainDirection))
			local straightSequence = NumberSequence.new{
				numberSequenceKeypoint1;
				NumberSequenceKeypoint.new(rain_Transparency_T1, (1 - t)*straightLowAlpha + t, 0);
				NumberSequenceKeypoint.new(rain_Transparency_T2, (1 - t)*straightLowAlpha + t, 0);
				numberSequenceKeypoint2;
			}
			local topdownSequence = NumberSequence.new{
				numberSequenceKeypoint1;
				NumberSequenceKeypoint.new(rain_Transparency_T1, t*topdownLowAlpha + (1 - t), 0);
				NumberSequenceKeypoint.new(rain_Transparency_T2, t*topdownLowAlpha + (1 - t), 0);
				numberSequenceKeypoint2;
			}
			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
				for _,v in pairs(rainAttachments) do
					v.RainStraight.Transparency = straightSequence
					v.RainStraight.Rotation = straightRotation
					v.RainTopDown.Transparency = topdownSequence
				end
				if not disabled then
					local volume = 0
					if (not currentCeiling or workspace.CurrentCamera.CFrame.p.y <= currentCeiling) then
						local minDistance = rain_Volume_Scan_Radius
						local rayDirection = -rainDirection * rain_Scanheight
						for i = 1, #volumeScanGrid do
							if not raycast(Ray.new(workspace.CurrentCamera.CFrame * volumeScanGrid[i], rayDirection), true) then
								minDistance = volumeScanGrid[i].magnitude
								break
							end
						end
						volume = 1 - minDistance / rain_Volume_Scan_Radius
					end
					if math.abs(volume - volumeTarget) > .01 then
						volumeTarget = volume
						tweenService:Create(sound, TweenInfo.new(1), {Volume = volumeTarget}):Play()
					end
				end
			else
				emitter.RainStraight.Transparency = straightSequence
				emitter.RainStraight.Rotation = straightRotation
				emitter.RainTopDown.Transparency = topdownSequence
			end
			frame = 0
		end
		local center = workspace.CurrentCamera.CFrame.p
		local right = workspace.CurrentCamera.CFrame.lookVector:Cross(-rainDirection)
		right = right.magnitude > .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
		for i = 1, numSplashes do
			local splashAttachment = splashAttachments[i]
			local rainAttachment = rainAttachments[i]
			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
				splashAttachment.Position = position + normal * rain_Splash_Correction_Y
				splashAttachment.RainSplash:Emit(1)
				if inside then
					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
				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 #connections > 0 then
		for _,v in pairs(connections) do
			v:disconnect()
		end
		connections = {}
	end
end

local function disableSound(tweenInfo)
	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()
	emitter.RainStraight.Enabled = false
	emitter.RainTopDown.Enabled = false
	emitter.Size = min_Size
	if not disabled then
		disableSound(TweenInfo.new(rain_Sound_Fadeout_Time))
	end
end

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 {
		numberSequenceKeypoint1;
		NumberSequenceKeypoint.new(rain_Transparency_T1, opacity*rain_Splash_Alpha_Low + transparency, 0);
		NumberSequenceKeypoint.new(rain_Transparency_T2, opacity*rain_Splash_Alpha_Low + transparency, 0);
		numberSequenceKeypoint2;
	}
	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_Size * value
	intensityOccludedRain = math.ceil(rain_Occluded_Maxintensity * value)
	numSplashes = rain_Splash_Number * 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)

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()
	emitter.RainStraight.Enabled = true
	emitter.RainTopDown.Enabled = true
	emitter.Parent = workspace.CurrentCamera
	
	for i = 1, rain_Splash_Number do
		splashAttachments[i].Parent = workspace.Terrain
		rainAttachments[i].Parent = workspace.Terrain
	end
	
	if runService:IsRunning() then
		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
				disable()
			end
			tween:Destroy()
		end)
		tween:Play()
		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)
	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
		collisionList = nil
		collisionFunc = nil
	elseif mode == collisionMode.Blacklist then
		if typeof(param) == "Instance" then
			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}
			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
		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
		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
		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

Also some extra values ect needed for this to work.

image

This is maintained within the server script.

I’ve looked on other devforums for a hint at what might be the problem but can’t get it, possibly missing something out.

Any help is appreciated, thank you!

You may be able to do this:

for _, v in pairs(rain_Volume_Scan_Grid) do
local mul = (v * rain_Volume_Scan_Grid) -- (v * v) may work here
	table.insert(volumeScanGrid, mul)
end
1 Like

I think I see the issue (Take this with a grain of salt), you have all these values inside the table, but you aren’t specifying which one you want

1 Like

rain_volume_scan_grid is a table, so you can’t multiply it with v. I’m not sure what you want to put there, but it can’t be rain_volume_scan_grid.
You said this was a free model? Did the original work?

1 Like

as @DasKairo had said, you were multiplying it by the table itself, but not the values inside. I’m assuming you meant this:

for _, v in pairs(rain_Volume_Scan_Grid) do
	for _,v2 in pairs(rain_volume_Scan_Grid) do
		local mul = (v * v2)
		table.insert(volumeScanGrid, mul)
	end
end
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.