💰 Wallet og Coin System

Lag et komplett system hvor spillere kan samle mynter, se saldoen sin, og bruke myntene i en butikk!

IntValue Touched Event RenderStepped Folder LocalScript

🎯 Mål for dette systemet

  • Lage en wallet som holder oversikt over spillerens mynter.
  • Vise mynt-saldoen i UI som oppdateres i sanntid.
  • Skape coins i verdenen som roterer og bobber.
  • La spillere plukke opp coins ved å gå på dem.
  • Gi lydeffekter og partikler når coins plukkes opp.
Resultat: Spillere kan samle mynter og se saldoen sin i UI!

📦 Komplett oppsett - Oversikt

Dette er strukturen vi skal bygge i dette systemet:

ServerScriptService └─ Wallet (Script) Workspace ├─ coins (Folder) │ └─ Coin1 (Part) [Anchored=true] │ ├─ Script (coin pickup) │ ├─ Coin_collect (Sound) [valgfritt] │ └─ ParticleEmitter [valgfritt] StarterPlayer └─ StarterPlayerScripts └─ AnimateCoins (LocalScript) StarterGui └─ ScreenGui └─ coinsLabel (TextLabel) └─ LocalScript
Enkelt forklart: Wallet opprettes automatisk → coins vises i verden → spiller plukker opp → UI oppdateres!

🧱 Del 1: Wallet System

Først må vi lage en wallet som holder oversikt over spillerens mynter.

1 Opprett Wallet Script

  1. Åpne ServerScriptService i Explorer.

    Høyreklikk ServerScriptService → Insert Object → Script

    Navn: Wallet

  2. Lim inn følgende kode:
    local Players = game:GetService("Players")
    
    local function ensureWallet(player)
    	local wallet = player:FindFirstChild("wallet")
    	if not wallet then
    		wallet = Instance.new("Folder")
    		wallet.Name = "wallet"
    		wallet.Parent = player
    	end
    
    	local coins = wallet:FindFirstChild("coins")
    	if not coins then
    		coins = Instance.new("IntValue")
    		coins.Name = "coins"
    		coins.Value = 0
    		coins.Parent = wallet
    	end
    end
    
    Players.PlayerAdded:Connect(function(player)
    	ensureWallet(player)
    end)
⚠️ Viktig: Dette scriptet kjører på serveren og oppretter automatisk en wallet for hver spiller som blir med i spillet.

🧱 Del 2: Coin UI

Nå skal vi lage en enkel UI som viser hvor mange mynter spilleren har.

1 Opprett Coin UI

  1. Åpne StarterGui i Explorer.

    Høyreklikk StarterGui → Insert Object → ScreenGui

    Navn: CoinUI

  2. Legg til en TextLabel i ScreenGui.

    Høyreklikk CoinUI → Insert Object → TextLabel

    Navn: coinsLabel

    Position: UDim2.new(0, 20, 0, 20)

    Size: UDim2.new(0, 200, 0, 50)

    BackgroundTransparency: 1

    Text: Coins: 0

    TextScaled: true

    TextColor3: White

  3. Legg til en LocalScript i coinsLabel.

    Høyreklikk coinsLabel → Insert Object → LocalScript

  4. Lim inn følgende kode i LocalScript:
    -- StarterGui -> ScreenGui -> coinsLabel -> LocalScript
    
    local player = game.Players.LocalPlayer
    local coins = player:WaitForChild("wallet"):WaitForChild("coins")
    local textLable = script.Parent
    
    local function updateCoins()
    	textLable.Text = "Coins: " .. coins.Value
    end
    
    updateCoins()
    
    coins.Changed:Connect(updateCoins)
✅ Ferdig! Nå vil UI automatisk oppdatere seg hver gang spilleren får eller bruker mynter.

🧱 Del 3: Coin Collection

Nå skal vi lage coins som spillere kan plukke opp ved å gå på dem.

1 Opprett Coins Folder

  1. Åpne Workspace i Explorer.

    Høyreklikk Workspace → Insert Object → Folder

    Navn: coins

