I am creating a coin spawn system, and different types of them. The problem is in the line function createDiamondCoin:SpawnCoins(player) which is nil, so nothing works.
-- Services
local players = game:GetService("Players")
local replicatedStorage = game:GetService("ReplicatedStorage"):WaitForChild("SpawnCoinsSystemV2")
-- Variables
local storageCoins = {} -- Table for storing coins
-- Events
local playLocalSoundTouchedCoinEvent = replicatedStorage:WaitForChild("Events"):WaitForChild("PlayLocalSoundTouchedCoin")
-- Modules
local animationCoinModule = require(replicatedStorage:WaitForChild("AnimationCoinModule"))
local leaderstatsModule = require(replicatedStorage:WaitForChild("LeaderstatsModule"))
-- Custom coin data types
type coinsType = {
name: string,
typeCoin: string,
rarity: number,
value: number,
}
-- Initialize special type for special coins
type diamondCoins = coinsType & {
specialAbility: string?
}
-- Function to create coins
function storageCoins:CreateCoins(name: string, typeCoin: string, rarity: number, value: number): coinsType
-- Table with type coinsType
local coin: coinsType = {
name = name,
typeCoin = typeCoin,
rarity = rarity,
value = value
}
-- Set metatable
setmetatable(coin, { __index = self })
-- Function to spawn coins
function storageCoins:SpawnCoins(player: Player, specialCoin: string): coinsType
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:FindFirstChildOfClass("Humanoid")
-- Check for player's humanoid
if character and humanoid then
local spawnCoinsPart = workspace:WaitForChild("SpawnCoinsPart"):FindFirstChild("SpawnCoinsPlatform")
local offset = 5 -- Offset for margin
-- Get the part size range for spawning coins
local minX = spawnCoinsPart.Position.X - spawnCoinsPart.Size.X / 2 + offset
local maxX = spawnCoinsPart.Position.X + spawnCoinsPart.Size.X / 2 - offset
local minZ = spawnCoinsPart.Position.Z - spawnCoinsPart.Size.Z / 2 + offset
local maxZ = spawnCoinsPart.Position.Z + spawnCoinsPart.Size.Z / 2 - offset
local minY = spawnCoinsPart.Position.Y + spawnCoinsPart.Size.Y / 2
-- Create region
local region3 = Region3.new(Vector3.new(minX, minY, minZ), Vector3.new(maxX, minY, maxZ))
-- Get the minimum and maximum points of region3
local min = region3.CFrame.Position - (region3.Size / 2)
local max = region3.CFrame.Position + (region3.Size / 2)
-- Calculate center and size of Region3
local center = (min + max) / 2
local size = max - min
-- Visualize region
local part = Instance.new("Part", workspace)
part.Name = "VisualizationPartRegion3"
part.Position = center
part.Size = size
part.Color = Color3.fromRGB(0, 170, 0)
part.Transparency = .5
part.Anchored = true
part.CanCollide = false
print(region3)
-- Loop to spawn coins within region3
local folder = Instance.new("Folder", workspace)
folder.Name = "CollectionCoinsFolder"
local currentCoin = 1
-- Overlapping function
local function overlappingFunction(position: Vector3, orientation: CFrame, ...: MeshPart)
for _, _coin in ipairs({...}) do
-- Get position and orientation of the current coin
local coinPosition = _coin.Position
local coinOrientation = _coin.CFrame - _coin.Position
-- Calculate distance between coin centers
local distance = (coinPosition - position).Magnitude
-- Calculate coin radius
local coinRadius = _coin.Size.Magnitude / 2
-- Check for overlap considering radius
if distance <= coinRadius then
local deltaOrientation = orientation:ToObjectSpace(coinOrientation)
if deltaOrientation.Position.Magnitude <= coinRadius then
return true
end
end
end
return false
end
-- Randomized coin spawn loop
for _, value: MeshPart in pairs(replicatedStorage:GetChildren()) do
if value:IsA("MeshPart") and value.Name == "Coin" then
repeat
-- Function for generating random rotation
local function randomRotationObject(minY, maxY)
return math.random() * (maxY - minY) + minY
end
-- Create rotation matrix
local function randomCFrame(minY, maxY)
return CFrame.Angles(0, randomRotationObject(minY, maxY), 0)
end
-- Randomize coin positions
local randomX = math.random(minX, maxX)
local randomY = math.random(minY, minY)
local randomZ = math.random(minZ, maxZ)
-- Results of calculations
local randomPosition = Vector3.new(randomX, randomY + 1, randomZ)
local randomRotation = randomCFrame(0, math.rad(360))
-- Clone coin
local newCoin = value:Clone()
newCoin.Parent = folder
newCoin.Name = "ClonedCoin" .. currentCoin
newCoin.Position = randomPosition
newCoin.Transparency = 0
newCoin.CanCollide = false
newCoin.CanQuery = true
newCoin.CanTouch = true
newCoin.CFrame *= randomRotation
currentCoin = currentCoin + 1
print(newCoin.Name)
table.insert(self, newCoin)
until currentCoin or not overlappingFunction(randomPosition, randomRotation, table.unpack(self))
print("Were created: " .. #self .. " coins")
end
end
else
warn("The player does not have Humanoid")
end
print("Spawning coins for player:", player.Name)
return self
end
return self
end
-- Spawn special type of coins
function storageCoins:DiamondSpawnCoins(): diamondCoins
local createDiamondCoin = self:CreateCoins("DiamondCoin", "Special", 30, 4)
print(table.unpack(self)) -- nil
print(createDiamondCoin) -- index table
-- Inherit or override SpawnCoins function
function createDiamondCoin:SpawnCoins(player)
-- Call base implementation
if self.__index and self.__index.SpawnCoins then
self.__index:SpawnCoins(player, "DiamondCoin") -- Call common coin spawning logic
else
warn("11111111111")
end
self.specialAbility = "TestString"
print("Spawn diamonds for player:", player.Name)
end
return createDiamondCoin
end
-- Function to handle coin touch event
local function onTouchedCoin(coin: MeshPart, player: Player)
playLocalSoundTouchedCoinEvent:FireClient(player, true)
end
-- Loop to find coins
for _, index: MeshPart in ipairs(workspace:GetDescendants()) do
if index:IsA("MeshPart") and string.match(index.Name, "^ClonedCoin%d+$") then
index.Touched:Connect(function(hit: BasePart)
if hit.Parent and hit:FindFirstChildOfClass("Humanoid") then
local player = players:GetPlayerFromCharacter(hit.Parent)
if player then
onTouchedCoin(index, player)
end
end
end)
end
end
-- Event handler
players.PlayerAdded:Connect(function(player)
local specialCoin = storageCoins:DiamondSpawnCoins()
specialCoin:SpawnCoins(player)
end)
