Detektor Seret 3D

*Konten ini diterjemahkan menggunakan AI (Beta) dan mungkin mengandung kesalahan. Untuk melihat halaman ini dalam bahasa Inggris, klik di sini.

Instansi DragDetector memfasilitasi dan mendorong interaksi dengan objek 3D dalam permainan, seperti membuka pintu dan laci, menggeser bagian, mengambil dan melempar bola bowling, menarik kembali dan menembakkan ketapel, dan banyak lagi. Fitur utama termasuk:

  • Tempatkan DragDetector di bawah BasePart atau Model mana pun untuk membuatnya dapat diseret melalui semua input (mouse, sentuhan, gamepad, dan VR), semuanya tanpa satu baris kode pun.

  • Pilih dari beberapa gaya seret, tentukan bagaimana objek merespons gerakan, dan secara opsional terapkan batas sumbu atau gerakan.

  • Skrip dapat merespons manipulasi objek yang diseret untuk menggerakkan UI atau membuat keputusan logis, seperti menyesuaikan tingkat cahaya di sebuah ruangan berdasarkan dimmer saklar dinding yang geser.

  • Pemain dapat memanipulasi bagian atau model yang terikat dan mereka akan tetap persis di tempat Anda meletakkannya setelah dilepaskan.

  • DragDetectors bekerja di Studio selama Anda tidak menggunakan alat Pilih, Gerakkan, Skala, atau Putar, sehingga lebih mudah untuk menguji dan menyesuaikan objek yang dapat diseret saat mengedit.

Membuat objek dapat diseret

Untuk membuat bagian atau model apa pun dapat diseret, cukup tambahkan DragDetector sebagai keturunan langsung.

  1. Di jendela Explorer, arahkan mouse ke Part, MeshPart, atau Model dan klik tombol ⊕. Menu kontekstual ditampilkan.

  2. Dari menu, masukkan DragDetector.

  3. Secara default, objek sekarang akan dapat diseret di bidang tanah, tetapi Anda dapat menyesuaikan DragStyle-nya, menentukan bagaimana objek merespons gerakan, dan secara opsional menerapkan batas sumbu atau gerakan.

Kustomisasi detektor seret

Gaya seret

DragDetectors memetakan gerakan kursor ke garis dan bidang virtual untuk menghitung gerakan 3D yang diusulkan. Melalui properti DragStyle, Anda dapat memilih dari berbagai pemetaan untuk memenuhi kebutuhan Anda. Misalnya, TranslatePlane menghasilkan translasi di bidang virtual, sedangkan RotateAxis menghasilkan rotasi di sekitar sumbu virtual.

PengaturanDeskripsi
TranslateLineGerakan 1D sepanjang Axis detektor, secara default sumbu Y dunia.
TranslatePlaneGerakan 2D di bidang yang tegak lurus terhadap Axis detektor, secara default bidang XZ dunia.
TranslatePlaneOrLineGerakan 2D di bidang yang tegak lurus terhadap Axis detektor dan, ketika modifikator aktif, gerakan 1D sepanjang Axis detektor.
TranslateLineOrPlaneGerakan 1D sepanjang Axis detektor dan, ketika modifikator aktif, gerakan 2D di bidang yang tegak lurus terhadap Axis detektor.
TranslateViewPlaneGerakan 2D di bidang yang tegak lurus terhadap pandangan kamera. Dalam mode ini, bidang diperbarui secara konstan, bahkan saat diseret, dan akan selalu menghadap pandangan kamera saat ini.
RotateAxisRotasi di sekitar Axis detektor, secara default sumbu Y dunia.
RotateTrackballRotasi trackball, lebih lanjut disesuaikan melalui properti TrackballRadialPullFactor dan TrackballRollFactor.
BestForDeviceTranslatePlaneOrLine untuk mouse dan gamepad; TranslatePlane untuk sentuhan; 6DOF untuk VR.
ScriptableMenghitung gerakan yang diinginkan melalui fungsi kustom yang disediakan melalui SetDragStyleFunction().

Arah seret

