Class.DragDetector instansi memudahkan dan meningkatkan interaksi dengan objek 3D dalam pengalaman, seperti membuka pintu dan Drawers, menylip sebuah bagian di sekitar, menangkap dan melempar bola bowling, menarik dan menembakkan slingshot, dan banyak lagi. Fitur utama termasuk:
Tempatkan DragDetector di bawah salah satu BasePart atau Model untuk 1> membuatnya ditarik1> melalui semua input (mouse, sentuh, gamepad, dan VR), semua tanpa satu baris kode.
Pilih dari beberapa gaya seret, definisikan cara objek menanggapi gerakan , dan opsi batas sumbu atau gerakan.
Skrip dapat menanggapi manipulasi objek yang diseret untuk mengemudi UI atau membuat keputusan logik, seperti menyesuaikan tingkat cahaya di ruangan berdasarkan pintu pintu geser.
Pemain dapat menipu bagian atau model yang terancam dan mereka akan tetap persis di mana Anda menempatkannya setelah rilis.
Class.DragDetector|DragDetectors bekerja di Studio as long as you're tidak menggunakan alat Pilih , 0> Pindahkan 0>, 3> Skala 3>, atau DragDetectors6> alat, membuat lebih mudah untuk menguji dan menyesuaikan objek yang dapat diseret saat mengedit.
Membuat Objek Dapat Drag
Untuk membuat bagian atau model yang dapat diseret, cukup tambahkan DragDetector sebagai nenek moyang langsung.
Dari menu, sisipkan DragDetector .
Secara default, objek sekarang akan ditarik di pesawat tanah, tetapi Anda dapat mengubah DragStyle , mendefinisikan cara bereaksi terhadap gerakan , dan secara opsional menerapkan batas gerakan atau batas gerakan.
Mengeset Detektor Drag Kustom
Gaya Menyeret
DragDetectors gerakan mouse ke garis dan pesawat virtual untuk menghitung gerakan 3D yang diusulkan. Melalui property DragStyle, Anda dapat memilih dari berbagai peta untuk sesuai kebutuhan Anda. Misalnya, TranslatePlane menghas
Mengatur | Deskripsi |
---|---|
TranslateLine | 1D gerakan sepanjang sumbu detector ini, default dunia Axis sumbu. |
TranslatePlane | 2D gerakan di dalam pesawat perpendekar ke detektor, secara default pesawat dunia Axis pesawat. |
TranslatePlaneOrLine | 2D motion di dalam pesawat perpendekar ke detektor Axis dan, ketika modifier aktif , 1D movement di sepanjang detector Axis. |
TranslateLineOrPlane | 1D gerakan sepanjang Axis dan, ketika modifier aktif, gerakan 2D di pesawat paralel dengan Axis . |
TranslateViewPlane | 2D motion di dalam pesawat perpendekar ke pandangan kamera. Dalam mode ini, pesawat selalu diperbarui, bahkan saat menyeret, dan akan selalu menghadapi pandangan kamera saat ini. |
RotateAxis | Rotasi tentang detector's Axis , secara default dunia Y sumbu. |
RotateTrackball | Rotasi bola, diperbaiki lebih lanjut melalui property TrackballRadialPullFactor dan TrackballRollFactor. |
BestForDevice | TerjemahkanPesawatAtauBaris untuk mouse dan gamepad; TerjemahkanPesawat untuk sentuh; 6DOF untuk VR. |
Scriptable | Menghitung gerakan yang diinginkan melalui fungsi kustom yang disediakan melalui SetDragStyleFunction() . |
Arah Seret
Secara default, 3D motion dan map DragStyle ke ruang dunia. Namun, Anda mungkin ingin mengubah ReferenceInstance , Orientation , atau 1>
Properti | Deskripsi | Standar |
---|---|---|
ReferenceInstance | Sebuah instansi cucuru yang menyediakan frame referensi untuk detector拖. The DragFrame diungkapkan relatif terhadap referensi frame ini yang dapat diambil melalui Class.DragDet | nil |
Orientation | Spesifikasi rotasi YXZ dari sumbu gerakan relatif terhadap referensi frame (tidak mengubah orientasi referensi frame itu sendiri). Translasi lini dan rotasi sumbu akan berada di sumbu Y ini, dan rotasi sumbu di XZ pesawat. Mengubah nilai ini secara otomatis menghubungkan 1> Class | (0, 0, 0) |
Axis | Dasar sumbu gerakan, diungkapkan relatif terhadap referensi frame. Mengubah nilai ini secara otomatis menghasilkan Orientation dan sebaliknya. | (0, 1, 0) |
Balasan untuk Gerakan
Properti ResponseStyle menentukan cara sebuah objek menanggapi gerakan yang diusulkan, tergantung pada apakah objek adalah Anchored atau tidak.
Mengatur | Perilaku Tertancam | Perilaku Tidak Dibatasi |
---|---|---|
Geometric | Kedua di dalam pengalaman berjalan dan di mode Studio pengeditan, posisi / orientasi objek yang diikat akan diperbarui untuk mencerminkan persisuaraan yang diusulkan. | Untuk objek yang tidak berancang, perilaku sama dengan objek yang berancang. Namun, dalam pengalaman berjalan, objek akan diancang di awal drag dan diembalikan ke tahun tua setelah rilis拖. |
Physical | Objek yang diancang akan default ke Geometric perilaku, karena tidak terpengaruh oleh kekuatan. | Objek yang tidak berujung akan dipergeser oleh kekuatan batas yang mencoba untuk membawanya ke posisi dan/atau orientasi yang diberikan oleh gerakan yang diusulkan. |
Custom | Objek tidak akan bergerak sama semua, tetapi DragFrame masih akan diperbarui dan Anda dapat menanggapi manipulasi seret-tampilan seperti yang Anda inginkan. | (sama seperti yang ditautkan) |
Limit Aksi & Gerakan
Secara default, tidak ada batasan untuk gerakan 3D di luar batasan intrinsik Class.DragDetector.DragStyle|DragStyle . Jika perlu, Anda dapat menerapkan batas minimum dan maksimum untuk kedua terjemahan dan rotasi. Catat, bagaimanapun, bahwa ini bukan batasan; mereka hanya mengganggu upaya detektor gerakan untuk menghasilkan gerakan untuk tetap dalam batas.
Properti | Deskripsi | Standar |
---|---|---|
Class.DragDetector.MinDragTranslation|MinDragTranslation``Class.DragDetector.MaxDragTranslation|MaxDragTranslation | Membatasi untuk menyeret terjemahan di setiap dimensi. Jika MaxDragTranslation lebih besar dari MinDragTranslation, terjemahan akan dibungkukkan dalam rentang itu. | (0, 0, 0) |
Class.DragDetector.MinDragAngle|MinDragAngle``Class.DragDetector.MaxDragAngle|MaxDragAngle | Hanya relevan jika DragStyle ditetapkan ke RotateAxis . Jika MaxDragAngle lebih besar dari 1> Class.DragDetector.MinDragAngle|MinDragAngle1>, rotasi akan dibatasi dalam rentang itu. | 0 |
Izinkan Drag
Izinkan pemain untuk berinteraksi dengan instansi detektor serupa yang diberikan dapat ditentukan oleh property PermissionPolicy ini. Ini di set ke Enum.DragDetectorPermissionPolicy.Everybody secara default, dan juga dapat diubah untuk mendukung kontrol izin skrip seperti yang ditunjukkan dalam contoh kode.
Mengatur | Deskripsi |
---|---|
Nobody | Tidak ada pemain yang dapat berinteraksi dengan DragDetector . |
Everybody | Semua pemain dapat berinteraksi dengan DragDetector . |
Scriptable | Izin seretan pemain akan ditentukan oleh fungsi yang terdaftar melalui SetPermissionPolicyFunction() . Di bawah pengaturan ini, ketidakberhasilan mendaftarkan fungsi atau mengembalikan hasil yang tidak valid akan mencegah semua pemain untuk menyeret. |
DragDetector - Ijin Tali Gulir
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)
Balasan Fisika
Menganggap gaya respons dragger di set ke Fisikal dan diterapkan ke objek yang tidak berujung, objek itu akan di移動 oleh kekuatan batas yang mencoba untuk membawanya ke posisi/orientasi yang diberikan oleh gerakan yang diusulkan. Anda dapat menyempurnakan respons fisik melalui berbagai elemen berikut:
Properti | Deskripsi | Standar |
---|---|---|
ApplyAtCenterOfMass | Ketika benar, dorong kekuatan diterapkan di titik di mana pengguna mengklik. Ketika benar, dorong kekuatan diterapkan di pusat massa objek. | benar |
MaxForce | Kekuatan maksimum diterapkan untuk objek untuk mencapai tujuan. | 100.000.000 |
MaxTorque | Torsi maksimum diterapkan untuk objek untuk mencapai tujuan. | 10.000 |
Responsiveness | Nilai yang lebih tinggi menyebabkan objek mencapai tujuan lebih cepat. | 10 |
Masukkan Pengubah
Replikasi
Ketika properti RunLocally adalah palsu (default), klien menafsirkan semua masukan untuk menghasilkan data yang dikirim ke server untuk melakukan drag. Dalam mode ini, semua sinyal acara kustom dan fungsi terdaftar harus ada di server Scripts .
Ketika properti RunLocally benar, tidak ada acara yang dikirim ke server. Semua sinyal acara khusus dan fungsi terdaftar harus ada di client LocalScripts dan Anda harus menggunakan acara remote untuk menyebarkan perubahan yang diperlukan ke server.
Menulis Tanggapan untuk Klik dan Drag
Melalui sinyal acara , perubahan propperti, Scriptable gaya seret, dan fungsi kustom, skrip dapat merespon manipulasi objek yang ditarik untuk mengemudi UI atau membuat keputusan logik, seperti menyesuaikan tingkat cahaya di ruangan berdasarkan pintu pintu geser.
Sinyal Acara
Melalui sinyal acara berikut, Anda dapat mendeteksi ketika seorang pengguna memulai, melanjutkan, dan mengakhiri menyeret objek.
Acara | Deskripsi |
---|---|
DragStart | Mengaktifkan ketika seorang pengguna mulai menyeret objek. |
DragContinue | Berapi-api saat pengguna terus menyeret objek setelah DragStart telah diaktifkan. |
DragEnd | Menembak ketika seorang 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)
Seret PerubahanFrame
Selain sinyal acara, Anda dapat melacak perubahan ke DragFrame detector secara langsung.
DragDetektor - Perubahan DragFrame
local dragDetector = script.Parent.DragDetector
dragDetector:GetPropertyChangedSignal("DragFrame"):Connect(function()
local currentDragTranslation = dragDetector.DragFrame.Position
print(currentDragTranslation)
end)
Gaya Tyerbak Berjalan
Jika Anda menetapkan DragStyle detektor Anda ke Scriptable , Anda dapat menyediakan fungsi Anda sendiri yang mengambil Ray dan mengembalikan ruang dunia 1> Datatype.CFrame1> . Detektor akan menyebarkan gerakan sehingga objek yang diseret
DragDetector - DragStyle Berbasis Skrip
local dragDetector = script.Parent.DragDetector
dragDetector.DragStyle = Enum.DragDetectorDragStyle.Scriptable
local cachedHitPoint = Vector3.zero
local cachedHitNormal = Vector3.yAxis
local function followTheCursor(cursorRay)
-- Hilangkan objek yang ditarik 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 Batas Kustom
Detektor tindakan tidak memiliki aturan gerakan bawaan tentang grid dan snapping, tetapi Anda dapat mendaftar fungsi batas khusus untuk mengedit detector's DragFrame sebelum diterapkan. Misalnya, Anda dapat menyimpan gerakan pada grid dengan menyelesaikan posisi keping ke kali jumlah peningkatan grid, atau menyimulasikan
DragDetector - Fungsi Batas 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 = math.floor(SNAP_INCREMENT)
if snapIncrement < 1 then
return proposedMotion
end
local newWorldPosition = startPartPosition + proposedMotion.Position
local roundedX = math.floor(newWorldPosition.X / snapIncrement + 0.5) * snapIncrement
local roundedY = math.floor(newWorldPosition.Y / snapIncrement + 0.5) * snapIncrement
local roundedZ = math.floor(newWorldPosition.Z / snapIncrement + 0.5) * snapIncrement
local newRoundedWorldPosition = Vector3.new(roundedX, roundedY, roundedZ)
return proposedMotion.Rotation + (newRoundedWorldPosition - startPartPosition)
end
local connection = dragDetector:AddConstraintFunction(2, snapToWorldGrid)
-- When applicable, remove the constraint function by invoking connection:Disconnect()
Contoh Penggunaan
Objek Fisik Tidak Bersarat
Sebuah permainan dasar implementasi detektor tarikan adalah permainan keseimbangan menara di mana pemain harus dengan hati-hati menghapus bagian dan mencoba untuk menjaga menara tegak. Dalam struktur menara berikut, setiap bagian memiliki anak DragDetector dengan default DragStyle d
Model Tertancap Dengan Bagian yang Dapat Ditingkatkan
Anda dapat dengan mudah membuat dan berbagi model yang terutama tertancap, tetapi yang memiliki satu atau lebih bagian anak/model yang pemain dapat menyeret. Misalnya, meja berikut memiliki dua Drawer yang pemain dapat membuka untuk mengeksplorasi apa yang ada di dalam.
Seret Detektor dan Batasan
Anda dapat menggabungkan detektor serupam dengan Constraints, misalnya topeng marionet. Dalam pengaturan berikut, tangan kontrol diancang, bagian tubuh tidak diancang, dan kendali mengikat marionet bersama. Menggerakkan tangan dengan Translate
Antarmuka Pengguna 3D
Antarmuka pengguna 3D mudah diakses melalui detektor geser, seperti menyesuaikan kecerahan SpotLight berdasarkan dimmer
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 partikel dan kecepatan berdasarkan detector拖 X
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 Z faktor detektor serupan
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)