Detektor 3D Drag

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

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.

  1. Di jendela Explorer, geser atas Part, MeshPart, atau 1> Class.Model1> dan klik tombol ⊕. Menu konteks dibuat.

  2. Dari menu, sisipkan DragDetector .

  3. 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

MengaturDeskripsi
TranslateLine1D gerakan sepanjang sumbu detector ini, default dunia Axis sumbu.
TranslatePlane2D gerakan di dalam pesawat perpendekar ke detektor, secara default pesawat dunia Axis pesawat.
TranslatePlaneOrLine2D motion di dalam pesawat perpendekar ke detektor Axis dan, ketika modifier aktif , 1D movement di sepanjang detector Axis.
TranslateLineOrPlane1D gerakan sepanjang Axis dan, ketika modifier aktif, gerakan 2D di pesawat paralel dengan Axis .
TranslateViewPlane2D 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.
RotateAxisRotasi tentang detector's Axis , secara default dunia Y sumbu.
RotateTrackballRotasi bola, diperbaiki lebih lanjut melalui property TrackballRadialPullFactor dan TrackballRollFactor.
BestForDevice TerjemahkanPesawatAtauBaris untuk mouse dan gamepad; TerjemahkanPesawat untuk sentuh; 6DOF untuk VR.
ScriptableMenghitung 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>

PropertiDeskripsiStandar
ReferenceInstanceSebuah instansi cucuru yang menyediakan frame referensi untuk detector拖. The DragFrame diungkapkan relatif terhadap referensi frame ini yang dapat diambil melalui Class.DragDetnil
OrientationSpesifikasi 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)
AxisDasar 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.

MengaturPerilaku TertancamPerilaku Tidak Dibatasi
GeometricKedua 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拖.
PhysicalObjek 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.
CustomObjek 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.

PropertiDeskripsiStandar
Class.DragDetector.MinDragTranslation|MinDragTranslation``Class.DragDetector.MaxDragTranslation|MaxDragTranslationMembatasi 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|MaxDragAngleHanya 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.

MengaturDeskripsi
NobodyTidak ada pemain yang dapat berinteraksi dengan DragDetector .
EverybodySemua pemain dapat berinteraksi dengan DragDetector .
ScriptableIzin 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:

PropertiDeskripsiStandar
ApplyAtCenterOfMassKetika benar, dorong kekuatan diterapkan di titik di mana pengguna mengklik. Ketika benar, dorong kekuatan diterapkan di pusat massa objek.benar
MaxForceKekuatan maksimum diterapkan untuk objek untuk mencapai tujuan.100.000.000
MaxTorqueTorsi maksimum diterapkan untuk objek untuk mencapai tujuan.10.000
ResponsivenessNilai 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.

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.

AcaraDeskripsi
DragStartMengaktifkan ketika seorang pengguna mulai menyeret objek.
DragContinueBerapi-api saat pengguna terus menyeret objek setelah DragStart telah diaktifkan.
DragEndMenembak 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)