Secara default, gerakan 3D dan DragStyle terkait dipetakan ke ruang dunia. Namun, Anda mungkin ingin mengubah ReferenceInstance, Orientation, atau Axis, misalnya saat membangun detektor seret ke dalam model dengan bagian yang dapat disesuaikan.

PropertiDeskripsiDefault
ReferenceInstanceSebuah instansi yang porosnya menyediakan kerangka referensi untuk detektor seret. DragFrame dinyatakan relatif terhadap kerangka referensi ini yang dapat diambil melalui GetReferenceFrame(). Jika kerangka referensi adalah nil, translasi akan dilakukan ke arah (atau di bidang yang tegak lurus terhadap) properti Axis di ruang dunia.nil
OrientationMenentukan rotasi YXZ sumbu gerakan relatif terhadap kerangka referensi (tidak mengubah orientasi kerangka referensi itu sendiri). Translasi linier dan rotasi sumbu akan berada di sumbu Y yang telah diorientasikan ini, dan translasi planar di bidang XZ. Mengubah nilai ini secara otomatis memperbarui Axis dan sebaliknya.(0, 0, 0)
AxisSumbu utama gerakan, dinyatakan relatif terhadap kerangka referensi. Mengubah nilai ini secara otomatis memperbarui Orientation dan sebaliknya.(0, 1, 0)

Respons terhadap gerakan

Properti ResponseStyle menentukan bagaimana objek merespons gerakan yang diusulkan, tergantung pada apakah objek tersebut Anchored atau tidak.

PengaturanPerilaku TerikatPerilaku Tidak Terikat
GeometricBaik di dalam permainan yang sedang berjalan maupun dalam mode edit Studio, posisi/orientasi objek yang terikat akan diperbarui untuk mencerminkan dengan tepat gerakan yang diusulkan.Untuk objek yang tidak terikat, perilakunya sama dengan objek yang terikat. Namun, dalam permainan yang sedang berjalan, objek akan terikat pada awal seret dan dipulihkan menjadi tidak terikat saat seret dilepaskan.
PhysicalObjek yang terikat akan default ke perilaku Geometric, karena tidak terpengaruh oleh gaya.Objek yang tidak terikat akan dipindahkan oleh gaya pembatas yang berusaha membawanya ke posisi dan/atau orientasi yang diinginkan yang diberikan oleh gerakan yang diusulkan.
CustomObjek tidak akan bergerak sama sekali, tetapi DragFrame masih akan diperbarui dan Anda dapat merespons manipulasi seret sesuai keinginan Anda.(sama seperti terikat)

Batas sumbu & gerakan

Secara default, tidak ada batasan untuk gerakan 3D di luar batasan bawaan dari DragStyle. Jika perlu, Anda dapat menerapkan batas minimum dan maksimum untuk translasi dan rotasi. Namun, perlu dicatat bahwa ini bukan batasan; mereka hanya menghalangi upaya detektor seret untuk menghasilkan gerakan agar tetap dalam batas.

PropertiDeskripsiDefault
MinDragTranslation
MaxDragTranslation
Batas untuk translasi seret di setiap dimensi. Jika MaxDragTranslation lebih besar dari MinDragTranslation, translasi akan dibatasi dalam rentang tersebut.(0, 0, 0)
MinDragAngle
MaxDragAngle
Hanya relevan jika DragStyle diatur ke RotateAxis. Jika MaxDragAngle lebih besar dari MinDragAngle, rotasi akan dibatasi dalam rentang tersebut.0

Izin seret

Izin pemain untuk berinteraksi dengan instansi detektor seret tertentu dapat ditentukan oleh properti PermissionPolicy. Ini diatur ke Enum.DragDetectorPermissionPolicy.Everybody secara default, dan juga dapat diubah untuk mendukung kontrol izin yang diprogram seperti yang ditunjukkan dalam contoh kode.

