ตัวอย่าง DragDetector ช่วยอำนวยความสะดวกและส่งเสริมการโต้ตอบกับวัตถุ 3D ในประสบการณ์ เช่น เปิดประตูและลิ้นชัก เลื่อนชิ้นส่วนไปรอบๆ คว้าและโยนลูกบอลโบว์ล ดึงกลับและยิงปืนพก และอื่นๆ อีกมากมายคุณสมบัติสําคัญรวมถึง:
วาง DragDetector ภายใต้ใดก็ได้ BasePart หรือ Model เพื่อ ทำให้มันลากได้ ผ่านทุกอินพุต (เมาส์, แตะ, เกมแพด, และ VR) รหัส
เลือกจากหลายรูปแบบ ลากและวาง , กำหนดวิธีที่วัตถุ ตอบสนองต่อการเคลื่อนไหว และใช้ตัวเลือก ขีดจํากัดแกนหรือการเคลื่อนที่ ได้
สคริปต์สามารถตอบสนองต่อการควบคุมวัตถุที่ลากไปได้ เพื่อขับเคลื่อน UI หรือตัดสินใจทางเหตุผล เช่น ปรับระดับแสงในห้องตามสวิตช์กำแพงเลื่อนดิมเมอร์
ผู้เล่นสามารถควบคุมชิ้นส่วนหรือโมเดลที่ติดอยู่ได้ และพวกเขาจะอยู่ในตำแหน่งที่คุณวางไว้เมื่อปล่อยออกมา
DragDetectors ทำงานในสตูดิโอตราบใดที่คุณไม่ได้ ไม่ใช้ เครื่องมือ เลือก , ย้าย , ขนาด หรือ หมุน เครื่องมือทำให้ง่ายต่อการทดสอบและปรับเปลี่ยนวัตถุที่สามารถลากได้ในขณะที่กำลังแก้ไข
ทำให้วัตถุเป็นรูปแบบลากได้
เพื่อทำให้ส่วนหรือโมเดลใดก็ได้เป็นแบบลากได้ เพียงเพิ่ม DragDetector เป็นลูกหลานโดยตรง
จากเมนูใส่ DragDetector
โดยค่าเริ่มต้น ตอนนี้วัตถุจะสามารถลากได้ในแผ่นดิน แต่คุณสามารถปรับแต่ง DragStyle ของมันได้ว่าจะตอบสนองต่อการเคลื่อนไหวอย่างไร และสามารถใช้ ขีดจํากัดแกนหรือการเคลื่อนที่ได้ตามต้องการ
ปรับแต่งตัวตรวจจับการลาก
ลากสไตล์
DragDetectors เคลื่อนเคอร์เซอร์แผนที่ไปยังเส้นและแผนการเสมือนเพื่อคำนวณการเคลื่อนไหว 3D ที่เสนอผ่านคุณสมบัติ DragStyle คุณสามารถเลือกจากแผนที่ต่างๆ เพื่อตอบสนองความต้องการของคุณตัวอย่างเช่น TranslatePlane ผลิตการแปลในเครื่องบินเสมือนในขณะที่ RotateAxis ผลิตการหมุนเกี่ยวกับเครื่องบินเสมือน
การตั้งค่า | คําอธิบาย |
---|---|
TranslateLine | การเคลื่อนไหว 1D ตามแนวนักตรวจจับ Axis โดยค่าเริ่มต้นคือแกนโลก Y |
TranslatePlane | การเคลื่อนไหว 2D ในเครื่องบินที่ตั้งฉากกับเครื่องตรวจจับ Axis โดยปกติจะเป็นเครื่องบิน XZ ของโลก |
TranslatePlaneOrLine | การเคลื่อนไหว 2D ในเครื่องบินตั้งฉากกับตัวตรวจจับ Axis และเมื่อ modifier ใช้งานอยู่ การเคลื่อนไหว 1D ตามเส้นตรวจจับ Axis |
TranslateLineOrPlane | การเคลื่อนไหว 1D ตามแนวนอนของเครื่องตรวจจับ Axis และเมื่อ modifier ใช้งานอยู่ การเคลื่อนไหว 2D ในแนวนอนตรงข้ามกับเครื่องตรวจจับ Axis |
TranslateViewPlane | การเคลื่อนไหว 2D ในเครื่องบินที่ตั้งฉากกับมุมมองของกล้องในโหมดนี้เครื่องบินจะได้รับการอัปเดตอย่างต่อเนื่องแม้ในขณะที่ลากและจะเผชิญกับมุมมองปัจจุบันของกล้องเสมอ |
RotateAxis | การหมุนรอบเซนเซอร์ของ Axis โดยค่าเริ่มต้นคือแกนโลก Y |
RotateTrackball | การหมุนลูกศรติดตามต่อไปโดยการปรับแต่งเพิ่มเติมผ่านคุณสมบัติ TrackballRadialPullFactor และ TrackballRollFactor |
BestForDevice | แปลเครื่องบินหรือเส้น สำหรับเมาส์และเกมแพด; แปลเครื่องบิน สำหรับการสัมผัส; 6DOF สำหรับ VR |
Scriptable | คำนวณการเคลื่อนไหวที่ต้องการผ่านฟังก์ชันที่กําหนดเองที่ให้ผ่านทาง SetDragStyleFunction() |
ลากทิศทาง
โดยค่าเริ่มต้น การเคลื่อนไหว 3D และแผนที่ที่เกี่ยวข้อง DragStyle ไปยังพื้นที่โลกอย่างไรก็ตาม คุณอาจต้องการเปลี่ยน ReferenceInstance , Orientation หรือ Axis ตัวอย่างเช่นเมื่อสร้างตัวตรวจจับลากไปยัง โมเดลที่สามารถปรับได้
คุณสมบัติ | คําอธิบาย | ค่าเริ่มต้น |
---|---|---|
ReferenceInstance | ตัวอย่างที่สามารถให้เฟรมอ้างอิง สำหรับตัวตรวจจับแรงดึง สำหรับตัวตรวจจับแรงดึงThe DragFrame ถูกแสดงเป็นค่าสัมพันธ์กับกรอบอ้างอิงนี้ซึ่งสามารถดึงได้ผ่าน GetReferenceFrame()หากกรอบอ้างอิงเป็น nil การแปลจะอยู่ในทิศทางของ (หรือในแนวตั้งฉากกับ) คุณสมบัติ Axis ในพื้นที่โลก | nil |
Orientation | ระบุการหมุน YXZ ของแกนการเคลื่อนที่เมื่อเทียบกับกรอบอ้างอิง (ไม่เปลี่ยนทิศทางของกรอบอ้างอิงเอง)การแปลเชิงเส้นและการหมุนแบบเขวี้ยงจะอยู่บนแกนหมุนเชิงเส้นนี้ Y และการแปลแบบเรียบในแพลน XZ การเปลี่ยนค่านี้โดยอัตโนมัติจะอัปเดต Axis และกลับกัน | (0, 0, 0) |
Axis | แกนหลักของการเคลื่อนไหวที่แสดงเป็นค่าเปรียบเทียบกับกรอบอ้างอิง การเปลี่ยนค่านี้จะอัปเดตอัตโนมัติ Orientation และกลับกัน | (0, 1, 0) |
การตอบสนองต่อการเคลื่อนไหว
คุณสมบัติ ResponseStyle กำหนดวิธีที่วัตถุตอบสนองต่อการเคลื่อนไหวที่เสนอขึ้น ขึ้นอยู่กับว่าวัตถุเป็น Anchored หรือไม่
การตั้งค่า | พฤติกรรมที่ติดตั้งอยู่ | พฤติกรรมที่ไม่ได้รับการยึดถือ |
---|---|---|
Geometric | ทั้งภายในประสบการณ์การทำงานและในโหมดการแก้ไขสตูดิโอ ตำแหน่ง/ทิศทางของวัตถุที่ติดตั้งจะได้รับการอัปเดตเพื่อสะท้อนการเคลื่อนไหวที่เสนอได้อย่างถูกต้อง | สำหรับวัตถุที่ไม่ได้ติดตั้ง พฤติกรรมจะเหมือนกับวัตถุที่ติดตั้งอย่างไรก็ตามในประสบการณ์ที่กําลังดําเนินอยู่วัตถุจะถูกยึดที่จุดเริ่มต้นของการลากและฟื้นฟูกลับเป็นค่าที่ไม่ได้ยึดเมื่อปล่อยการลาก |
Physical | วัตถุที่ถูกยึดจะเริ่มต้นด้วยพฤติกรรมทางเรขาคณิต เนื่องจากไม่ได้รับผลกระทบจากแรง | วัตถุที่ไม่ได้ติดตั้งจะถูกย้ายโดย แรงข้อจํากัด ที่พยายามนําไปสู่ตําแหน่งและ/หรือทิศทางที่ต้องการโดยการเคลื่อนไหวที่เสนอ |
Custom | วัตถุจะไม่เคลื่อนที่เลย แต่ DragFrame จะยังคงได้รับการอัปเดตและคุณสามารถ ตอบสนองต่อการจัดการลากได้ อย่างที่คุณต้องการ | (เหมือนกับที่ถูกยึด) |
ขีดจํากัดแกนและการเคลื่อนที่
โดยค่าเริ่มต้นจะไม่มีข้อจํากัดสำหรับการเคลื่อนไหว 3D เกินข้อจํากัดที่มีอยู่แล้วของ DragStyleหากจำเป็น คุณสามารถใช้ขีดจํากัดขั้นต่ําและสูงสุดสำหรับทั้งการแปลและการหมุนหมายเหตุ, อย่างไรก็ตาม, ข้อจํากัดเหล่านี้ไม่ใช่ข้อจํากัด; พวกเขาเพียงแค่ขัดขวางความพยายามของเครื่องตรวจจับการเคลื่อนไหวในการสร้างการเคลื่อนไหวเพื่ออยู่ภายในขอบเขต
คุณสมบัติ | คําอธิบาย | ค่าเริ่มต้น |
---|---|---|
Class.DragDetector.MinDragTranslation|MinDragTranslation``Class.DragDetector.MaxDragTranslation|MaxDragTranslation | ข้อจํากัดในการลากแปลในแต่ละมิติ หาก MaxDragTranslation มากกว่า MinDragTranslation การแปลจะถูกขัดขวางภายในช่วงนั้น | (0, 0, 0) |
Class.DragDetector.MinDragAngle|MinDragAngle``Class.DragDetector.MaxDragAngle|MaxDragAngle | เกี่ยวข้องเฉพาะถ้า DragStyle ถูกตั้งค่าเป็น RotateAxis หาก MaxDragAngle มากกว่า MinDragAngle การหมุนจะถูกจำกัดภายในช่วงนั้น | 0 |
ลากสิทธิ์
สิทธิ์ของผู้เล่นที่จะโต้ตอบกับตัวตรวจจับแรงดึงที่กำหนดได้สามารถระบุได้โดยคุณสมบัติ PermissionPolicyตั้งค่านี้เป็น Enum.DragDetectorPermissionPolicy.Everybody โดยค่าเริ่มต้นและสามารถเปลี่ยนเป็นการสนับสนุนการควบคุมสิทธิ์แบบสคริปต์ได้ตามที่แสดงในตัวอย่างโค้ด
การตั้งค่า | คําอธิบาย |
---|---|
Nobody | ผู้เล่นไม่สามารถโต้ตอบกับ DragDetector ได้ |
Everybody | ผู้เล่นทุกคนสามารถโต้ตอบกับ DragDetector ได้ |
Scriptable | สิทธิ์ในการลากของผู้เล่นจะถูกกำหนดโดยฟังก์ชันที่ลงทะเบียนผ่าน SetPermissionPolicyFunction()ภายใต้การตั้งค่านี้ การลงทะเบียนฟังก์ชันไม่สําเร็จหรือการส่งผลลัพธ์ที่ไม่ถูกต้องจะป้องกันไม่ให้ผู้เล่นทั้งหมดลาก |
ตรวจจับการลาก - สิทธิ์การลากที่เขียนโปรแกรมไว้
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)
การตอบสนองทางฟิสิกส์
คาดว่าสไตล์การตอบสนองของผู้ลากจูง จะถูกตั้งค่าเป็น กายภาพ และมันจะถูกนำไปใช้กับวัตถุที่ไม่ได้ติดตั้ง วัตถุนั้นจะถูกย้ายโดยแรงข้อจำกัดที่พยายามนํามันไปสู่ตําแหน่ง/ทิศทางที่กำหนดโดยการเคลื่อนไหวที่เสนอคุณสามารถปรับแต่งคำตอบทางกายภาพต่อไปผ่านคุณสมบัติต่อไปนี้:
คุณสมบัติ | คําอธิบาย | ค่าเริ่มต้น |
---|---|---|
ApplyAtCenterOfMass | เมื่อเท็จ, แรงลากจะถูกใช้ที่จุดที่ผู้ใช้คลิก เมื่อถูกต้อง, แรงจะถูกใช้ที่ศูนย์กลางของมวลของวัตถุ | ปิด |
MaxForce | แรงสูงสุดที่ใช้กับวัตถุเพื่อให้บรรลุเป้าหมาย | 10000000 |
MaxTorque | แรงบิดสูงสุดที่ใช้กับวัตถุเพื่อให้บรรลุเป้าหมาย | 10000 |
Responsiveness | มูลค่าที่สูงกว่าทำให้วัตถุบรรลุเป้าหมายได้เร็วขึ้น | 10 |
การปรับเปลี่ยนการใส่ข้อมูล
บางโหมด DragStyle ช่วยให้ผู้ใช้กดค้างปุ่ม แก้ไข ไว้เพื่อที่จะควบคุมวัตถุที่ลากไปในรูปแบบที่แตกต่างกันโดยค่าเริ่มต้น ตัวแก้ไขจะเป็น LeftControl บนพีซี ButtonR1 บนเกมแพด หรือ ButtonL2 บน VRคุณสามารถปรับแต่งตัวปรับเปลี่ยนเหล่านี้ผ่าน KeyboardModeSwitchKeyCode , GamepadModeSwitchKeyCode หรือ VRSwitchKeyCode คุณสมบัติของตัวระบุตําแหน่งลากได้
การเลียนแบบ
เมื่อคุณสมบัติ RunLocally เป็นเท็จ (ค่าเริ่มต้น) ไคลเอนต์จะตีความทั้งหมดของการใส่เพื่อผลิตข้อมูลที่ส่งไปยังเซิร์ฟเวอร์เพื่อดำเนินการลากในโหมดนี้ สัญญาณกิจกรรมและฟังก์ชันที่กําหนดเองทั้งหมดจะต้องอยู่ในเซิร์ฟเวอร์ Scripts
เมื่อคุณสมบัติ RunLocally เป็นจริงไม่มีการสําเนาอีเวนต์ไปยังเซิร์ฟเวอร์สัญญาณกิจกรรมที่กําหนดเองทั้งหมดและฟังก์ชันที่ลงทะเบียนต้องอยู่ในไคลเอนต์ LocalScripts และคุณต้องใช้ กิจกรรมระยะไกล เพื่อแพร่กระจายการเปลี่ยนแปลงที่จําเป็นให้กับเซิร์ฟเวอร์
การตอบสนองของสคริปต์เมื่อคลิกและลาก
ผ่านสัญญาณอีเว้นท์ , การเปลี่ยนแปลงคุณสมบัติ, Scriptable สไตล์การลาก, และฟังก์ชันที่กําหนดเอง, สคริปต์สามารถตอบสนองต่อการจัดการของวัตถุที่ลากไปเพื่อขับ UI หรือตัดสินใจทางเหตุผล เช่น ปรับระดับแสงในห้องตามสวิตช์ดิมเมอร์กำแพงเลื่อน
สัญญาณกิจกรรม
ผ่านสัญญาณกิจกรรมต่อไปนี้คุณสามารถตรวจพบเมื่อผู้ใช้เริ่มต้น ดำเนินการต่อ และสิ้นสุดการลากวัตถุ
อีเวนต์ | คําอธิบาย |
---|---|
DragStart | เกิดไฟไหม้เมื่อผู้ใช้เริ่มลากวัตถุ |
DragContinue | เกิดไฟไหม้เมื่อผู้ใช้ดึงวัตถุต่อไปหลังจากที่ DragStart ได้รับการเริ่มต้นแล้ว |
DragEnd | เกิดไฟไหม้เมื่อผู้ใช้หยุดลากวัตถุ |
เครื่องตรวจจับลาก - สัญญาณกิจกรรม
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)
ลากเปลี่ยนกรอบ
นอกจากสัญญาณการเหตุ คุณสามารถตรวจสอบการเปลี่ยนแปลงในตัวรับสัญญาณ DragFrame โดยตรง
ตรวจจับการลาก - การเปลี่ยนแปลงกรอบลาก
local dragDetector = script.Parent.DragDetector
dragDetector:GetPropertyChangedSignal("DragFrame"):Connect(function()
local currentDragTranslation = dragDetector.DragFrame.Position
print(currentDragTranslation)
end)
สไตล์การลากที่เขียนโปรแกรมไว้
หากคุณตั้งค่าตัวตรวจจับ DragStyle เป็น สามารถใช้งานได้ คุณสามารถให้ฟังก์ชันของคุณเองที่รับ Ray และส่งคืนพื้นที่โลก CFrameเครื่องตรวจจะเคลื่อนที่การเคลื่อนไหวเพื่อให้วัตถุที่ลากไปอยู่ในตำแหน่งหรือทิศทางที่กําหนด
ตรวจจับสไตล์การลาก - สคริปต์สไตล์การลาก
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)
-- ยกเลิกวัตถุที่ลากออกจากการตรวจจับรังสี
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)
ฟังก์ชันข้อจํากัดที่กําหนดเอง
ตัวตรวจจับแบบลากไม่มีกฎการเคลื่อนไหวที่ติดตั้งไว้เกี่ยวกับกริดและการสแน็ป แต่คุณสามารถลงทะเบียนฟังก์ชันข้อจํากัดที่กําหนดเองเพื่อเเก้ไขตัวตรวจจับได้ก่อนที่จะถูกใช้ตัวอย่างเช่น คุณสามารถรักษาการเคลื่อนไหวบนกริดโดยการรอบตำแหน่งเป็นหลายเท่าของการเพิ่มของกริดหรือจำลองเกมหมากรุกด้วยกฎการเคลื่อนไหวที่ถูกกฎหมายสำหรับแต่ละชิ้น
ตรวจจับลาก - ฟังก์ชันข้อจำกัดที่กำหนดเอง
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()
การใช้งานตัวอย่าง
วัตถุทางกายภาพที่ไม่ได้ติดตั้งอยู่
การดําเนินการพื้นฐานของตัวตรวจจับลากคือเกมสมดุลของทาวเวอร์ที่ผู้เล่นต้องลบชิ้นส่วนอย่างระมัดระวังและพยายามรักษาทาวเวอร์ให้ตั้งตรงในโครงสร้างทาวเวอร์ต่อไปนี้แต่ละชิ้นมีลูก DragDetector ด้วยค่าเริ่มต้นของ DragStyle ของ TranslatePlane ดังนั้นผู้เล่นสามารถดึงชิ้นออกไปด้านนอกแต่ไม่ได้ขึ้นหรือลง
โมเดลที่ติดตั้งอยู่ด้วยชิ้นส่วนที่ปรับได้
คุณสามารถสร้างและแบ่งปันโมเดลที่มีหลักฐานเป็นหลัก แต่มีส่วนหรือโมเดลลูกบนหนึ่งหรือมากกว่าที่ผู้เล่นสามารถลากได้ตัวอย่างเช่น โต๊ะต่อไปนี้มีลิ้นชักสองชิ้นที่ผู้เล่นสามารถเปิดเพื่อตรวจสอบสิ่งที่อยู่ภายใน
ลากตัวตรวจจับและข้อจำกัด
คุณสามารถรวมตัวตรวจจับการลากกับ Constraints ตัวอย่างเช่นหุ่นละครหุ่นในการตั้งค่าต่อไปนี้ การควบคุมจัดอยู่บนฐาน ส่วนของร่างกายไม่ได้รับการยึด และข้อจํากัดรักษามาริออนไว้ด้วยกันการย้ายจัดก้านด้วย TranslateViewPlane DragStyle ทำให้มาริออนเต้นรํา และส่วนตัวบอดี้แต่ละส่วนอาจถูกย้ายด้วยตัวตรวจจับลากทั้งหมดในขณะที่โมเดลยังคงรักษาความสมบูรณ์ไว้
อินเทอร์เฟซผู้ใช้ 3D
อินเทอร์เฟซผู้ใช้ 3D สามารถเข้าถึงได้ง่ายผ่านตัวตรวจจับการลาก เช่น ปรับความสว่างของ SpotLight ตามสวิตช์สไลเดอร์ที่เลื่อนคุณยังสามารถตรวจจับแกน X และ Z แยกต่างหากเพื่อควบคุมสองด้านที่แตกต่างกันของอินเทอร์เฟซผู้ใช้ 3D เช่น Size , Speed และ Color ของ ParticleEmitter
ตรวจจับ - อินเทอร์เฟซผู้ใช้ 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
-- ปรับขนาดและความเร็วของอนุภาคตามตัวชี้วัดการลาก 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)
-- ปรับสีอนุภาคตามตัวตรวจจับแรงดึง 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)