2 Opprett Coin Part

  1. Legg til en Part i coins-folderen.

    Høyreklikk coins → Insert Object → Part

    Navn: Coin1

    Anchored: true

    CanCollide: false

    Size: 2, 0.4, 2

    Color: Gull eller sølv

    Material: SmoothPlastic eller Metal

  2. (Valgfritt) Legg til en Sound for pickup-lyd.

    Høyreklikk Coin1 → Insert Object → Sound

    Navn: Coin_collect

    SoundId: Lim inn en lyd-ID (f.eks. fra Roblox Library)

  3. (Valgfritt) Legg til en ParticleEmitter for visuell effekt.

    Høyreklikk Coin1 → Insert Object → ParticleEmitter

    Color: Gull eller sølv

  4. Legg til en Script i Coin1.
    -- ServerScript under coin-Part
    local coin = script.Parent
    local COIN_VALUE = 50
    
    -- Valgfritt: hvis lyden ligger som barn av coinen (f.eks. "Coin_collect")
    local soundTemplate = coin:FindFirstChild("Coin_collect")
    
    local SoundService = game:GetService("SoundService")
    local Debris = game:GetService("Debris")
    
    local taken = false
    
    local function onTouch(otherPart)
    	if taken then return end
    
    	local character = otherPart.Parent
    	local player = game.Players:GetPlayerFromCharacter(character)
    	if not player then return end
    
    	-- Finn wallet/Coins (tilpass hvis du bruker leaderstats)
    	local wallet = player:FindFirstChild("wallet")
    	if not wallet then return end
    	local coins = wallet:FindFirstChild("coins")
    	if not coins then return end
    	
    	print("wallet og coins er funnet")
    
    	-- Lås umiddelbart så vi ikke kan plukke dobbelt
    	taken = true
    	coin.CanTouch = false
    
    	-- Gi verdi
    	coins.Value += COIN_VALUE
    
    	-- Spill lyd ETTER at vi har klonet den til SoundService
    	if soundTemplate then
    		local s = soundTemplate:Clone()
    		s.Parent = SoundService
    		s:Play()
    
    		-- Rydd opp automatisk etter at lyden er ferdig (med litt margin)
    		local ttl = (s.TimeLength > 0) and (s.TimeLength + 0.5) or 2
    		Debris:AddItem(s, ttl)
    	end
    
    	-- Emit partikler KUN nå
    	for _, d in ipairs(coin:GetDescendants()) do
    		if d:IsA("ParticleEmitter") then
    			-- Bare én burst
    			d:Emit(10)
    		end
    	end
    
    
    	-- FÅ COINEN BORT MED EN GANG (visuelt og fysisk)
    	coin.Transparency = 1
    	coin.CanCollide = false
    	coin.CanQuery = false
    	coin.CanTouch = false
    	
    	wait(2)
    
    	-- Slett coinen helt (lyden fortsetter siden den er i SoundService)
    	coin:Destroy()
    end
    
    coin.Touched:Connect(onTouch)
⚠️ Viktig: Coinen forsvinner etter 2 sekunder for å gi tid til lyd og partikler.

🧱 Del 4: Coin Animation

La oss gjøre coins mer levende ved å la dem rotere og bobbe!

