Roblox
Belajar Luau 07: Roblox Studio, Part, Properti, dan Event
Masuk ke Roblox Studio: hierarki Instance, membaca dan mengubah properti Part, membuat Part dengan script, event Touched, debounce, dan cooldown per pemain lewat kill brick, platform rapuh, dan pad penyembuh.

Mulai pelajaran ini, kode dijalankan di Roblox Studio (komputer Windows), bukan di terminal. Semua dasar Luau dari pelajaran 01–05 tetap berlaku. Yang baru adalah objek-objek Roblox dan event.
| Script | Isi | Diletakkan di |
|---|---|---|
| Script 1: properti Part | Membaca/mengubah properti, membuat Part dengan script, membangun tangga dengan loop | ServerScriptService |
| Script 2: kill brick | Event Touched, mendeteksi pemain, lava |
Di dalam Part "Lava" |
| Script 3: platform rapuh | Debounce, task.wait, efek memudar |
Di dalam Part "PlatformRapuh" |
| Script 4: pad penyembuh | Cooldown per pemain memakai dictionary | Di dalam Part "PadPenyembuh" |
Akhiran
.server.luaupada nama file artinya "Script biasa yang berjalan di server". Ini juga aturan penamaan Rojo, yang dipakai di pelajaran 14.
Konsep 1: semua di Roblox adalah Instance
Setiap benda di game (Part, Script, Folder, pemain, suara, UI) adalah Instance. Instance-instance itu tersusun seperti pohon, dan bisa dilihat di jendela Explorer:
game
├── Workspace ← semua yang TERLIHAT di dunia 3D
│ ├── Baseplate
│ ├── Lava (Part)
│ │ └── Script ← script.Parent = Lava
│ └── Tangga (Folder)
├── Players ← pemain yang sedang online
├── ReplicatedStorage ← barang yang dipakai server DAN client
├── ServerScriptService ← script server yang tidak menempel ke Part
└── StarterGui ← UI yang muncul di layar pemain
- Parent adalah "induk" (wadah) sebuah Instance, dan Children adalah isinya.
- Di dalam script,
scriptadalah script itu sendiri, danscript.Parentadalah objek tempat script itu diletakkan. workspacesama dengangame.Workspace.
Konsep 2: properti
Setiap Instance punya properti, misalnya Name, Size, Position, Color, Anchored, dan Transparency. Semuanya terlihat di jendela Properties saat objek dipilih. Properti yang bisa diubah di jendela Properties juga bisa diubah lewat script.
Ada beberapa tipe data baru khusus Roblox:
| Tipe | Contoh | Dipakai untuk |
|---|---|---|
Vector3 |
Vector3.new(4, 1, 4) |
Ukuran dan posisi (X, Y, Z) |
Color3 |
Color3.fromRGB(255, 0, 0) |
Warna |
Enum |
Enum.Material.Neon |
Pilihan tetap, seperti material atau bentuk |
Konsep 3: event
Event adalah sesuatu yang terjadi, misalnya Part disentuh, pemain masuk, atau tombol diklik. Kamu "berlangganan" sebuah event dengan :Connect(function). Function yang diberikan adalah callback dari pelajaran 04.
part.Touched:Connect(function(bagianYangMenyentuh)
print("Disentuh oleh", bagianYangMenyentuh.Name)
end)
Titik dua
:dipakai untuk memanggil method (function milik objek), misalnya:Connect(),:FindFirstChild(), atau:Destroy(). Titik.dipakai untuk properti dan event, misalnya.Nameatau.Touched.
Persiapan di Roblox Studio
- Buka Roblox Studio, lalu New → Baseplate.
- Buka menu View, lalu aktifkan Explorer, Properties, dan Output. Output adalah tempat hasil
printdan pesan error muncul.
Script 1: properti dan membuat Part
Langkah di Studio:
- Di tab Home, klik Part. Sebuah balok muncul di dunia.
- Di Explorer, klik kanan Part tersebut, pilih Rename, dan beri nama
BalokLatihan. Nama ini harus sama persis, termasuk huruf besar dan kecilnya. - Di Explorer, arahkan kursor ke ServerScriptService, klik +, lalu pilih Script.
- Hapus isi bawaannya, lalu tempel kode di bawah.
- Tekan Play (F5). Balok akan berubah warna dan sebuah tangga pelangi muncul. Periksa jendela Output.
Mengambil objek dan membaca properti
WaitForChild menunggu sampai objeknya ada. Ini lebih aman daripada workspace.BalokLatihan, karena saat game baru mulai, objek bisa belum selesai dimuat.
local balok = workspace:WaitForChild("BalokLatihan")
print("Nama:", balok.Name)
print("Ukuran:", balok.Size) -- Vector3, contoh: 4, 1, 2
print("Posisi:", balok.Position)
print("Tinggi (Y):", balok.Position.Y) -- ambil satu sumbu saja
print("Anchored?", balok.Anchored)
Mengubah properti
Hasilnya langsung terlihat di dunia 3D:
balok.Anchored = true -- tidak jatuh / terdorong
balok.Size = Vector3.new(6, 2, 6) -- lebar X, tinggi Y, panjang Z
balok.Position = Vector3.new(0, 5, -10) -- melayang 5 stud di atas tanah
balok.Color = Color3.fromRGB(255, 120, 0) -- oranye
balok.Material = Enum.Material.Neon -- menyala
balok.Transparency = 0.2 -- 0 = padat, 1 = tak terlihat
Membuat Part baru dengan Instance.new
local function buatBalok(posisi, warna)
local part = Instance.new("Part")
part.Name = "AnakTangga"
part.Size = Vector3.new(6, 1, 3)
part.Position = posisi
part.Color = warna
part.Anchored = true
-- Atur Parent PALING AKHIR. Begitu Parent diisi, Part muncul di dunia,
-- jadi lebih efisien kalau semua properti sudah diatur sebelumnya.
return part
end
Folder dan loop: membangun tangga pelangi
local folderTangga = Instance.new("Folder")
folderTangga.Name = "Tangga"
folderTangga.Parent = workspace
local JUMLAH_ANAK_TANGGA = 15
for i = 1, JUMLAH_ANAK_TANGGA do
-- Setiap anak tangga naik 1 stud dan maju 3 stud
local posisi = Vector3.new(15, i * 1, i * 3)
-- Warna pelangi: fromHSV(hue 0..1, saturasi, kecerahan)
local warna = Color3.fromHSV(i / JUMLAH_ANAK_TANGGA, 0.8, 1)
local anakTangga = buatBalok(posisi, warna)
anakTangga.Parent = folderTangga
end
GetChildren dan FindFirstChild
GetChildren mengembalikan array (pelajaran 05) berisi semua anak. FindFirstChild mencari anak berdasarkan nama, dan mengembalikan nil kalau tidak ada.
local semuaAnakTangga = folderTangga:GetChildren()
print("Jumlah anak tangga:", #semuaAnakTangga)
-- Buat anak tangga paling atas jadi "garis finish" emas
for _, part in ipairs(semuaAnakTangga) do
if part.Position.Y == JUMLAH_ANAK_TANGGA then
part.Name = "Finish"
part.Color = Color3.fromRGB(255, 215, 0)
part.Material = Enum.Material.Neon
end
end
local finish = folderTangga:FindFirstChild("Finish")
if finish then
print("Garis finish ada di ketinggian", finish.Position.Y)
end
Menghapus objek dengan :Destroy()
Contoh balok sementara yang hilang setelah 5 detik:
local sementara = buatBalok(Vector3.new(-12, 3, 0), Color3.fromRGB(255, 0, 0))
sementara.Name = "BalokSementara"
sementara.Parent = workspace
print("Balok merah akan hilang dalam 5 detik...")
task.wait(5)
sementara:Destroy()
print("Balok merah dihapus!")
Script 2: kill brick (lava)
Langkah di Studio:
- Buat Part baru, beri nama
Lava, dan atur ukurannya supaya pipih dan lebar. - Di Properties, centang Anchored supaya Part tidak jatuh.
- Arahkan kursor ke
Lavadi Explorer, klik +, lalu pilih Script. Script akan berada di dalam Lava. - Tempel kode di bawah, tekan Play, lalu injak lavanya.
-- script.Parent = objek tempat script ini berada, yaitu Part Lava
local lava = script.Parent
lava.Color = Color3.fromRGB(255, 60, 0)
lava.Material = Enum.Material.Neon
-- Function ini akan dipanggil Roblox SETIAP KALI ada yang menyentuh lava.
-- Parameter "bagian" adalah Part yang menyentuh, misalnya kaki pemain
-- ("LeftFoot"), bukan pemainnya langsung.
local function saatDisentuh(bagian)
-- Struktur karakter pemain di Workspace:
-- NamaPemain (Model) <- bagian.Parent
-- ├── Humanoid <- yang mengatur darah & gerakan
-- ├── Head
-- ├── LeftFoot <- bagian (yang menyentuh)
-- └── ...
local karakter = bagian.Parent
local humanoid = karakter:FindFirstChildOfClass("Humanoid")
-- Kalau tidak ada Humanoid, berarti yang menyentuh bukan pemain/NPC
-- (misalnya Part lain yang jatuh). Abaikan saja.
if humanoid then
humanoid.Health = 0
print(karakter.Name, "terjatuh ke lava!")
end
end
-- Hubungkan event Touched ke function di atas (callback, pelajaran 4)
lava.Touched:Connect(saatDisentuh)
Script 3: platform rapuh
Langkah di Studio: buat Part, beri nama PlatformRapuh, centang Anchored, lalu angkat sedikit dari tanah. Supaya ada tantangan, letakkan di atas lava. Tambahkan Script di dalamnya, tempel kode di bawah, lalu tekan Play dan berdiri di atasnya.
Debounce adalah "kunci" supaya kode tidak berjalan berkali-kali bersamaan. Touched bisa terpicu puluhan kali per detik (setiap kaki, setiap gerakan kecil). Tanpa debounce, efek memudar berjalan berulang kali secara tumpang tindih dan hasilnya kacau.
local platform = script.Parent
local WAKTU_MEMUDAR = 1 -- detik sampai platform hilang
local WAKTU_KEMBALI = 3 -- detik sampai platform muncul lagi
local LANGKAH = 10 -- berapa tahap efek memudar
local sedangBerjalan = false
local function saatDisentuh(bagian)
-- Kalau efek sedang berjalan, abaikan sentuhan baru
if sedangBerjalan then
return
end
local humanoid = bagian.Parent:FindFirstChildOfClass("Humanoid")
if not humanoid then
return
end
sedangBerjalan = true -- kunci
-- Memudar sedikit demi sedikit (loop, pelajaran 3)
for i = 1, LANGKAH do
platform.Transparency = i / LANGKAH
task.wait(WAKTU_MEMUDAR / LANGKAH)
end
platform.CanCollide = false -- pemain jatuh menembus platform
task.wait(WAKTU_KEMBALI)
platform.Transparency = 0
platform.CanCollide = true
sedangBerjalan = false -- buka kunci
end
platform.Touched:Connect(saatDisentuh)
Script 4: pad penyembuh dengan cooldown per pemain
Langkah di Studio: buat Part, beri nama PadPenyembuh, centang Anchored, lalu tambahkan Script di dalamnya. Untuk mengujinya kamu perlu terluka dulu: saat Play berjalan, buka View → Command Bar, ketik kode berikut (ganti NamaKamu dengan username Roblox-mu), lalu tekan Enter. Setelah itu injak pad penyembuh dan lihat bar darahmu naik.
workspace.NamaKamu.Humanoid.Health = 30
Script 3 memakai satu kunci untuk semua pemain. Di sini setiap pemain punya kuncinya sendiri, disimpan di dictionary (pelajaran 05). Kunci dictionary boleh berupa objek, bukan hanya teks.
local pad = script.Parent
local JUMLAH_PULIH = 25
local COOLDOWN = 2 -- detik sebelum pemain yang sama bisa sembuh lagi
local WARNA_SIAP = Color3.fromRGB(0, 255, 120)
local WARNA_DIPAKAI = Color3.fromRGB(80, 80, 80)
pad.Color = WARNA_SIAP
pad.Material = Enum.Material.Neon
-- sedangCooldown[karakterBudi] = true
-- sedangCooldown[karakterSiti] = nil (tidak sedang cooldown)
local sedangCooldown = {}
local function saatDisentuh(bagian)
local karakter = bagian.Parent
local humanoid = karakter:FindFirstChildOfClass("Humanoid")
if not humanoid then
return
end
-- Pemain ini masih cooldown? Abaikan.
if sedangCooldown[karakter] then
return
end
-- Darah sudah penuh? Tidak perlu disembuhkan.
if humanoid.Health >= humanoid.MaxHealth then
return
end
sedangCooldown[karakter] = true
-- Darah tidak boleh melebihi MaxHealth
humanoid.Health = math.min(humanoid.Health + JUMLAH_PULIH, humanoid.MaxHealth)
print(`{karakter.Name} disembuhkan, darah sekarang {math.floor(humanoid.Health)}`)
pad.Color = WARNA_DIPAKAI
task.wait(COOLDOWN)
pad.Color = WARNA_SIAP
sedangCooldown[karakter] = nil -- hapus dari dictionary = boleh sembuh lagi
end
pad.Touched:Connect(saatDisentuh)
Error yang sering muncul
| Pesan di Output | Artinya |
|---|---|
BalokLatihan is not a valid member of Workspace |
Nama Part salah ketik, atau Part belum ada |
Infinite yield possible on 'Workspace:WaitForChild("...")' |
WaitForChild menunggu objek yang tidak pernah muncul. Periksa ejaan namanya. |
attempt to index nil with 'Health' |
Kamu memakai sesuatu yang ternyata nil. Biasanya yang menyentuh Part bukan pemain. |
| Part jatuh atau hilang saat Play | Lupa mencentang Anchored |
Latihan
- Lava berkedip: ubah script lava supaya warnanya bergantian merah dan oranye setiap 0,5 detik. Pakai
while true dodan jangan lupatask.wait. - Lantai berduri: buat Part yang mengurangi darah sebanyak 20, bukan langsung membunuh, dengan debounce 1 detik supaya darah tidak langsung habis. Gabungkan ide dari script 2 dan 3.
- Tangga spiral: ubah loop di script 1 supaya tangganya berputar, misalnya dengan menghitung posisi memakai
math.cosdanmath.sin. Ini lebih menantang, jadi boleh minta petunjuk. - Obby mini: gabungkan semuanya menjadi lintasan pendek berisi lava di bawah, platform rapuh di atasnya, dan pad penyembuh di tengah jalan.
Kunci jawaban
Coba kerjakan sendiri dulu sebelum membaca bagian ini.
Latihan 1: lava berkedip
Tambahkan di paling bawah script lava, setelah baris lava.Touched:Connect(saatDisentuh):
local MERAH = Color3.fromRGB(255, 40, 0)
local ORANYE = Color3.fromRGB(255, 150, 0)
while true do
lava.Color = MERAH
task.wait(0.5)
lava.Color = ORANYE
task.wait(0.5)
end
Kenapa harus di paling bawah? while true tidak pernah selesai, jadi kode di bawahnya tidak akan pernah dijalankan. Kalau loop ini ditaruh di atas :Connect(...), event Touched tidak pernah terhubung dan lava tidak membunuh siapa pun.
Kalau loop terpaksa ada di tengah script, jalankan di "jalur" terpisah dengan task.spawn:
task.spawn(function()
while true do
lava.Color = Color3.fromRGB(255, 40, 0)
task.wait(0.5)
lava.Color = Color3.fromRGB(255, 150, 0)
task.wait(0.5)
end
end)
-- kode di sini TETAP dijalankan
Latihan 2: lantai berduri
Script di dalam Part bernama LantaiBerduri:
local lantai = script.Parent
local DAMAGE = 20
local COOLDOWN = 1
-- Cooldown PER PEMAIN (seperti pad penyembuh), supaya dua pemain
-- yang menginjak bersamaan sama-sama terkena damage
local sedangCooldown = {}
lantai.Touched:Connect(function(bagian)
local karakter = bagian.Parent
local humanoid = karakter:FindFirstChildOfClass("Humanoid")
if not humanoid or sedangCooldown[karakter] then
return
end
sedangCooldown[karakter] = true
humanoid:TakeDamage(DAMAGE)
task.wait(COOLDOWN)
sedangCooldown[karakter] = nil
end)
Kenapa TakeDamage, bukan humanoid.Health -= 20? Keduanya mengurangi darah, tetapi TakeDamage menghormati ForceField (perisai sementara yang biasanya muncul sebentar setelah respawn). Jadi pemain yang baru respawn tidak langsung terkena damage lagi.
Kesalahan umum: memakai satu debounce untuk semua pemain (local sedangCooldown = false). Akibatnya, selama Budi kena cooldown, Siti bisa berjalan di atas duri tanpa terluka.
Latihan 3: tangga spiral
Ganti bagian loop tangga di script 1:
local PUSAT = Vector3.new(30, 0, 0) -- titik tengah spiral
local JARI_JARI = 8
local SUDUT_PER_ANAK = math.rad(25) -- setiap anak tangga berputar 25 derajat
local JUMLAH = 20
for i = 1, JUMLAH do
local sudut = i * SUDUT_PER_ANAK
-- cos dan sin mengubah sudut menjadi posisi di lingkaran
local x = math.cos(sudut) * JARI_JARI
local z = math.sin(sudut) * JARI_JARI
local posisi = PUSAT + Vector3.new(x, i * 1.5, z)
local anakTangga = buatBalok(posisi, Color3.fromHSV(i / JUMLAH, 0.8, 1))
-- Putar balok supaya menghadap ke arah lingkaran
anakTangga.CFrame = CFrame.new(posisi) * CFrame.Angles(0, -sudut, 0)
anakTangga.Parent = folderTangga
end
Bayangkan jarum jam: cos memberi posisi kiri-kanan dan sin memberi posisi depan-belakang dari sebuah sudut. Dengan menaikkan sudut dan ketinggian sedikit demi sedikit, terbentuklah spiral. CFrame.Angles(0, -sudut, 0) memutar balok di sumbu Y (seperti gasing) supaya ujungnya mengikuti lengkungan.
Kalau spiralnya terlalu rapat untuk dilompati, perbesar JARI_JARI atau kecilkan SUDUT_PER_ANAK.
Latihan 4: obby mini
Latihan ini tanpa kode baru. Yang perlu diperiksa:
- Lava ada di bawah lintasan dan cukup lebar, sehingga pemain yang jatuh pasti mengenainya.
- Jarak antar platform rapuh bisa dilompati. Coba sendiri: lompatan normal sekitar 7–8 stud mendatar.
- Platform rapuh Anchored. Kalau tidak, ia langsung jatuh saat game dimulai.
- Pad penyembuh diletakkan setelah bagian yang sulit, sebagai hadiah.
- Ada SpawnLocation di awal lintasan.
Tips desain: mulai dengan lompatan yang mudah, lalu makin sulit. Pemain yang langsung gagal di 10 detik pertama biasanya keluar dan tidak kembali.
Discussion (0)
We store your optional name, your comment, and technical hashes (not your raw IP address) to prevent spam. A functional cookie lets you edit or delete your own comments from this browser. To request deletion, use the contact page.
No comments yet. Start the discussion.