Các ví dụ DragDetector giúp dễ dàng và khuyến khích tương tác với các đối tượng 3D trong một trải nghiệm, chẳng hạn như mở cửa và ngăn kéo, kéo một phần xung quanh, nắm lấy và ném một quả bóng bowling, kéo lại và bắn một khẩu súng ngắn, và nhiều hơn nữa.Các tính năng chính bao gồm:
Đặt một DragDetector dưới bất kỳ BasePart hoặc Model để làm cho nó có thể kéo dài thông qua tất cả các đầu vào (chuột, cảm ứng, gamepad và VR), tất cả mà không có một dòng mã nào.
Chọn từ một số kiểu kéo , xác định cách mà đối tượng phản ứng với chuyển động , và có thể áp dụng tùy chọn trục hoặc giới hạn di chuyển .
Các kịch bản có thể phản ứng với sự thao tác của các đối tượng bị kéo để lái UI hoặc đưa ra các quyết định logic, chẳng hạn như điều chỉnh mức độ sáng trong một phòng dựa trên một công tắc chuyển đổi ánh sáng trượt.
Người chơi có thể thao tác các phần hoặc mô hình được neo và chúng sẽ ở lại chính xác nơi bạn đặt chúng khi phát hành.
DragDetectors làm việc trong Studio miễn là bạn không sử dụng công cụ Chọn , Di chuyển , Thước đo hoặc Xoay công cụ, làm cho nó dễ dàng hơn để kiểm tra và điều chỉnh các đối tượng có thể kéo được trong khi chỉnh sửa.
Làm cho các đối tượng có thể kéo
Để làm cho bất kỳ phần hoặc mô hình nào có thể kéo, chỉ cần thêm một DragDetector như một con cháu trực tiếp.
Từ menu, chèn vào DragDetector .
Mặc định, vật phẩm bây giờ có thể kéo trên máy bay mặt đất, nhưng bạn có thể tùy chỉnh DragStyle, xác định cách nó phản ứng với chuyển động và có thể áp dụng trục hoặc giới hạn di chuyển tùy chọn.
Tùy chỉnh cảm biến kéo
Kéo phong cách
DragDetectors di chuyển con trỏ bản đồ đến các dòng và kế hoạch ảo để tính toán chuyển động 3D đề xuất.Thông qua thuộc tính DragStyle, bạn có thể chọn từ các bản đồ khác nhau để phù hợp với nhu cầu của bạn.Ví dụ, TranslatePlane sản xuất bản dịch trong một máy bay ảo, trong khi RotateAxis sản xuất sự xoay xung quanh một trục ảo.
Cài đặt | Mô tả |
---|---|
TranslateLine | 1D chuyển động dọc theo trục của cảm biến, mặc định là trục thế giới Y . |
TranslatePlane | 2D chuyển động trong máy bay vuông góc với detector's Axis , mặc định là máy bay thế giới XZ . |
TranslatePlaneOrLine | 2D chuyển động trong máy bay vuông góc với điểm cảm biến Axis và, khi điều chỉnh modifier được bật, chuyển động 1D dọc theo điểm cảm biến Axis . |
TranslateLineOrPlane | 1D chuyển động dọc theo detector's Axis và, khi modifier được bật, chuyển động 2D trong phương diện vuông góc với detector's Axis . |
TranslateViewPlane | Chuyển động 2D trong phi cơ vuông góc với tầm nhìn của camera.Trong chế độ này, máy bay liên tục được cập nhật, ngay cả khi kéo, và sẽ luôn phải đối mặt với góc nhìn hiện tại của máy ảnh. |
RotateAxis | Vòng xoay quanh trục cảm biến của Axis, mặc định là trục thế giới Y . |
RotateTrackball | Vòng xoay trackball, tiếp tục điều chỉnh thông qua các thuộc tính TrackballRadialPullFactor và TrackballRollFactor. |
BestForDevice | Dịch máy bay hoặc dòng cho chuột và gamepad; Dịch máy bay cho cảm ứng; 6DOF cho VR. |
Scriptable | Tính toán chuyển động mong muốn thông qua chức năng tùy chỉnh cung cấp thông qua SetDragStyleFunction() . |
Hướng kéo
Mặc định, chuyển động 3D và bản đồ liên quan DragStyle đến không gian thế giới.Tuy nhiên, bạn có thể muốn thay đổi ReferenceInstance , Orientation , hoặc Axis , ví dụ khi xây dựng cảm biến kéo vào mô hình có thể điều chỉnh các bộ phận .
Tài sản | Mô tả | Mặc định |
---|---|---|
ReferenceInstance | Một ví dụ mà trục của nó cung cấp khung tham chiếu cho bộ cảm biến kéo cho người dùng.The DragFrame được biểu hiện tương quan với khung tham chiếu này có thể được truy xuất thông qua GetReferenceFrame() .Nếu khung tham chiếu là nil , bản dịch sẽ ở trong hướng (hoặc trên phi cơ song song với) thuộc tính Axis ở không gian thế giới. | nil |
Orientation | Xác định sự xoay YXZ của trục chuyển động so với khung tham chiếu (không thay đổi hướng của khung tham chiếu chính nó).Dịch chuyển song song và xoay trục sẽ ở trên trục Y này được chuyển hướng lại, và dịch chuyển phẳng trong XZ không gian.Thay đổi giá trị này tự động cập nhật Axis và ngược lại. | (0, 0, 0) |
Axis | Trục chính của chuyển động, được biểu hiện so với khung tham chiếu. Thay đổi giá trị này tự động cập nhật Orientation và ngược lại. | (0, 1, 0) |
Phản hồi lại chuyển động
Thuộc tính ResponseStyle quy định cách một đối tượng phản hồi lại chuyển động đề xuất, tùy thuộc vào việc đối tượng có phải là Anchored hay không.
Cài đặt | Hành vi neo cố định | Hành vi không neo |
---|---|---|
Geometric | Cả bên trong trải nghiệm chạy và trong chế độ chỉnh sửa Studio, vị trí/hướng của một đối tượng neo sẽ được cập nhật để chính xác phản ánh chuyển động được đề xuất. | Đối với một đối tượng chưa neo, hành vi giống như đối với một đối tượng neo.Tuy nhiên, trong một trải nghiệm đang chạy, đối tượng sẽ được neo tại đầu của cuộc kéo và được khôi phục lại không neo khi phát hành cuộc kéo. |
Physical | Một đối tượng được neo sẽ mặc định cho hành vi định hình , vì nó không bị ảnh hưởng bởi lực. | Một đối tượng không neo sẽ được di chuyển bởi lực siết mà cố gắng đưa nó vào vị trí và/hoặc hướng mong muốn được đưa ra bởi chuyển động đề xuất. |
Custom | Vật thể sẽ không di chuyển chút tất cả, nhưng DragFrame vẫn sẽ được cập nhật và bạn có thể phản hồi với thao tác kéo bất kỳ theo cách nào bạn muốn. | (tương tự như neo) |
Giới hạn trục và chuyển động
Mặc định, không có giới hạn cho chuyển động 3D vượt quá các hạn chế bẩm sinh của DragStyle .Nếu cần, bạn có thể áp dụng giới hạn tối thiểu và tối đa cho cả dịch và xoay.Tuy nhiên, hãy lưu ý rằng chúng là không những hạn chế; chúng chỉ cản trở các nỗ lực của máy phát hiện chuyển động để tạo ra chuyển động nhằm đảm bảo nằm trong giới hạn.
Thuộc tính | Mô tả | Mặc định |
---|---|---|
Class.DragDetector.MinDragTranslation|MinDragTranslation``Class.DragDetector.MaxDragTranslation|MaxDragTranslation | Giới hạn kéo bản dịch trong mỗi chiều. Nếu MaxDragTranslation lớn hơn MinDragTranslation, bản dịch sẽ bị giới hạn trong phạm vi đó. | (0, 0, 0) |
Class.DragDetector.MinDragAngle|MinDragAngle``Class.DragDetector.MaxDragAngle|MaxDragAngle | Chỉ liên quan nếu DragStyle được đặt thành Trục xoay .Nếu MaxDragAngle lớn hơn MinDragAngle , việc xoay sẽ bị giới hạn trong phạm vi đó. | 0 |
Kéo quyền
Quyền của người chơi để tương tác với một ví dụ cảm biến kéo cụ thể có thể được xác định bởi thuộc tính PermissionPolicy.Nó được đặt thành Enum.DragDetectorPermissionPolicy.Everybody mặc định, và cũng có thể được thay đổi để hỗ trợ kiểm soát quyền được lập trình như được hiển thị trong ví dụ mã.
Cài đặt | Mô tả |
---|---|
Nobody | Không ai có thể tương tác với DragDetector . |
Everybody | Tất cả người chơi có thể tương tác với DragDetector. |
Scriptable | Quyền kéo của người chơi sẽ được xác định bởi một chức năng đã đăng ký thông qua SetPermissionPolicyFunction() .Trong cài đặt này, việc không đăng ký chức năng hoặc trả về kết quả không hợp lệ sẽ ngăn tất cả các người chơi kéo. |
DragDetector - Quyền kéo được lập trình
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)
Phản ứng vật lý
Giả sử phong cách phản hồi của người kéo được đặt thành Vật lý và nó được áp dụng cho một đối tượng chưa neo, đối tượng đó sẽ được di chuyển bởi các lực siết cố gắng đưa nó đến vị trí/hướng được đưa ra bởi chuyển động đề xuấtBạn có thể tùy chỉnh thêm phản hồi vật lý thông qua các thuộc tính sau:
Tài sản | Mô tả | Mặc định |
---|---|---|
ApplyAtCenterOfMass | Khi giả mạo, lực kéo được áp dụng tại điểm mà người dùng nhấp vào. Khi đúng, lực được áp dụng tại trung tâm khối lượng của đối tượng. | giả mạo |
MaxForce | Lực tối đa được áp dụng cho đối tượng để đạt được mục tiêu của nó. | 10000000 |
MaxTorque | Mômen tối đa được áp dụng cho đối tượng để đạt được mục tiêu của nó. | 10000 |
Responsiveness | Các giá trị cao hơn khiến đối tượng đạt được mục tiêu của nó nhanh hơn. | 10 |
Nhập biến thể
Một số chế độ DragStyle cho phép người dùng giữ phím/ nút chỉnh sửa để thao tác với đối tượng bị kéo theo nhiều cách khác nhau.Mặc định, chỉnh sửa viên là LeftControl trên PC, ButtonR1 trên gamepad hoặc ButtonL2 trên VR.Bạn có thể tùy chỉnh các modifier này thông qua KeyboardModeSwitchKeyCode , GamepadModeSwitchKeyCode hoặc VRSwitchKeyCode tính chất của ví dụ / trường hợpcảm biến kéo.
Sao lưu
Khi thuộc tính RunLocally giả mạo, khách hàng giải thích tất cả các đầu vào để sản xuất dữ liệu mà nó gửi cho máy chủ để thực hiện kéoTrong chế độ này, tất cả các tín hiệu sự kiện tùy chỉnh và chức năng đã đăng ký phải ở trong máy chủ Scripts .
Khi thuộc tính RunLocally là true, không có sự kiện nào được sao chép lên máy chủ.Tất cả các tín hiệu sự kiện tùy chỉnh và chức năng đã đăng ký phải ở trong khách hàng LocalScripts và bạn phải sử dụng sự kiện từ xa để truyền đạt các thay đổi cần thiết cho máy chủ.
Phản ứng kịch bản đến việc nhấp và kéo
Thông qua các tín hiệu sự kiện , thay đổi tính chất, kiểu kéo, và chức năng tùy chỉnh, các kịch bản có thể đáp ứng sự thay đổi của các đối tượng bị kéo để điều khiển giao diện người dùng hoặc đưa ra các quyết định logic, chẳng hạn như điều chỉnh mức độ sáng trong một phòng dựa trên công tắc chuyển đổi tường trượt.
Tín hiệu sự kiện
Thông qua các tín hiệu sự kiện sau, bạn có thể phát hiện khi người dùng bắt đầu, tiếp tục và kết thúc kéo một đối tượng.
Sự kiện | Mô tả |
---|---|
DragStart | Bắt lửa khi người dùng bắt đầu kéo đối tượng. |
DragContinue | Bắt lửa khi người dùng tiếp tục kéo đối tượng sau khi DragStart đã được khởi động. |
DragEnd | Bắt lửa khi người dùng ngừng kéo đối tượng. |
Detector kéo - Tín hiệu sự kiện
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)
Thay đổi khung kéo
Ngoài các tín hiệu sự kiện , bạn có thể theo dõi các thay đổi đến của cảm biến trực tiếp.
DragDetector - Thay đổi DragFrame
local dragDetector = script.Parent.DragDetector
dragDetector:GetPropertyChangedSignal("DragFrame"):Connect(function()
local currentDragTranslation = dragDetector.DragFrame.Position
print(currentDragTranslation)
end)
Kiểu kéo được lập trình
Nếu bạn đặt chức năng của một cảm biến thành DragStyle để Thể thao , bạn có thể cung cấp chức năng riêng của mình mà nhận Ray và trả về không gian thế giới CFrame .Bộ cảm biến sẽ di chuyển chuyển động để vật phẩm bị kéo đi đến vị trí/hướng tùy chỉnh đó.
DragDetector - Phong cách kéo được lập trình
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)
-- Bỏ vật phẩm bị kéo ra khỏi việc phát hiện 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)
Chức năng giới hạn tùy chỉnh
Các máy dò kéo không có các quy tắc chuyển động tích hợp về lưới và ghim, nhưng bạn có thể đăng ký chức năng giới hạn tùy chỉnh để chỉnh sửa cảm biến trước khi nó được áp dụng DragFrame.Ví dụ, bạn có thể giữ chuyển động trên lưới bằng cách làm tròn vị trí thành nhân số của tăng trưởng lưới, hoặc mô phỏng một trò chơi cờ với các quy tắc chuyển động hợp pháp cho mỗi khối.
DragDetector - Chức năng hạn chế tùy chỉnh
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()
Ví dụ sử dụng
Vật lý không neo cố định
Một thực hiện cơ bản của cảm biến kéo là một trò chơi cân bằng tháp mà người chơi phải cẩn thận loại bỏ các khối và cố gắng giữ cho tháp thẳng.Trong cấu trúc tháp tiếp theo, mỗi khối có một đứa con DragDetector với một đứa con mặc định DragStyle của TranslatePlane để người chơi có thể kéo các khối ra ngoài nhưng không lên trên hoặc xuống dưới.
Mô hình neo với các bộ phận có thể điều chỉnh
Bạn có thể dễ dàng tạo và chia sẻ các mô hình được neo chính yếu, nhưng có một hoặc nhiều phần con/mô hình con mà người chơi có thể kéo.Ví dụ, bàn làm việc sau có hai ngăn kéo mà người chơi có thể mở để kiểm tra những gì ở bên trong.
Kéo cảm biến và hạn chế
Bạn có thể kết hợp cảm biến kéo với Constraints , ví dụ như một con rối marionette.Trong cài đặt tiếp theo, các tay cầm điều khiển được neo, các bộ phận cơ thể không neo và các hạn chế giữ nhân vật cùng nhau.Di chuyển các tay cầm với TranslateViewPlane DragStyle làm cho vũ điệu marionette, và các bộ phận cơ thể cá nhân cũng có thể được di chuyển bằng cảm biến kéo, trong khi mô hình vẫn giữ nguyên sự nguyên vẹn.
Giao diện người dùng 3D
Giao diện người dùng 3D dễ dàng đạt được thông qua cảm biến kéo, chẳng hạn như điều chỉnh độ sáng của một SpotLight dựa trên một công tắc chuyển đổi độ mờ.Bạn cũng có thể phát hiện các trục X và Z riêng lẻ để kiểm soát hai khía cạnh khác nhau của giao diện người dùng 3D, chẳng hạn như Size, Speed và Color của một ParticleEmitter .
DragDetector - Giao diện người dùng 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
-- Điều chỉnh kích thước và tốc độ hạt dựa trên yếu tố X của máy dò kéo
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)
-- Chỉnh màu hạt dựa trên yếu tố Z cảm biến kéo
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)