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 memudahkan dan mendorong interaksi dengan objek 3D dalam pengalaman, seperti membuka pintu dan laci, menylipkan bagian, mengambil dan melempar bola bowling, menarik kembali dan menembakkan panah, dan banyak lagi.Fitur kunci termasuk:

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

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

  • Skrip dapat menanggapi manipulasi objek yang diseret untuk mengemudikan UI atau membuat keputusan logis, seperti menyesuaikan tingkat cahaya di sebuah ruang berdasarkan sakelar dinding geser dimmer.

  • Pemain dapat memanipulasi bagian atau model terikat dan mereka akan tetap tepat di tempat Anda menempatkannya saat dirilis.

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

Membuat objek dapat diseret

Untuk membuat bagian atau model yang dapat diseret, tambahkan hanya DragDetector sebagai keturunan langsung.

  1. Di jendela Explorer, gulir di atas Part, MeshPart, atau Model dan klik tombol ⊕. Menu konteks ditampilkan.

  2. Dari menu, masukkan Detektor Drag .

  3. Secara default, objek sekarang dapat ditarik di pesawat tanah, tetapi Anda dapat menyesuaikan nya , mendefinisikan bagaimana ia menanggapi gerakan , dan secara opsional menerapkan batas sumbu atau gerakan .

Sesuaikan detektor seretan

Seret gaya

DragDetectors memindahkan kursor peta ke garis dan pesawat virtual untuk menghitung gerakan 3D yang diusulkan.Melalui properti DragStyle , Anda dapat memilih dari berbagai mape untuk memenuhi kebutuhan Anda.Sebagai contoh, TranslatePlane menghasilkan terjemahan di pesawat virtual, sementara RotateAxis menghasilkan rotasi tentang sumbu virtual.

PengaturanDeskripsi
TranslateLine1D gerakan di sepanjang sumbu detektor Axis, secara default sumbu dunia Y .
TranslatePlaneGerakan 2D di pesawat berlawanan dengan Axis, secara default pesawat dunia XZ .
TranslatePlaneOrLineGerakan 2D di pesawat berpendam pada detektor Axis dan, ketika modifikasi aktif , gerakan 1D di sepanjang detektor Axis.
TranslateLineOrPlane1D gerakan di sepanjang detektor Axis dan, ketika modifikasi aktif , gerakan 2D di pesawat berlawanan dengan detektor Axis .
TranslateViewPlaneGerakan 2D di pesawat berlawanan dengan pandangan kamera.Dalam mode ini, pesawat terus diperbarui, bahkan saat menyeret, dan akan selalu menghadapi pandangan saat ini kamera.
RotateAxisRotasi tentang sumbu detektor Axis , secara default sumbu dunia Y .
RotateTrackballRotasi trackball, lebih disesuaikan melalui properti TrackballRadialPullFactor dan TrackballRollFactor .
BestForDevice TerjemahkanPesawatAtauGaris untuk mouse dan gamepad; TerjemahkanPesawat untuk sentuhan; 6DOF untuk VR.
ScriptableMenghitung gerakan yang diinginkan melalui fungsi khusus yang disediakan melalui SetDragStyleFunction() .

Arah seret

Secara default, gerakan 3D dan peta terkait DragStyle 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 .

PropinsiDeskripsiStandar
ReferenceInstanceSebuah instansi yang pivotnya menyediakan frame referensi untuk detektor seret untuk detektor seret.The DragFrame diungkapkan relatif terhadap frame referensi ini yang dapat diambil melalui GetReferenceFrame() .Jika frame referensi adalah nil , terjemahan akan berada di arah (atau di pesawat paralel dengan) properti Axis di ruang dunia.nil
OrientationMenentukan rotasi YXZ sumbu gerakan relatif terhadap frame referensi (tidak mengubah orientasi frame referensi itu sendiri).Terjemahan linier dan rotasi sumbu akan berada di sumbu reorientasi ini Y , dan terjemahan datar di plane XZ .Mengubah nilai ini secara otomatis memperbarui Axis dan sebaliknya.(0, 0, 0)
AxisL sumbu utama gerakan, diekspresikan relatif terhadap frame referensi. Mengubah nilai ini secara otomatis memperbarui Orientation dan sebaliknya.(0, 1, 0)