1 Opprett AnimateCoins Script

  1. Åpne StarterPlayerStarterPlayerScripts i Explorer.

    Høyreklikk StarterPlayerScripts → Insert Object → LocalScript

    Navn: AnimateCoins

  2. Lim inn følgende kode:
    -- LocalScript: StarterPlayer -> StarterPlayerScripts
    -- Roterer og bobber alle coins i workspace.coins
    
    local RunService = game:GetService("RunService")
    
    -- === Oppsett ===
    local FOLDER_NAME     = "coins"  -- mappe i Workspace
    local ROTATION_SPEED  = 90       -- grader per sekund
    local FLOAT_HEIGHT    = 0.5      -- bob-amplitude (meter)
    local FLOAT_SPEED     = 2        -- bob-hastighet (Hz ~ svingninger/sek)
    
    -- Hvis mesh-aksen er "liggende", kan du rotere mynten fast én gang her:
    -- Sett til CFrame.Angles(0,0,0) hvis du ikke trenger dette.
    local MESH_FIX = CFrame.Angles(0, 0, 0) -- evt. CFrame.Angles(math.rad(90), 0, 0)
    
    -- === Internt lager ===
    -- [BasePart] = { basePos = Vector3, baseRot = CFrame (valgfri), phase = number }
    local animated = {}
    
    -- Finn visningspart for en coin (Part direkte eller PrimaryPart/første BasePart i Model)
    local function getDisplayPart(inst: Instance): BasePart?
    	if inst:IsA("BasePart") then
    		return inst
    	elseif inst:IsA("Model") then
    		if inst.PrimaryPart then
    			return inst.PrimaryPart
    		end
    		return inst:FindFirstChildWhichIsA("BasePart", true)
    	end
    	return nil
    end
    
    -- Legg til én coin
    local function addCoin(inst: Instance)
    	local part = getDisplayPart(inst)
    	if not part or animated[part] then return end
    
    	part.Anchored = true -- stabil animasjon uten fysikk
    
    	animated[part] = {
    		basePos = part.Position,                 -- posisjon i verden
    		baseRot = (part.CFrame - part.Position), -- opprinnelig tilt/roll (valgfri)
    		phase   = math.random() * math.pi * 2,   -- desynk bobbing
    	}
    end
    
    -- Fjern coin som forsvinner
    local function removeCoin(inst: Instance)
    	if inst:IsA("BasePart") and animated[inst] then
    		animated[inst] = nil
    	elseif inst:IsA("Model") then
    		for part, _ in pairs(animated) do
    			if part:IsDescendantOf(inst) then
    				animated[part] = nil
    			end
    		end
    	end
    end
    
    -- Finn/vent på mappen
    local coinsFolder = workspace:WaitForChild(FOLDER_NAME)
    
    -- Init: legg til alle nåværende coins
    for _, d in ipairs(coinsFolder:GetDescendants()) do
    	addCoin(d)
    end
    
    -- Reager på endringer i mappen
    coinsFolder.DescendantAdded:Connect(addCoin)
    coinsFolder.DescendantRemoving:Connect(removeCoin)
    
    -- === Animasjonsloop ===
    local t = 0
    RunService.RenderStepped:Connect(function(dt)
    	t += dt
    	local angle = math.rad(ROTATION_SPEED) * t
    
    	for part, info in pairs(animated) do
    		if part and part.Parent then
    			-- Bob i verdens Y
    			local y = math.sin(t * FLOAT_SPEED + info.phase) * FLOAT_HEIGHT
    
    			-- Roter rundt verdens Y, og (valgfritt) gjenbruk opprinnelig tilt + mesh-fix
    			part.CFrame =
    				CFrame.new(info.basePos + Vector3.new(0, y, 0)) -- pos+bob i verden
    				* CFrame.Angles(0, angle, 0)                    -- ren spin rundt Y
    				* info.baseRot                                   -- bevar tilt (kan fjernes)
    				* MESH_FIX                                       -- fast korrigering (valgfritt)
    		else
    			animated[part] = nil
    		end
    	end
    end)
    
    print("[CoinsAnim] Aktiv – roterer og bobber coins i workspace." .. FOLDER_NAME)
✅ Ferdig! Nå vil alle coins i workspace.coins rotere og bobbe automatisk!

🧪 Test systemet

  1. Start spillet ved å trykke Play i Roblox Studio.
  2. Du skal se en wallet i spilleren med 0 coins.
  3. UI skal vise "Coins: 0".
  4. Gå til en coin og plukk den opp.
  5. UI skal oppdatere til "Coins: 50" (eller verdien du satte).
  6. Coinen skal rotere og bobbe.
  7. Du skal høre lyd og se partikler når du plukker opp coinen.
🎉 Gratulerer! Du har nå et komplett wallet og coin system!

📚 Konsepter du har lært

  • IntValue: En verdi som kan lagre heltall (brukes for coins).
  • Folder: En beholder for å organisere objekter (wallet).
  • Touched Event: Skjer når en del berører noe annet.
  • RenderStepped: Kjører hver frame for animasjoner.
  • LocalScript: Kjører kun på klienten (spillerens maskin).
  • SoundService: Tjeneste for å spille lyder på tvers av spillet.
  • Debris: Tjeneste for å automatisk slette objekter etter en viss tid.
  • ParticleEmitter: Skaper partikkeleffekter.

🚀 Neste steg

Nå som du har et wallet og coin system, kan du:

  • Lage en 🛒 Shop System hvor spillere kan bruke myntene sine!
  • Legge til forskjellige typer coins med forskjellige verdier.
  • Lage power-ups som koster mynter.
  • Lagre mynter i DataStore så de beholdes mellom sesjoner.