PengaturanDeskripsi
NobodyTidak ada pemain yang dapat berinteraksi dengan DragDetector.
EverybodySemua pemain dapat berinteraksi dengan DragDetector.
ScriptableIzin seret pemain akan ditentukan oleh fungsi yang terdaftar melalui SetPermissionPolicyFunction(). Di bawah pengaturan ini, kegagalan untuk mendaftarkan fungsi atau mengembalikan hasil yang tidak valid akan mencegah semua pemain dari seret.
DragDetector - Izin Seret yang Diprogram
local dragDetector = script.Parent.DragDetector
dragDetector.PermissionPolicy = Enum.DragDetectorPermissionPolicy.Scriptable
dragDetector:SetPermissionPolicyFunction(function(player, part)
if player and player:GetAttribute("IsInTurn") then
return true
elseif part and not part:GetAttribute("IsDraggable") then
return false
else
return true
end
end)

Respons fisika

Dengan asumsi gaya respons detektor diatur ke Physical dan diterapkan pada objek yang tidak terikat, objek tersebut akan dipindahkan oleh gaya pembatas yang berusaha membawanya ke posisi/orientasi yang diberikan oleh gerakan yang diusulkan. Anda dapat lebih menyesuaikan respons fisik melalui properti berikut:

PropertiDeskripsiDefault
ApplyAtCenterOfMassKetika false, gaya seret diterapkan pada titik di mana pengguna mengklik. Ketika true, gaya diterapkan di pusat massa objek.false
MaxForceGaya maksimum yang diterapkan agar objek mencapai tujuannya.10000000
MaxTorqueTorsi maksimum yang diterapkan agar objek mencapai tujuannya.10000
ResponsivenessNilai yang lebih tinggi menyebabkan objek mencapai tujuannya lebih cepat.10

Input modifikator

Beberapa mode DragStyle memungkinkan pengguna untuk menahan tombol/kolom modifikator untuk memanipulasi objek yang diseret dengan cara yang berbeda. Secara default, modifikator adalah LeftControl di PC, ButtonR1 di gamepad, atau ButtonL2 di VR. Anda dapat menyesuaikan modifikator ini melalui KeyboardModeSwitchKeyCode, GamepadModeSwitchKeyCode, atau VRSwitchKeyCode properti dari instansi detektor seret.

Replikasi

Ketika properti RunLocally adalah false (default), klien menginterpretasikan semua input untuk menghasilkan data yang dikirim ke server untuk melakukan seret. Dalam mode ini, semua sinyal acara kustom dan fungsi yang terdaftar harus berada di server Scripts.

Ketika properti RunLocally adalah true, tidak ada acara yang direplikasi ke server. Semua sinyal acara kustom dan fungsi yang terdaftar harus berada di klien LocalScripts dan Anda harus menggunakan acara jarak jauh untuk menyebarkan perubahan yang diperlukan ke server.

Respons skrip terhadap klik dan seret

Melalui sinyal acara, perubahan properti, gaya seret Scriptable, dan fungsi kustom, skrip dapat merespons manipulasi objek yang diseret untuk menggerakkan UI atau membuat keputusan logis, seperti menyesuaikan tingkat cahaya di sebuah ruangan berdasarkan dimmer saklar dinding yang geser.

Sinyal acara

Melalui sinyal acara berikut, Anda dapat mendeteksi kapan pengguna mulai, melanjutkan, dan menghentikan seret objek.

AcaraDeskripsi
DragStartDipicu ketika pengguna mulai menyeret objek.
DragContinueDipicu ketika pengguna melanjutkan menyeret objek setelah DragStart telah dimulai.
DragEndDipicu ketika pengguna berhenti menyeret objek.
DragDetector - Sinyal Acara
local dragDetector = script.Parent.DragDetector
local highlight = Instance.new("Highlight")
highlight.Enabled = false
highlight.Parent = script.Parent
dragDetector.DragStart:Connect(function()
highlight.Enabled = true
end)
dragDetector.DragContinue:Connect(function()
end)
dragDetector.DragEnd:Connect(function()
highlight.Enabled = false
end)

Perubahan bingkai seret

Selain sinyal acara, Anda dapat memantau perubahan pada DragFrame detektor secara langsung.