Respon terhadap gerakan

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

PengaturanPerilaku terikatPerilaku tidak terikat
GeometricKedua di dalam pengalaman berjalan dan di mode edit Studio, posisi/orientasi objek yang diikat akan diperbarui untuk mencerminkan gerakan yang diusulkan dengan tepat.Untuk objek yang tidak diikat, perilaku sama dengan untuk objek yang diikat.Namun, dalam pengalaman yang sedang berjalan, objek akan diberikan pada awal seret dan dipulihkan pada saat pembebasan seret tanpa disangkut.
PhysicalObjek yang diikat akan default ke perilaku Geometris , karena tidak dipengaruhi oleh kekuatan.Objek yang tidak diikat akan dipindahkan oleh kekuatan batasan yang berusaha 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 seretan sesuai keinginan Anda.(sama dengan diikat)

Batas sumbu & gerakan

Secara default, tidak ada batasan untuk gerakan 3D di luar batasan inheren dari DragStyle .Jika perlu, Anda dapat menerapkan batas minimum dan maksimum untuk kedua terjemahan dan rotasi.Perhatikan, bagaimanapun, bahwa ini bukan batasan; mereka hanya mengganggu upaya detektor gerakan untuk menghasilkan gerakan agar tetap berada dalam batas.

PropinsiDeskripsiStandar
Class.DragDetector.MinDragTranslation|MinDragTranslation``Class.DragDetector.MaxDragTranslation|MaxDragTranslationBatasan untuk menyeret terjemahan di setiap dimensi. Jika MaxDragTranslation lebih besar dari MinDragTranslation, terjemahan akan dibatasi dalam rentang itu.(0, 0, 0)
Class.DragDetector.MinDragAngle|MinDragAngle``Class.DragDetector.MaxDragAngle|MaxDragAngleHanya relevan jika DragStyle diatur ke RotateAxis .Jika MaxDragAngle lebih besar dari MinDragAngle , rotasi akan dibatasi dalam rentang itu.0

Seret izin

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

PengaturanDeskripsi
NobodyTak ada pemain yang bisa berinteraksi dengan DragDetector.
EverybodySemua pemain dapat berinteraksi dengan DragDetector.
ScriptableIzin seret pemain akan ditentukan oleh fungsi yang terdaftar melalui SetPermissionPolicyFunction().Di bawah pengaturan ini, gagal mendaftarkan fungsi atau kembali dengan hasil tidak valid akan mencegah semua pemain menyeret.
Detektor Drag - Izin Drag Tertulis

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)

Tanggapan fisika

Mengasumsikan gaya respons dragger adalah ditetapkan ke Fisik dan itu diterapkan ke objek yang tidak diikat, objek itu akan dipindahkan oleh ketegangan yang mencoba membawanya ke posisi/orientasi yang diberikan oleh gerakan yang diusulkan.Anda dapat lebih lanjut menyesuaikan respons fisik melalui properti berikut:

PropinsiDeskripsiStandar
ApplyAtCenterOfMassKetika palsu, gaya seret diterapkan di titik yang diklik pengguna. Ketika benar, gaya diterapkan di pusat massa objek.salah
MaxForceKekuatan maksimum yang diterapkan untuk objek untuk mencapai tujuannya.10000000
MaxTorqueTorsi maksimum yang diterapkan untuk objek untuk mencapai tujuannya.10000
ResponsivenessNilai lebih tinggi menyebabkan objek mencapai tujuannya lebih cepat.10

Input modifikasi

