Skip to content

Vật lý và khớp nối ​

KHIM mô phỏng part trên game server (và trong Play của KHIM Engine). Một unit bằng một stud; trọng lực 196,2 unit/s², như Roblox.

Neo hay thả ​

  • Part neo (anchored) đứng yên tuyệt đối. Sàn, tường, nhà cửa.
  • Part thả (anchored = false) rơi, lăn, bị đẩy và va đập. Thùng gỗ, bóng, mảnh vỡ.
lua
local crate = world.Crate
crate.anchored = false
crate:applyImpulse(vec3(0, 500, -300))   -- một cú đẩy, chia cho khối lượng của nó
crate.velocity = vec3(0, 50, 0)          -- hoặc đặt vận tốc

Vật liệu và khối lượng ​

Part nặng bằng thể tích nhân mật độ vật liệu, và vật liệu quyết định độ bám và độ nảy:

Vật liệuMật độMa sátĐộ nảy
Plastic, Neon0.70.50.1
Smooth0.70.30.1
Wood0.350.60.05
Glass2.40.250.2
Metal7.80.40.05
Grass0.90.650.05
Brick1.90.750.05
Concrete2.40.70.03
Sand1.60.850
Rock2.70.650.05
Water1.00.10
Leaves0.30.60.02

Vì vậy cùng một cú đẩy làm một part Metal lớn nhúc nhích ít hơn nhiều so với một part Wood nhỏ.

Nhóm va chạm ​

Mỗi part thuộc một nhóm va chạm (part.group, ban đầu là "Default"). Các nhóm quyết định thứ gì đi xuyên qua thứ gì:

lua
local door = world.VipDoor
door.group = "VipDoor"
physics.collide("VipDoor", "Players", false)   -- người chơi đi xuyên qua; thùng gỗ vẫn đụng vào

print(physics.collides("VipDoor", "Players"))  -- false
  • Có sẵn: Default, Players (mọi nhân vật) và Ragdoll. Một world đặt thêm được 13 nhóm của riêng nó (mỗi tên tối đa 23 ký tự).
  • physics.collide(a, b, false) với a == b làm các part trong cùng nhóm đi xuyên nhau.
  • touched vẫn chạy với các part không va chạm, nên cửa VIP vẫn biết ai đã đi qua.

Trong KHIM Engine bạn đặt bảng này không cần code: Inspector của part > Behavior > CollisionGroup > Which groups collide... (hoặc Insert > Collision groups) - một bảng ô tick.

Hàn (weld) ​

Weld giữ hai part dính làm một. KHIM Engine giữ weld giữa các part dựng cùng nhau, và clone() của một Model giữ chúng. Các part đã hàn không va chạm với nhau.

Khớp nối (joint) ​

Khớp nối đặt trong part chuyển động và trỏ tới part nó nối vào (part1):

KhớpLàm gìVí dụ
HingeXoay quanh một trụcCửa, bánh xe, cần gạt
SliderTrượt dọc một trụcThang máy, ngăn kéo, piston
BallJointXoay mọi hướng quanh một điểmĐèn treo trên xích
SpringKéo về một độ dài nghỉGiảm xóc xe, bạt nhún
RopeGiữ khoảng cách không quá một độ dàiXích đu, móc cần cẩu

Trong KHIM Engine: chọn part sẽ được nối vào, Ctrl-bấm part chuyển động, rồi chèn khớp (Insert Object > Joints). Inspector đặt part kia, điểm neo, trục, giới hạn và motor.

Thành viên ​

Thành viên
part1Part được nối vào
anchor, axisvec3 trong không gian part của chính nó
enabledBật hay tắt
limited, lower, upperHinge: độ; Slider: unit
motor, speed, forceTự quay/trượt: độ hoặc unit mỗi giây, với lực tối đa force
angle (Hinge), offset (Slider)Đã xoay / trượt bao nhiêu (chỉ đọc)
length, stiffness, dampingSpring và Rope (length cho cả hai)
lua
-- Bệ xoay trên trụ (bệ không neo: khớp nối chỉ di chuyển part thả)
local spinner = new("Hinge", world.Platform)
spinner.part1 = world.Post
spinner.motor = true
spinner.speed = 45        -- độ mỗi giây
spinner.force = 100000

-- Cổng dựng trong KHIM Engine: giới hạn 0 tới 90, mở bằng một nút bấm
local gate = world.Gate.Hinge
world.Button.Clickable.clicked:connect(function()
    gate.motor = true
    gate.speed = 60       -- mở tới chốt 90 độ và giữ ở đó
end)

Khớp nối hoạt động trên server. ClientScript đọc được nhưng không làm gì di chuyển bằng chúng.

Lực đẩy (mover) ​

Đặt vào một part thả để đẩy nó:

MoverLàm gìThành viên
MoverĐẩy nó đi với một vận tốc, giữ nó chống lại trọng lực: bệ di động, dronevelocity, strength, relative
SpinnerLàm nó quay: quạt, bánh xe lănspin (radian mỗi giây quanh mỗi trục), strength, relative
ThrusterĐẩy bằng một lực đều: tên lửa, gióforce, relative
lua
local drone = new("Mover", world.Drone)
drone.velocity = vec3(0, 0, -10)   -- bay ngang 10 unit mỗi giây

relative = true làm véc-tơ xoay theo part (mặc định của Thruster: tên lửa đẩy theo hướng mũi nó).

Di chuyển part không cần vật lý ​

Với bệ và cửa cần đi đúng một đường, Motion (không cần code) hoặc tween đơn giản hơn vật lý:

lua
world.Lift:tween({position = world.Lift.position + vec3(0, 20, 0)}, {time = 4, reverses = true, repeats = -1})

Nhân vật đứng trên part đang di chuyển - tween, khớp nối, đang xoay - được chở theo.

Raycast ​

lua
local hit = world:raycast(origin, direction)   -- part đầu tiên dọc đường thẳng, hoặc nil
if hit then print(hit.part, hit.position, hit.normal, hit.distance) end

Độ dài của direction là khoảng cách nó dò.