DragDetector - Perubahan DragFrame
local dragDetector = script.Parent.DragDetector
dragDetector:GetPropertyChangedSignal("DragFrame"):Connect(function()
local currentDragTranslation = dragDetector.DragFrame.Position
print(currentDragTranslation)
end)

Gaya seret yang diprogram

Jika Anda mengatur DragStyle detektor ke Scriptable, Anda dapat menyediakan fungsi Anda sendiri yang menerima Ray dan mengembalikan CFrame ruang dunia. Detektor akan memindahkan gerakan sehingga objek yang diseret pergi ke lokasi/orientasi kustom tersebut.

DragDetector - Gaya Seret yang Diprogram
local Workspace = game:GetService("Workspace")
local dragDetector = script.Parent.DragDetector
dragDetector.DragStyle = Enum.DragDetectorDragStyle.Scriptable
local cachedHitPoint = Vector3.zero
local cachedHitNormal = Vector3.yAxis
local function followTheCursor(cursorRay)
-- Kecualikan objek yang diseret dari deteksi raycast
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {dragDetector.Parent}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local hitPoint = Vector3.zero
local hitNormal = Vector3.yAxis
local raycastResult = Workspace:Raycast(cursorRay.Origin, cursorRay.Direction, raycastParams)
if raycastResult then
hitPoint = raycastResult.Position
hitNormal = raycastResult.Normal.Unit
else
hitPoint = cachedHitPoint
hitNormal = cachedHitNormal
end
cachedHitPoint = hitPoint
cachedHitNormal = hitNormal
local lookDir1 = hitNormal:Cross(Vector3.xAxis)
local lookDir2 = hitNormal:Cross(Vector3.yAxis)
local lookDir = if lookDir1.Magnitude > lookDir2.Magnitude then lookDir1.Unit else lookDir2.Unit
return CFrame.lookAt(hitPoint, hitPoint + lookDir, hitNormal)
end
dragDetector:SetDragStyleFunction(followTheCursor)

Fungsi batasan kustom

Detektor seret tidak memiliki aturan gerakan bawaan tentang grid dan snapping, tetapi Anda dapat mendaftarkan fungsi batasan kustom untuk mengedit DragFrame detektor sebelum diterapkan. Misalnya, Anda dapat menjaga gerakan pada grid dengan membulatkan posisi ke kelipatan dari peningkatan grid, atau mensimulasikan permainan catur dengan aturan gerakan yang sah untuk setiap bidak.

