Skip to content

Cơ bản về script ​

Game KHIM được lập trình bằng Luau, ngôn ngữ nhanh và an toàn Roblox làm từ Lua, cộng thêm bộ API gọn của riêng KHIM. Nếu bạn đã viết Lua, JavaScript hay Python, bạn sẽ đọc hiểu ngay.

Ba loại script ​

LoạiChạy ởDùng cho
ScriptGame server - một lầnChính game: máu, xu, điểm, vòng chơi, cửa, mọi thứ quan trọng
ClientScriptThiết bị của từng người chơi - mỗi máy một lầnPhím bấm, UI, camera, hiệu ứng chỉ một người thấy
ModuleNơi nó được requireCode và cài đặt dùng chung cho nhiều script

Thêm bằng Insert Object (chuột phải vào một dòng trong Hierarchy) hoặc menu Insert trên thanh trên cùng. Nhấp đúp để mở.

Script nằm ở đâu quyết định nó có chạy hay không:

  • Script chạy ở mọi nơi trừ StorageService và UI. Đặt logic game trong ServerService, nơi người chơi không bao giờ thấy, hoặc bên trong part nó điều khiển.
  • ClientScript chạy trên mọi người chơi trừ khi nằm trong ServerService hoặc StorageService. Đặt nó trong ClientService, hoặc bên trong UI nó điều khiển.
  • Module chạy lần đầu có thứ require nó. Module dùng chung để trong ReplicationService (shared trong script).

KHIM Engine làm mờ script không chạy được ở chỗ nó nằm, và tooltip nói vì sao.

Script đầu tiên ​

Chèn một Part, rồi chuột phải vào nó trong Hierarchy > Insert Object > Script. Mở script và gõ:

lua
local part = script.parent  -- part chứa script này

part.touched:connect(function(hit)
    local player = players.fromPart(hit)
    if player then
        print(player.name .. " đã chạm vào tôi!")
        part.color = rgb(255, 80, 80)
    end
end)

Bấm F5, đi vào part: nó chuyển đỏ và Console ghi ai đã chạm.

Ba quy tắc bao trọn cả API ​

  1. Thành viên viết camelCase: part.position, player.walkSpeed, button.clicked.
  2. Module dùng dấu chấm, đối tượng dùng dấu hai chấm: net.send(...), players.all() - nhưng part:tween(...), folder:find("Coin").
  3. Lựa chọn trong vài giá trị là một chuỗi: part.shape = "Ball", label.textAlign = "Center", input.onKey("E", fn).

Tìm đồ vật ​

Mọi thứ trong world là một đối tượng có name, parent và các con:

lua
local door = world.Door                 -- một con theo tên
local lamp = world.House.Kitchen.Lamp   -- sâu hơn
local tree = world:find("Big Tree")     -- tên có dấu cách
local shop = world:waitFor("Shop")      -- chờ tới khi nó có
local config = require(shared.Config)   -- một Module trong ReplicationService
worldMục World: mọi part người chơi thấy
sharedReplicationService
game.ServerService, game.StorageService, game.ClientServiceCác mục chứa khác
scriptScript này; script.parent là thứ chứa nó
players.meTrong ClientScript: người chơi sở hữu thiết bị đó

find(name) trả nil khi không có gì mang tên đó; waitFor(name) chờ nó (và cảnh báo sau 5 giây). Dùng waitFor trong ClientScript, nơi world tới từng phần một.

Sự kiện (event) ​

Những gì xảy ra là event. Nối (connect) một hàm vào event là hàm chạy mỗi lần event xảy ra:

lua
local connection = part.touched:connect(function(hit) print("bị chạm bởi", hit.name) end)
connection:disconnect()                        -- thôi lắng nghe

part.touched:once(function(hit) print("chỉ lần đầu") end)

local hit = part.touched:wait()                -- chờ lần tới, rồi chạy tiếp

Hay dùng: players.joined, players.left, part.touched, button.clicked, prompt.triggered, player.died, game.frame (mỗi khung hình, kèm thời gian từ khung trước).

