🎒 Item System

Lag et komplett system hvor spillere kan plukke opp epler som faller fra trær, og spise dem for å få helse tilbake!

Tools ProximityPrompt RemoteEvent ServerStorage Clone() Humanoid.Health

🎯 Mål for dette systemet

  • Lage et eple i verden som faller fra et tre etter tilfeldig tid.
  • Bruke ProximityPrompt så spilleren kan plukke opp eplet.
  • Gi spilleren et Tool (eple) som de kan holde i hånden.
  • La spilleren spise eplet for å få tilbake helse (+20 HP).
  • Bruke RemoteEvent for kommunikasjon mellom klient og server.
Resultat: Et komplett item-system med plukking, bruk, og effekt!

📦 Komplett oppsett - Oversikt

Før vi begynner, se på den komplette strukturen. Dette er det vi skal bygge i dette systemet:

ReplicatedStorage └─ EatApple (RemoteEvent) ServerStorage └─ Apple (Tool) ├─ Handle (Part) [Anchored=false, CanCollide=false, Shape=Ball] ├─ Crunch (Sound) [valgfritt] └─ LocalScript ServerScriptService └─ EatAppleHandler (Script) Workspace └─ AppleWorld (Part) [Anchored=true ved start] └─ Script
Enkelt forklart: Et eple faller fra et tre → spilleren plukker det opp → får et Tool → klikker for å spise → får helse!

🧱 Del 1: Lag eple-verktøyet (Tool)

Dette er malen som spilleren får når de plukker opp eplet.

1 Opprett Tool i ServerStorage

  1. Åpne ServerStorage i Explorer.

    Høyreklikk ServerStorage → Insert Object → Tool

    Navn: AppleTool

  2. Lag en Handle (Part) inne i AppleTool.

    VIKTIG: Den MÅ hete Handle (med stor H)

    Anchored: false

    CanCollide: false

    Shape: Ball

    Size: 0.7, 0.7, 0.7

    Color: Rød eller grønn (som et eple)

    Material: SmoothPlastic eller Neon

  3. (Valgfritt) Legg til en Sound i AppleTool for "crunch"-lyd.

    Navn: Crunch

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

2 LocalScript i AppleTool

Dette scriptet sender en beskjed til serveren når spilleren aktiverer Tool.

-- LocalScript under AppleTool
local tool = script.Parent
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local EatAppleEvent = ReplicatedStorage:WaitForChild("EatApple")

-- Debounce så vi ikke skyter mange ganger pr klikk
local canUse = true

local function updateTooltip()
	local stack = tool:GetAttribute("Stack") or 1
	tool.ToolTip = ("Eple x%d – klikk for å spise"):format(stack)
end

tool:GetAttributeChangedSignal("Stack"):Connect(updateTooltip)
updateTooltip()

tool.Activated:Connect(function()
	if not canUse then return end
	local stack = tool:GetAttribute("Stack") or 0
	if stack <= 0 then return end

	canUse = false
	local player = Players.LocalPlayer
	if not player then
		canUse = true
		return
	end

	-- Be server om å spise ett eple
	EatAppleEvent:FireServer()

	-- Kort lokal cooldown (matcher server-delay)
	task.delay(0.35, function()
		canUse = true
	end)
end)

tool.Equipped:Connect(function()
	game:GetService("StarterGui"):SetCore("SendNotification", {
		Title = "🍎 Eple";
		Text = "Klikk for å spise. Stacks: " .. (tool:GetAttribute("Stack") or 1);
		Duration = 2
	})
end)
Hva gjør denne koden? Når spilleren klikker med eplet, sendes en melding til serveren. Vi viser også en liten notifikasjon når eplet holdes i hånden.

🧱 Del 2: Kommunikasjon (RemoteEvent)

3 Opprett RemoteEvent

  1. Åpne ReplicatedStorage i Explorer.

    Høyreklikk ReplicatedStorage → Insert Object → RemoteEvent

    Navn: EatApple

Hvorfor RemoteEvent? LocalScript (klient) kan ikke endre spillerens helse direkte. Vi må sende en beskjed til serveren som gjør endringen.

🧱 Del 3: Server-side logikk

4 ServerScript i ServerScriptService

Dette scriptet lytter etter "spis eple"-beskjeden og gir spilleren helse.

-- ServerScriptService/EatAppleHandler.server.lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local EatAppleEvent = ReplicatedStorage:WaitForChild("EatApple")

EatAppleEvent.OnServerEvent:Connect(function(player)
	local char = player.Character
	if not char then return end
	local tool = char:FindFirstChild("Apple")
	if not tool then return end
	local humanoid = char:FindFirstChildOfClass("Humanoid")
	if not humanoid then return end

	local heal = 20
	humanoid.Health = math.min(humanoid.MaxHealth, humanoid.Health + heal)

	local handle = tool:FindFirstChild("Handle")
	if handle then
		local crunch = handle:FindFirstChild("Crunch")
		if crunch then crunch:Play() end
	end

	local stack = tool:GetAttribute("Stack") or 1
	stack -= 1
	tool:SetAttribute("Stack", stack)

	-- Vent litt slik at lyd/heal fullføres
	task.delay(0.5, function()
		if tool and tool.Parent and (tool:GetAttribute("Stack") or 0) <= 0 then
			tool:Destroy()
		end
	end)
end)
Hva gjør denne koden? Serveren sjekker at spilleren holder AppleTool, gir 20 helse, spiller crunch-lyd, og sletter eplet.

🧱 Del 4: Verdens-eple som faller