Beberapa mode DragStyle memungkinkan pengguna untuk menahan tombol modifikasi untuk memanipulasi objek yang ditarik 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 instansi detektor seret.

Replikasi

Ketika properti RunLocally palsu, klien menafsirkan semua input untuk menghasilkan data yang dikirim ke server untuk melakukan seretanDalam mode ini, semua sinyal acara khusus dan fungsi terdaftar harus ada di server Scripts.

Ketika properti RunLocally benar, tidak ada acara yang direplikasikan ke server.Semua sinyal acara khusus dan fungsi terdaftar harus ada di klien LocalScripts dan Anda harus menggunakan peristiwa jarak jauh untuk menyebarkan perubahan yang diperlukan ke server.

Respons skrip untuk mengklik dan seret

Melalui sinyal acara, perubahan properti, Scriptable gaya seret, dan fungsi khusus, skrip dapat menanggapi manipulasi objek tertarik untuk mengemudikan UI atau membuat keputusan logis, seperti menyesuaikan tingkat cahaya di sebuah ruang berdasarkan sakelar dinding geser dimmer.

Sinyal acara

Melalui sinyal acara berikut, Anda dapat mendeteksi kapan pengguna mulai, melanjutkan, dan mengakhiri menyeret objek.

PeristiwaDeskripsi
DragStartMelepaskan api saat pengguna mulai menyeret objek.
DragContinueMelepaskan api saat pengguna melanjutkan menyeret objek setelah DragStart telah diinisialisasi.
DragEndMelepaskan api saat pengguna berhenti menyeret objek.
Detektor Drag - Sinyal Peristiwa

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 perubahan khung

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

Detektor Drag - Perubahan Frame Drag

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

Gaya seret ditulis

Jika Anda mengatur fungsi detektor DragStyle ke Scriptable , Anda dapat memberikan fungsi Anda sendiri yang mengambil Ray dan kembali ruang dunia CFrame .Detektor akan memindahkan gerakan sehingga objek yang ditarik pergi ke lokasi/orientasi khusus itu.

Detektor Drag - Gaya Drag Tertulis

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)
-- Terapkan 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 khusus

Detektor seret tidak memiliki aturan gerakan bawaan tentang grid dan geser, tetapi Anda dapat mendaftarkan fungsi batasan khusus untuk mengedit fungsi detektor DragFrame.Sebagai contoh, Anda dapat menyimpan gerakan di grid dengan membulatkan posisi ke multiplikasi peningkatan grid, atau menyimulasikan permainan catur dengan aturan gerakan yang sah untuk setiap bagian.

Detektor Drag - 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)
-- When applicable, remove the constraint function by invoking connection:Disconnect()

Contoh penggunaan

Objek fisik tidak terikat

Implementasi dasar detektor seret adalah permainan keseimbangan menara di mana pemain harus hati-hati menghapus bagian dan mencoba untuk menjaga menara tetap berdiri.Dalam struktur menara berikut, setiap bagian memiliki anak DragDetector dengan default DragStyle dari 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 berbagi model yang terutama diberikan, tetapi memiliki satu atau lebih bagian/model anak yang dapat ditarik pemain.Sebagai contoh, meja berikut memiliki dua laci yang dapat dibuka pemain untuk memeriksa apa yang ada di dalam.

Seret detektor dan batasan

Anda dapat menggabungkan detektor seret dengan Constraints, misalnya boneka marionet.Dalam pengaturan berikut, tangan kontrol diberi pijakan, bagian tubuh tidak diberi pijakan, dan batasan menahan marionette bersama-sama.Memindahkan pegangan dengan TranslateViewPlane DragStyle membuat tarian marionet, dan bagian tubuh individ juga dapat dipindahkan dengan detektor seret, semua sementara model mempertahankan integritasnya.

Antarmuka pengguna 3D

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

Detektor Drag - 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 faktor detektor drag 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 faktor detektor gerak Z
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)