DragDetector - Fungsi Batasan Kustom
local dragDetector = script.Parent.DragDetector
local startPartPosition = nil
local SNAP_INCREMENT = 4
dragDetector.DragStart:Connect(function()
startPartPosition = script.Parent.Position
end)
dragDetector.DragEnd:Connect(function()
startPartPosition = nil
end)
local function snapToWorldGrid(proposedMotion)
if startPartPosition == nil then
return proposedMotion
end
local snapIncrement = SNAP_INCREMENT // 1
if snapIncrement < 1 then
return proposedMotion
end
local newWorldPosition = startPartPosition + proposedMotion.Position
local roundedX = ((newWorldPosition.X / snapIncrement + 0.5) // 1) * snapIncrement
local roundedY = ((newWorldPosition.Y / snapIncrement + 0.5) // 1) * snapIncrement
local roundedZ = ((newWorldPosition.Z / snapIncrement + 0.5) // 1) * snapIncrement
local newRoundedWorldPosition = Vector3.new(roundedX, roundedY, roundedZ)
return proposedMotion.Rotation + (newRoundedWorldPosition - startPartPosition)
end
local connection = dragDetector:AddConstraintFunction(2, snapToWorldGrid)
-- Ketika berlaku, hapus fungsi batasan dengan memanggil connection:Disconnect()

Contoh penggunaan

Objek fisik yang tidak terikat

Implementasi dasar dari detektor seret adalah permainan keseimbangan menara di mana pemain harus hati-hati menghapus bagian dan berusaha menjaga menara tetap tegak. Dalam struktur menara berikut, setiap bagian memiliki anak DragDetector dengan DragStyle default TranslatePlane sehingga pemain dapat menarik bagian ke luar tetapi tidak ke atas atau ke bawah.

Model terikat dengan bagian yang dapat disesuaikan

Anda dapat dengan mudah membuat dan membagikan model yang sebagian besar terikat, tetapi memiliki satu atau lebih bagian/model anak yang dapat diseret oleh pemain. Misalnya, meja berikut memiliki dua laci yang dapat dibuka pemain untuk memeriksa apa yang ada di dalamnya.

Detektor seret dan batasan

Anda dapat menggabungkan detektor seret dengan Constraints, misalnya boneka marionette. Dalam pengaturan berikut, pegangan kontrol terikat, bagian tubuh tidak terikat, dan batasan menjaga marionette tetap bersama. Menggerakkan pegangan dengan gaya seret TranslateViewPlane DragStyle membuat marionette menari, dan bagian tubuh individu juga dapat dipindahkan dengan detektor seret, semuanya sementara model mempertahankan integritasnya.

Antarmuka pengguna 3D

Antarmuka pengguna 3D dapat dengan mudah dicapai melalui detektor seret, seperti menyesuaikan kecerahan SpotLight berdasarkan dimmer saklar yang geser. Anda juga dapat mendeteksi sumbu X dan Z secara individual untuk mengontrol dua aspek berbeda dari antarmuka pengguna 3D, seperti Size, Speed, dan Color dari ParticleEmitter.

DragDetector - Antarmuka Pengguna 3D
local model = script.Parent
local slider = model.SliderPart
local originPart = model.OriginPart
local emitter = script.Parent.EmitterPart.ParticleEmitter
local dragDetector = slider.DragDetector
dragDetector.ReferenceInstance = originPart
dragDetector.MinDragTranslation = Vector3.zero
dragDetector.MaxDragTranslation = Vector3.new(10, 0, 10)
local dragRangeX = dragDetector.MaxDragTranslation.X - dragDetector.MinDragTranslation.X
local dragRangeZ = dragDetector.MaxDragTranslation.Z - dragDetector.MinDragTranslation.Z
local MIN_PARTICLE_SIZE = 1
local MAX_PARTICLE_SIZE = 1.5
local MIN_PARTICLE_SPEED = 2.5
local MAX_PARTICLE_SPEED = 5
local COLOR1 = Color3.fromRGB(255, 150, 0)
local COLOR2 = Color3.fromRGB(255, 0, 50)
local function updateParticles(emitter)
local dragFactorX = (dragDetector.DragFrame.Position.X - dragDetector.MinDragTranslation.X) / dragRangeX
local dragFactorZ = (dragDetector.DragFrame.Position.Z - dragDetector.MinDragTranslation.Z) / dragRangeZ
-- Sesuaikan ukuran dan kecepatan partikel berdasarkan faktor X detektor seret
emitter.Size = NumberSequence.new{
NumberSequenceKeypoint.new(0, 0),
NumberSequenceKeypoint.new(0.1, MIN_PARTICLE_SIZE + ((MAX_PARTICLE_SIZE - MIN_PARTICLE_SIZE) * dragFactorX)),
NumberSequenceKeypoint.new(1, 0)
}
local speed = MIN_PARTICLE_SPEED + ((MAX_PARTICLE_SPEED - MIN_PARTICLE_SPEED) * dragFactorX)
emitter.Speed = NumberRange.new(speed, speed * 1.2)
-- Sesuaikan warna partikel berdasarkan faktor Z detektor seret
local color = COLOR2:Lerp(COLOR1, dragFactorZ)
emitter.Color = ColorSequence.new{
ColorSequenceKeypoint.new(0, color),
ColorSequenceKeypoint.new(1, color)
}
end
dragDetector:GetPropertyChangedSignal("DragFrame"):Connect(function()
updateParticles(emitter)
end)
©2026 Roblox Corporation. Roblox, logo Roblox, dan Powering Imagination termasuk dalam merek dagang kami yang terdaftar dan tidak terdaftar di AS dan negara lainnya.