Chờ và thời gian ​

lua
task.wait(2)                                    -- chờ 2 giây (không làm đứng game)
task.spawn(function() print("song song") end)   -- chạy một việc song song
task.delay(5, function() print("sau") end)      -- chạy một việc sau 5 giây
print(time())                                   -- số giây từ khi game bắt đầu

Vòng lặp phải có chờ

Script chạy quá một giây mà không chờ sẽ bị dừng. Mọi vòng while true do đều cần một task.wait() bên trong.

Giá trị ​

lua
local spot = vec3(0, 10, 0)              -- một vị trí hoặc hướng
local red = rgb(255, 0, 0)               -- màu, 0-255 (hoặc rgb("#ff0000"))
local sky = hsv(0.6, 0.5, 1)             -- màu theo sắc độ, độ bão hoà, độ sáng (0-1)
local where = transform.lookAt(vec3(0, 5, 10), vec3(0, 0, 0)) -- vị trí và hướng nhìn
local size = dim(0.5, 0, 0, 40)          -- UI: nửa chiều rộng, cao 40 điểm

Xem Kiểu giá trị.

Tạo đối tượng ​

lua
local ball = new("Part")
ball.shape = "Ball"
ball.size = vec3(2, 2, 2)
ball.position = vec3(0, 20, 0)
ball.anchored = false
ball.parent = world        -- chưa có cha thì chưa xuất hiện

local copy = world.Tree:clone()
copy.parent = world

ball:destroy()             -- biến mất, cùng mọi thứ bên trong
ball:destroyAfter(5)       -- biến mất sau 5 giây

new(className, parent) nhận cha làm đối số thứ hai luôn.

Di chuyển mượt ​

lua
local door = world.Door
door:tween({position = door.position + vec3(0, 8, 0)}, 1)                -- lên 8 unit trong 1 giây
door:tween({color = rgb(0, 255, 0), transparency = 0.5}, {time = 2, style = "Bounce"})

Part, đối tượng UI, Lighting và camera đều tween được. Tuỳ chọn: time, style ("Linear", "Sine", "Quad", "Cubic", "Quart", "Back", "Bounce", "Elastic"), direction ("In", "Out", "InOut"), repeats (-1 là mãi mãi), reverses, delay. Tween trả về một đối tượng có completed và cancel().

Module ​

Module trả về một giá trị - thường là một bảng - và mọi lần require đều nhận cùng một giá trị:

lua
-- Module "Config" trong ReplicationService
return {
    startingCoins = 50,
    swordDamage = 20,
}
lua
-- bất kỳ Script hay ClientScript nào
local Config = require(shared.Config)
print(Config.startingCoins)

Module chạy một lần trên mỗi server và một lần trên thiết bị của mỗi người chơi.

Trình soạn giúp bạn ​

  • Gợi ý khi gõ: sau . và : nó liệt kê những gì hợp ở đó - players. liệt kê joined, left, all...; trong players.joined:connect(function(player), player. liệt kê thành viên của người chơi. Ctrl Space để hỏi ở bất kỳ đâu.
  • Snippet: gõ touched, savedata hay whileloop ở đầu dòng - xem Snippet.
  • Rê chuột lên một tên để xem kiểu và công dụng.
  • Lỗi được gạch dưới ngay khi gõ, kèm "có phải ý bạn là": 'pirnt' is not defined; did you mean print?. Gõ sai thành viên lúc chạy cũng được báo: postion is not a valid member of Part; did you mean position?.
  • F12 trên world.Door.Hinge chọn Hinge đó trong Hierarchy.

Tên kiểu Roblox vẫn chạy ​

Nếu bạn biết Roblox, tên của nó vẫn chạy: game:GetService("Players"), Instance.new("Part"), Vector3.new, part.Position, :Connect, FindFirstChild, RemoteEvent và nhiều thứ khác. Tài liệu dùng tên của KHIM; trang Chuyển từ Roblox sang có bảng đối chiếu.

Tiếp theo ​