5 Lag eple i Workspace

  1. Sett inn en Part i Workspace.

    Navn: AppleWorld (eller valgfritt)

    Anchored: true (starter forankret)

    CanCollide: true

    Shape: Ball

    Size: 1, 1, 1

    Color: Rød eller grønn

    Position: Plasser høyt oppe i et tre

  2. Legg til et Script inne i denne Part.

6 Script for å falle og gi Tool

-- Script under verdens-eplet (Part) i Workspace
local Eple = script.Parent
local ServerStorage = game:GetService("ServerStorage")

-- La eplet falle etter 10–600 sek
local ventetid = math.random(10, 10 * 60)
task.wait(3)
Eple.Anchored = false

-- Prompt
local prompt = Instance.new("ProximityPrompt")
prompt.ActionText = "Plukk opp eple"
prompt.ObjectText = "Eple"
prompt.HoldDuration = 0
prompt.MaxActivationDistance = 12
prompt.Parent = Eple

local DEFAULT_MAX = 20
local DEFAULT_STACK = 1
local pickedUp = false -- server-globalt flagg

local function ensureAttributes(tool)
	if tool:GetAttribute("MaxStack") == nil then tool:SetAttribute("MaxStack", DEFAULT_MAX) end
	if tool:GetAttribute("Stack") == nil then tool:SetAttribute("Stack", DEFAULT_STACK) end
end

local function findAppleTool(player)
	local char = player.Character
	if char then
		local t = char:FindFirstChild("Apple")
		if t then return t end
	end
	return player.Backpack:FindFirstChild("Apple")
end

local function giveTool(player)
	-- Sjekk og lås umiddelbart
	if pickedUp then return end
	pickedUp = true
	prompt.Enabled = false -- blokker ekstra triggers

	local template = ServerStorage:FindFirstChild("Apple")
	if not template then
		warn("Apple mangler i ServerStorage")
		return
	end

	local existing = findAppleTool(player)
	if existing then
		ensureAttributes(existing)
		local stack = existing:GetAttribute("Stack") or DEFAULT_STACK
		local max = existing:GetAttribute("MaxStack") or DEFAULT_MAX
		if stack < max then
			existing:SetAttribute("Stack", stack + 1)
		else
			-- kan vise beskjed her
		end
	else
		local tool = template:Clone()
		ensureAttributes(tool)
		tool.Parent = player.Backpack
	end

	-- Fjern delen trygt
	task.defer(function()
		if Eple and Eple.Parent then
			Eple:Destroy()
		end
	end)
end

prompt.Triggered:Connect(giveTool)
Hva gjør denne koden? Eplet venter 10 sekunder til 10 minutter, faller ned, lager en "plukk opp"-knapp, og gir spilleren et Tool når de trykker.

🧩 Slik fungerer systemet - enkelt forklart!

  1. Eplet venter: Det ligger i et tre og teller ned (10 sek til 10 min)
  2. Eplet faller: Når tiden er ute, slippes eplet og faller til bakken
  3. Du ser en knapp: Når du går nær eplet, ser du "Plukk opp eple" (ProximityPrompt)
  4. Du trykker E: Serveren gir deg en kopi av AppleTool i ryggsekken din
  5. Du holder eplet: Velg eplet fra inventory - det dukker opp i hånden din
  6. Du klikker: LocalScript sender melding til serveren: "Jeg vil spise!"
  7. Du blir frisk: Serveren gir deg +20 helse, spiller "crunch"-lyd
  8. Eplet forsvinner: Etter 0.4 sekunder slettes Tool fra spillet
Viktig å forstå: LocalScript (på din PC) kan ikke endre helse direkte - det må serveren gjøre! Derfor bruker vi RemoteEvent til å sende beskjed.

🧪 Mini-oppgaver

  • Endre helse-boost fra 20 til 30.
  • Lag flere epler på forskjellige steder.
  • Endre venteTid til math.random(5, 30) for raskere testing.
  • Lag en "gylden eple" som gir 50 helse.
  • Legg til en ParticleEmitter på eplet for en "magisk" effekt.

🚀 Videreutvikling

  • Lag et "eple-tre" som respawner nye epler automatisk.
  • Legg til debounce så spilleren ikke kan spise flere epler samtidig.
  • Vis en UI-melding når spilleren spiser eplet.
  • Lag et "rotne eple" som tar bort helse i stedet.
  • Tell hvor mange epler spilleren har spist med en Leaderboard.

🛠️ Feilsøking

"AppleTool is not a valid member of ServerStorage"
Sjekk at Tool heter nøyaktig AppleTool (samme store/små bokstaver) og ligger i ServerStorage.
"Handle is not a valid member of Tool"
Part-en inne i Tool MÅ hete Handle (med stor H). Hvis den heter noe annet, vil ikke Tool fungere.
Eplet faller ikke: Sjekk at scriptet ligger inne i eplet (Part), og at Anchored starter som true.
ProximityPrompt vises ikke: Vent til eplet har falt. Prompten lages først etter at Anchored er satt til false.
Helse endrer seg ikke: Sjekk at EatApple RemoteEvent ligger i ReplicatedStorage og har riktig navn.

📝 Viktige konsepter i dette systemet

  • Tool - Et objekt spilleren kan holde i hånden
  • Handle - Den synlige delen av et Tool (MÅ hete "Handle")
  • ProximityPrompt - Viser en melding når spilleren er nær et objekt
  • RemoteEvent - Kommunikasjon mellom klient (LocalScript) og server (Script)
  • Clone() - Lager en kopi av et objekt
  • ServerStorage - Lagring av maler/templates som bare serveren ser
  • Backpack - Spillerens inventory hvor Tools ligger
🏠 Tilbake til Roblox Oversikt