การตรวจจับการโจมตี คือกระบวนการระบุว่าเมื่อการระเบิดชนกับผู้เล่น จากนั้นลดสุขภาพของพวกเขาตามลำดับ ในระดับสูง คุณสามารถคิดว่างานนี้เป็น:
- การตรวจสอบทางกายภาพว่าโครงการได้ตีเป้าหมายหรือไม่
- การตรวจสอบอย่างรวดเร็วว่าเครื่องปืนเป้าหมาย
ประเภทของการตรวจจับการโจมตีที่คุณใช้ขึ้นอยู่กับความต้องการในการเล่นเกมของประสบการณ์ของคุณ ตัวอย่างเช่น การตรวจจับการโจมตีแบบกายภาพเหมาะ
โดยใช้ประสบการณ์ เลเซอร์เต็มแสงเป็นตัวอย่าง เป็นตัวอ้างอิง ส่วนนี้ของการฝึกสอนสอนคุณเกี่ยวกับสคริปต์ที่อยู่เบื้องหลังการตรวจจับการโจมตีในพื้นที่ 3D รวมถึงคำแนะนำเกี่ยวกับ:
- พิมพ์
- ส่งรังสีในเส้นทางตรงจากตัวปล่อยไฟเมื่อมันระเบิด
- การตรวจสอบระเบิดเพื่อป้องกันการโจมตีของข้อมูลระเบิด
- ลดพลังชีวิตของผู้เล่นตามความเสียหายจากแต่ละประเภทของปืนฉีดน้ำแข็งและจำนวนรังสีที่ตรงตัวผู้เล่น
หลังจากที่คุณเสร็จสิ้นส่วนนี้ คุณสามารถสำรวจหัวข้อการพัฒนาเพิ่มเติมเพื่อเพิ่มประสิทธิภาพในการเล่นเกมของคุณ เช่นเสียง แสง และเอฟเฟ็กต์พิเศษ
รับทิศทางระเบิด
หลังจากผู้เล่นระเบิดปืนของพวกเขา, ReplicatedStorage > Blaster > attemptBlastClient > 1> blastClient1> > 4> generateBlastData4> เรียกสองฟังก์ชันเพื่อเริ่มกระบว
สร้างระเบิดข้อมูล
local rayDirections = getDirectionsForBlast(currentCamera.CFrame, blasterConfig)local rayResults = castLaserRay(localPlayer, currentCamera.CFrame.Position, rayDirections)
การป้อนข้อมูลสำหรับ rayDirections เป็นเรื่องง่าย: ตำแหน่งกล้องปัจจุบันและค่าการหมุน และประเภทของลาเซอร์
อย่างไรก็ตามเนื่องจากตัวอย่างนี้ให้ตัวเร่งชนิดเสริมที่ผลิตลำแสงเลเซอร์หลายลำแสงด้วยความกว้างและการแพร่กระจายที่กว้าง getDirectionsForBlast จะต้องคำนวณทิศทางสำหรับแต่ละลำแสงของ
รับทิศทางสำหรับการระเบิด
if numLasers == 1 then-- สำหรับเลเซอร์เดี่ยวพวกเขาเล็งตรงtable.insert(directions, originCFrame.LookVector)elseif numLasers > 1 then-- สำหรับเลเซอร์หลายตัว กระจายพวกเขาออกไปในแนวตั้งเท่ากัน-- การแผ่กระจายของเลเซอร์รอบ ๆ ศูนย์local leftAngleBound = laserSpreadDegrees / 2local rightAngleBound = -leftAngleBoundlocal degreeInterval = laserSpreadDegrees / (numLasers - 1)for angle = rightAngleBound, leftAngleBound, degreeInterval dolocal direction = (originCFrame * CFrame.Angles(0, math.rad(angle), 0)).LookVectortable.insert(directions, direction)endend
พิมพ์ ตั้งแต่ แล้
if numLasers == 1 thentable.insert(directions, originCFrame.LookVector)elseif numLasers > 1 thenlocal leftAngleBound = laserSpreadDegrees / 2local rightAngleBound = -leftAngleBoundlocal degreeInterval = laserSpreadDegrees / (numLasers - 1)for angle = rightAngleBound, leftAngleBound, degreeInterval dolocal directionif spreadDirection == "vertical" thendirection = (originCFrame * CFrame.Angles(math.rad(angle), 0, 0)).LookVectorelsedirection = (originCFrame * CFrame.Angles(0, math.rad(angle), 0)).LookVectorendtable.insert(directions, direction)endendreturn directions
ในท้ายที่สุด, การใช้งาน rayDirections() กลับมาเป็นตารางขนาด Vectors ที่แสดงความเป็นเลเซอร์แต่ละลำแสง หากมีประโยชน์, คุณสามารถเพิ่มบางบันทึกเพื่อให้ความรู
สร้างระเบิดข้อมูล
local rayDirections = getDirectionsForBlast(currentCamera.CFrame, blasterConfig)for _, direction in rayDirections do -- ใหม่ lineprint(direction) -- ใหม่ lineend -- ใหม่ linelocal rayResults = castLaserRay(localPlayer, currentCamera.CFrame.Position, rayDirections)
โคมตรี
castLaserRay() , ฟังก์ชันที่สองใน ReplicatedStorage > Blaster ข้อมูลนี้มีประโยชน์อย่างมากสำหรับประสบการณ์ผู้ประกอบการในบุคคลที่สองเพราะมันช่วยให้คุณสามารถดูเมื่อและที่สะสมของระเบิดปะทะกับผู้
พารามิเตอร์ castLaserRay() ระบุว่าการเรียก Raycast() ต้องพิจารณาทุกส่วนในพื้นที่ทํางาน ยกเว้นตัวละครที่ระเบิด สคริปต์จะ
- Distance – ระยะทางระหว่างจุดเริ่มต้นของรังสีและจุดสิ้นสุด
- Material – เวลา Enum.Material ที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรงสถานที่ตรง
ค่า Instance มีความสำคัญที่สุดในเกมเลเซอร์แท็กสําหรับเกมเลเซอร
castLaserRay() จากนั้นใช้ Position และ Normal เพื่อสร
castLaserRay
if result then-- ระเบิดตีบางอย่าง ตรวจสอบว่ามันเป็นผู้เล่นหรือไม่destination = CFrame.lookAt(result.Position, result.Position + result.Normal)taggedPlayer = getPlayerFromDescendant(result.Instance)else-- ระเบิดไม่ได้โจมตีอะไร ดังนั้นจุดหมายปลายทางของมันจึง-- จุดที่อยู่ในระยะไกลสุดของมันlocal distantPosition = origin + rayDirection * MAX_DISTANCEdestination = CFrame.lookAt(distantPosition, distantPosition - rayDirection)taggedPlayer = nilend
ยืนยันการระเบิด
เพื่อป้องกันการโกง บทความก่อนหน้านี้ การใช้ Blaster อธิบายวิธีการ <
ก่อนอื่น getValidatedRayResults เรียก validateRayResult เพื่อตรวจสอบว่าแต่ละรายการในตาราง rayResults จากลูกค้าเป็น 1> Datatype.CFrame1> และ 4> Player4> (หรือ zero)
ต่อไป, มันเรียก isRayAngleFromOriginValid เพื่อเปรียบเทียบมุมมองที่คาดหวังของเลเซอร์สเปรดไปยังมุมมองของลูกค้า โค้ดนี้ในเฉพาะแสดงข้อดีของการใ
เช่นเดียวกับการรับรองด้วยเลเซอร์จากบทที่ก่อนหน้านี้, isRayAngleFromOriginValid ใช้ค่าความอดทนเพื่อกำหนดว่าอะไรคือความแตกต่างที่ "เกินขีด" ในมุม:
isRayAngleFromOriginlocal claimedDirection = (rayResult.destination.Position - originCFrame.Position).Unitlocal directionErrorDegrees = getAngleBetweenDirections(claimedDirection, expectedDirection)return directionErrorDegrees <= ToleranceValues.BLAST_ANGLE_SANITY_CHECK_TOLERANCE_DEGREESRoblox ลดเมฆอันเกี่ยวข้องมากที่สุดของคณิตศาสตร์ออกจึงทำให้ผลลัพธ์เป็นตัวช่วยที่เป็นประโยชน์เฉพาะเจาะจงสำหรับการใช้งานในหลากหลาย:
รับมุมมองlocal function getAngleBetweenDirections(directionA: Vector3, directionB: Vector3)local dotProduct = directionA:Dot(directionB)local cosAngle = math.clamp(dotProduct, -1, 1)local angle = math.acos(cosAngle)return math.deg(angle)endการตรวจสอบครั้งต่อไปเป็นเรื่องที่เข้าใจได้มากที่สุด ในขณะที่ getValidatedBlastData ใช้ DISTANCE_SANITY_CHECK_TOLERANCE_STUDS เพื่อยืนยันว่าผู้เล
เป็นผู้เล่นใกล้ตำแหน่งlocal distanceFromCharacterToPosition = position - character:GetPivot().Positionif distanceFromCharacterToPosition.Magnitude > ToleranceValues.DISTANCE_SANITY_CHECK_TOLERANCE_STUDS thenreturn falseendการตรวจสอบครั้งสุดท้าย isRayPathObstructed สภาพแวดล้อมๆ จา
คือ RayPathObstructedlocal scaledDirection = (rayResult.destination.Position - blastData.originCFrame.Position)scaledDirection *= (scaledDirection.Magnitude - 1) / scaledDirection.Magnitude
ไม่มีกลยุทธ์ป้องกันการโจมตีที่กวดวิด แต่มีความสำคัญที่จะพิจารณาวิธีการที่ผู้เล่นอาจใกล้ประสบการณ์ของคุณเพื่อให้คุณสามารถวางการตรวจสอบในสถานที่ที่เซิร์ฟเวอร์สามารถดำเนินการเพื่อตรวจสอบพฤต
ลดสุขภาพผู้เล่น
หลังจากยืนยันว่าผู้เล่นป้ายผู้เล่นอื่นผู้เล่นสามารถทำตามขั้นตอนสุดท้ายในการเสร็จสิ้นวงจรเกมหลักในประสบการณ์ติดแท็กเลเซอร์ในตัวอย่างได้รับการยืนยันผู้เล่นจะลดสุขภาพของผู้เล่นเพิ่ม
เริ่มต้นด้วยการลดสุขภาพของผู้เล่นที่มีชื่อ, การเกิดและ
ประสบการณ์เก็บค่าความเสียหายในลักษณ
Health ไม่รองรับค่าตัวละครที่เป็นบวก ดังนั้น onPlayerTagged จึงมีบางส่วนที่มีโลจิกในการให้สุขภาพข
วิธีนี้ในการอยู่ใกล้ปัญหาอาจดูซับซ้อน เช่น ทำไมไม่เพียงแค่ตั้งค่าสุขภาพของผู้เล่นเป็นศูนย์หากมันจะเป็นบวก? เหตุผลคือเพราะการตั้งค่าค่าสุขภาพจะหลีกเลี
บนPlayerTagged
local function onPlayerTagged(playerBlasted: Player, playerTagged: Player, damageAmount: number)
local character = playerTagged.Character
local isFriendly = playerBlasted.Team == playerTagged.Team
-- ป้องกันไฟเป็นมิตร
if isFriendly then
return
end
local humanoid = character and character:FindFirstChild("Humanoid")
if humanoid and humanoid.Health > 0 then
-- หลีกเลี่ยงสุขภาพที่เป็นบวก
local damage = math.min(damageAmount, humanoid.Health)
-- TakeDamage รับประกันว่าสุขภาพจะไม่ลดลงหาก ForceField เปิดใช้งาน
humanoid:TakeDamage(damage)
if humanoid.Health <= 0 then
-- มอบรางวัลผู้เล่นที่ระเบิดแต้มสำหรับการแท็กผู้เล่นที่ถูกแท็ก
Scoring.incrementScore(playerBlasted, 1)
end
end
end
ตารางอันดับอาจไม่จำเป็นสำหรับ LaserBlastHandler ที่จะรวมผู้เล่นที่ระเบิดอยู่ใกล้กับข้อมูลระเบิด แต่โดยไม่มีข้อมู
ห้าบทในหลักสูตรนี้ครอบคลุมการเล่นเกมหลักของประสบการณ์ แต่ยังมีพื้นที่ให้สำรวจมากมาย เช่น:
- วิดีโอบลาสเตอร์ : ดู ReplicatedStorage > FirstPersonBlasterVisuals และ 0> ServerScriptService0> > 3> ThirdPersonBlasterVisuals 3> .
- เสียง : ดู ReplicatedStorage > SoundHandler * โหมดกําหนดเอง : คุณสามารถปรับแต่งประสบการณ์นี้เพื่อนําเสนอประเภทของเป้าหมายใหม่ เช่นการคะแนนสูงสุดก่อนที่จะหมดเวลา?
สำหรับเหตุผลการเล่นเกมที่ขับเคลื่อนโดยเลเซอร์สำหรับประสบการณ์เลเซอร์แท็กซ์รวมถึงสินทรัพย์สภาพแวดล้อมที่มีคุณภาพสูงและใช้ได้หลายครั้ง เลเซอร์แท็ก รูปแบบ