Một HUD hay Heads-Up Display là một tập hợp các thành phần UI luôn hiển thị hoặc có thể truy cập trong suốt quá trình chơi game, chẳng hạn như hiển thị điểm số, đồng hồ sức khỏe và các nút menu. Việc bao gồm HUD là điều cần thiết cho hầu hết các trải nghiệm vì nó hiển thị thông tin giúp người chơi thành công trong mục tiêu chơi game của họ.
Một thành phần HUD phổ biến là đồng hồ sức khỏe với một biểu tượng bên trái có thể được thích ứng thành thanh hẹn giờ, thanh tiến độ, hoặc tương tự.

Sử dụng Trạm Không Gian Nguy Hiểm làm nơi khởi đầu và UI Fundamentals - HUD Meter làm nơi tham khảo hoàn thành, hướng dẫn này trình bày:
- Thiết lập và sử dụng Device Emulator để kiểm tra thiết kế của bạn trên nhiều màn hình giả lập.
- Sử dụng StarterGui như một thiết kế và kho chứa.
- Cách định vị/thiết lập kích thước các yếu tố UI xung quanh các điều khiển và các hốc/đảo thiết bị tích hợp sẵn của Roblox, chẳng hạn như hốc camera trên các điện thoại hiện đại.
- Cách thay thế đồng hồ sức khỏe mặc định của Roblox bằng đồng hồ của riêng bạn và kết nối nó với mức sức khỏe của nhân vật.
- Cách hoạt hình phần trung tâm của đồng hồ sức khỏe và đặt màu của nó giữa năm điểm màu gradient (đỏ, cam, vàng, xanh chanh, xanh).
Bật Device Emulator
Roblox vốn dĩ là cros-platform, vì người chơi có thể khám phá và tham gia các trải nghiệm trên điện thoại hoặc máy tính bảng của họ, sau đó tiếp tục từ chỗ họ bỏ lỡ trên PC hoặc console của họ. Các thiết bị di động (điện thoại và máy tính bảng) có ít không gian màn hình nhất, vì vậy điều quan trọng là các yếu tố UI của bạn phù hợp với các màn hình nhỏ hơn và rõ ràng cho người chơi.
Cách tốt nhất để kiểm tra thiết kế UI trên các nền tảng là Device Emulator của Studio. Công cụ này cung cấp một lựa chọn thiết bị đã được định sẵn và cho phép bạn thêm các thiết lập tùy chỉnh của riêng mình.
Mở mẫu Trạm Không Gian Nguy Hiểm trong Studio.
Từ menu Test của Studio, bật Device Emulator.
Từ thanh ngay trên khung nhìn chính, chọn một chế độ giả lập điện thoại như iPhone X hoặc Samsung Galaxy A51. Sau đó, đặt kích thước xem thành Fit to Window để sử dụng tối đa không gian trong Studio.

Tạo một kho chứa màn hình
Một ScreenGui kho chứa giữ các đối tượng UI (GuiObjects) để hiển thị trên màn hình của người chơi (trong hướng dẫn này, toàn bộ đồng hồ sức khỏe). Để hiển thị một ScreenGui và các đối tượng con của nó cho tất cả mọi người tham gia trải nghiệm, hãy đặt nó bên trong kho chứa StarterGui. Khi một người chơi tham gia và nhân vật của họ lần đầu tiên xuất hiện, ScreenGui và nội dung của nó sẽ được sao chép vào kho chứa PlayerGui cho người chơi đó, nằm trong kho chứa Players.

Để chèn một ScreenGui trống:
Trong cửa sổ Explorer, tìm kho chứa StarterGui.

Di chuột qua kho chứa, nhấp vào nút ⊕ và chèn một ScreenGui.

Đổi tên kho chứa mới thành HUDContainer để phản ánh mục đích của nó.

Sử dụng các khu vực an toàn
Các điện thoại hiện đại tận dụng toàn bộ màn hình nhưng thường bao gồm các vùng cắt, các khe hở và các thành phần khác chiếm không gian màn hình. Mỗi trải nghiệm Roblox cũng bao gồm các điều khiển thanh trên để truy cập nhanh vào menu chính, chat, bảng điểm, và nhiều điều khác.

Để đảm bảo người chơi có thể nhìn thấy và truy cập tất cả các UI một cách không bị cản trở, Roblox cung cấp thuộc tính ScreenInsets mà kiểm soát các phần khu vực an toàn cho nội dung của một ScreenGui. Mỗi đối tượng UI mà bạn định vị bên trong một ScreenGui đều tương đối với các giới hạn của phần đệm.

Trong khi mặc định của CoreUISafeInsets đảm bảo tất cả các đối tượng UI không bị cản trở bởi UI Roblox và các vùng cắt của thiết bị, DeviceSafeInsets có thể là một lựa chọn tốt hơn để sử dụng không gian màn hình hạn chế, như dưới đây.

Trong cửa sổ Explorer, chọn HUDContainer.

Trong cửa sổ Properties, đặt thuộc tính ScreenInsets thành DeviceSafeInsets.

Thiết lập phần đệm cạnh
Với ScreenInsets được đặt thành DeviceSafeInsets, nội dung bây giờ có thể mở rộng trực tiếp lên đến cạnh trên của màn hình vật lý. Tuy nhiên, một chút đệm có thể giúp đẩy đồng hồ sức khỏe (và các đối tượng khác bên trong kho chứa) cách xa các cạnh màn hình để tạo ra một vẻ bề ngoài gọn gàng hơn và để ngăn chúng bị cắt.

Một cách để áp dụng phần đệm cho một kho chứa UI là thông qua việc chèn một UIPadding trình điều chỉnh:
Chèn một trình điều chỉnh UIPadding vào HUDContainer.

Với đối tượng UIPadding mới được chọn, nhập giá trị 0, 16 cho tất cả các cạnh của kho chứa (PaddingBottom, PaddingLeft, PaddingRight, PaddingTop). Điều này áp dụng đệm 16 pixels quanh kho chứa, bất kể độ phân giải của màn hình.

Xây dựng đồng hồ sức khỏe
Với kho chứa màn hình đã được cấu hình, bạn có thể bắt đầu xây dựng đồng hồ sức khỏe bằng cách sử dụng các đối tượng UI của Roblox như khung và một nhãn hình ảnh.

Tạo khung cha
Tương tự như các ứng dụng thiết kế như Figma và Photoshop, một Frame trong Roblox phục vụ như một kho chứa cho các đối tượng UI khác. Trong hướng dẫn này, toàn bộ đồng hồ sức khỏe sẽ được chứa trong một khung cha, giúp dễ dàng di chuyển nó qua nhiều bố cục HUD khác nhau.
Chèn một Frame vào HUDContainer. Khung mới xuất hiện ở góc trên bên trái như một hình vuông trắng trống.

Đổi tên thể hiện khung mới thành MeterBar.

Định vị khung
Trong Roblox, vị trí của một đối tượng UI được biểu diễn bởi một tập hợp tọa độ UDim2 chứa các giá trị Scale và Offset cho cả hai trục X và Y:


Để định vị một đối tượng UI ở góc trên bên phải của kho chứa màn hình, Scale là cách tiếp cận tốt nhất vì một giá trị X của 1 (100%) đại diện cho cạnh phải của kho chứa, bất kể kích thước pixel vật lý của màn hình. Tương tự, giá trị tỷ lệ Y của 0 (0%) đại diện cho cạnh trên cùng của kho chứa.

Ngoài ra, bạn sẽ cần thiết lập một điểm neo ở góc trên bên phải cho khung cha để xác định điểm gốc của nó. Các giá trị chấp nhận nằm giữa 0 và 1, tùy theo kích thước của đối tượng, vì vậy một giá trị neo là 1, 0 đặt điểm neo của khung ở góc trên bên phải của nó.

Trong cửa sổ Explorer, chọn khung MeterBar mà bạn đã chèn trước đó.

Nhập 1, 0 cho thuộc tính AnchorPoint. Khung giờ đây sẽ ở góc trên bên phải của khu vực an toàn thiết bị, được dời nhẹ từ cạnh do phần đệm.

Thay đổi kích thước khung
Giống như vị trí, kích thước của Frames của một đối tượng UI được biểu diễn bằng một tập hợp tọa độ UDim2 chứa các giá trị Scale và Offset cho cả hai trục X và Y.
Theo mặc định, kích thước của khung mới là {0, 100},{0, 100}, có nghĩa là 100 pixels về chiều rộng (X) và chiều cao (Y). Trong khi giá trị pixel nghiêm ngặt hữu ích trong một số trường hợp, nhiều yếu tố UI mở rộng một cách phản hồi hơn thông qua nhiều màn hình khi được đặt là một tỷ lệ phần trăm của kích thước tổng thể của kho chứa màn hình.
Với khung MeterBar đã chọn, truy cập vào cửa sổ Properties và điều hướng đến thuộc tính Size.
Nhập giá trị 0.35, 0, 0.05, 0 để thiết lập kích thước phần trăm là 35% chiều rộng và 5% chiều cao mà không có thêm độ lệch pixel.

Tạo kiểu cho khung
Theo mặc định, Frames được lấp đầy bằng màu trắng. Đồng hồ sức khỏe cuối cùng nên có màu lấp đầy tối hơn và hơi trong suốt, cũng như một đường viền tối, để nó nổi bật hơn trên cả nền sáng và tối.

Với khung MeterBar đã được chọn, nhập 0 cho thuộc tính BackgroundColor3. Studio sẽ tự động chuyển đổi nó thành giá trị RGB là [0, 0, 0].
Nhập 0.75 cho thuộc tính BackgroundTransparency. Trong Roblox, độ trong suốt dao động từ 0 cho đến hoàn toàn không trong suốt đến 1 cho đến hoàn toàn trong suốt, vì vậy 0.75 tương đương với 25% độ mờ trong các ứng dụng khác như Figma hoặc Photoshop.

Chèn một đối tượng UIStroke, một trình sửa UI mạnh mẽ thêm một đường viền có thể tùy chỉnh vào khung.

Với UIStroke mới được chọn, đặt các thuộc tính sau:
- Thickness = 3
- Transparency = 0.25 (75% không trong suốt)

Để hoàn thiện kiểu dáng của khung đồng hồ, bạn có thể làm tròn các góc để tạo hình dạng "viên thuốc" thay vì một hình chữ nhật sắc cạnh.
Chèn một đối tượng UICorner vào khung MeterBar.

Với trình điều chỉnh UICorner mới được chọn, đặt thuộc tính CornerRadius thành 0.5, 0. Sử dụng giá trị tỷ lệ là 0.5 (50%) thay vì giá trị pixel đặc biệt hữu ích cho thanh đồng hồ vì nó đảm bảo một đường cong tròn hoàn toàn bất kể khung chứa cao hay rộng như thế nào.

Tạo phần lấp đầy bên trong
Giờ đây, khung chứa đồng hồ sức khỏe đã hoàn tất, bạn có thể thêm một phần lấp đầy bên trong để đại diện cho sức khỏe biến đổi của nhân vật. Vì nó chỉ cần là một vùng được lấp đầy rắn, một Frame con bên trong khung cha là phù hợp.

Chèn một Frame con vào khung MeterBar.
Đổi tên thể hiện khung mới thành InnerFill.

Với InnerFill đã được chọn, đặt các thuộc tính sau:
- AnchorPoint = 0, 0.5 (cạnh trái và giữa theo chiều dọc)
- Position = 0, 0, 0.5, 0
- Size = 1, 0, 1, 0
Vì các đối tượng con của khung được định vị và thay đổi kích thước tương đối với khung cha của chúng, việc sử dụng tỷ lệ khiến khung bên trong đầy đủ chiều rộng và chiều cao của khung cha, bắt đầu từ cạnh trái của khung cha.

Để khớp với hình dạng "viên thuốc" của khung cha, hãy chèn thêm một UICorner vào InnerFill.

Với trình điều chỉnh UICorner mới được chọn, đặt thuộc tính CornerRadius thành 0.5, 0 để khớp với hình dạng "viên thuốc" của khung cha MeterBar.

Để thể hiện rằng một đồng hồ đầy đủ cho thấy sức khỏe tốt, chọn InnerFill và đặt thuộc tính BackgroundColor3 thành [0, 225, 50] (trong một nhiệm vụ sau, bạn sẽ kịch bản màu này để thay đổi dựa trên sức khỏe thực tế).

Thêm biểu tượng
Để chỉ rõ mục đích của đồng hồ, bạn có thể thêm một nhãn hình ảnh ở phía bên trái, trong trường hợp này là một trái tim đỏ mà thường tượng trưng cho sức khỏe hoặc sự sống.

Chèn một ImageLabel vào khung MeterBar. Đối tượng này cho phép bạn áp dụng một tài sản hình ảnh 2D đã được tải lên như một decal lên Roblox.
Đổi tên thể hiện nhãn mới thành Icon.

Với Icon đã được chọn, đặt thuộc tính ZIndex thành 2. Mặc dù các đối tượng UI được chèn mới luôn nằm ở phía trước các đối tượng đã được chèn trước đó, thay đổi này đảm bảo rằng biểu tượng luôn hiển thị ở phía trước của các phần khung đồng hồ.

Để đảm bảo rằng nhãn ImageLabel luôn giữ tỷ lệ 1:1, chèn một UIAspectRatioConstraint. Mặc dù ràng buộc này có các thuộc tính có thể tùy chỉnh để kiểm soát tỷ lệ khung hình, bạn có thể để các giá trị mặc định giữ nguyên.

Với Icon đã được chọn, hoàn thiện diện mạo và vị trí bằng cách thay đổi các thuộc tính sau:
- AnchorPoint = 0.5, 0.5 (neo trung tâm)
- BackgroundTransparency = 1 (100% trong suốt)
- Position = 0, 0, 0.5, 0 (bên trái đồng hồ và giữa theo chiều dọc)
- Size = 2, 0, 2, 0 (200% kích thước tổng thể của khung MeterBar, bị ràng buộc vào 1:1 bởi UIAspectRatioConstraint)

Ràng buộc kích thước
Mặc dù chiều cao tỷ lệ là 0.05 (5%) trông đẹp trên các màn hình điện thoại và màn hình chơi game hiện đại có tỷ lệ 16:9 rộng hơn, đồng hồ có thể trông hơi cao trên các màn hình máy tính bảng và điện thoại cũ hơn. Bạn có thể kiểm tra điều này bằng cách giả lập một máy tính bảng như iPad 7th Generation từ Device Emulator.


Để giữ chiều cao của thanh đồng hồ có sự nhất quán hơn với các màn hình rộng hơn, bạn có thể áp dụng một UISizeConstraint để giới hạn chiều cao pixel tối đa.
Chèn một UISizeConstraint vào khung MeterBar.

Với ràng buộc mới được chọn, đặt thuộc tính MaxSize thành inf, 20 để giới hạn chiều cao của nó trong 20 pixel trong khi không áp dụng giới hạn chiều rộng.

Bây giờ, thanh đồng hồ duy trì chiều cao nhất quán hơn giữa các màn hình rộng và cao hơn.

Thay thế đồng hồ sức khỏe mặc định
Các trải nghiệm Roblox bao gồm một đồng hồ sức khỏe mặc định sẽ hiển thị khi các nhân vật bị tổn thương. Nếu bạn giữ đồng hồ mặc định hiển thị, nó sẽ bị trùng lặp và có thể chồng lên đồng hồ tùy chỉnh.

Vô hiệu hóa đồng hồ mặc định
Để vô hiệu hóa đồng hồ sức khỏe mặc định, bạn sẽ sử dụng một kịch bản client (LocalScript) bên trong StarterPlayerScripts gọi StarterGui:SetCoreGuiEnabled().
Trong cửa sổ Explorer, mở rộng kho chứa StarterPlayer và tìm kho chứa StarterPlayerScripts bên trong nó.

Chèn một LocalScript mới vào kho chứa và đổi tên nó thành HideDefaultHealthMeter để mô tả mục đích của nó. Các kịch bản bên trong StarterPlayerScripts tự động chạy khi người chơi địa phương tham gia một trải nghiệm, biến nó thành một kho chứa lý tưởng để chạy một kịch bản ẩn đồng hồ mặc định vĩnh viễn.

Khi bạn chèn một kịch bản mới, nó sẽ tự động mở trong một tab trình soạn thảo kịch bản mới (nếu không, hãy nhấp đúp vào kịch bản trong cửa sổ Explorer).
Dán đoạn mã sau vào trong kịch bản HideDefaultHealthMeter:
HideDefaultHealthMeterlocal StarterGui = game:GetService("StarterGui")-- Ẩn đồng hồ sức khỏe mặc địnhStarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Health, false)Giải thích mãĐường Mục đích 1 Lấy tham chiếu đến một dịch vụ cốt lõi, StarterGui, điều này đại diện cho cùng một kho chứa nơi bạn đã tạo đồng hồ sức khỏe tùy chỉnh và nội dung của nó sao chép vào kho chứa PlayerGui cho mỗi người chơi tham gia trải nghiệm. 4 Gọi phương thức SetCoreGuiEnabled() của dịch vụ và chỉ định đồng hồ sức khỏe mặc định được vô hiệu hóa (false).
Nếu bạn thử nghiệm trải nghiệm bây giờ và bị tổn thương, bạn sẽ nhận thấy rằng đồng hồ mặc định đã bị vô hiệu hóa và ẩn (bạn sẽ lập trình đồng hồ tùy chỉnh để phản ánh các thay đổi sức khỏe trong phần tiếp theo).

Lắng nghe các thay đổi sức khỏe
Tất cả các mô hình nhân vật mặc định của Roblox chứa một lớp Humanoid có các hành vi và chức năng đặc biệt cho nhân vật, chẳng hạn như đặt tốc độ đi/bắt chạy của nó và quản lý sức khỏe của nó. Health thay đổi trên máy chủ sẽ tái tạo cho mỗi client của người chơi và bạn có thể phát hiện những thay đổi này để cập nhật cả kích thước và màu sắc của đồng hồ sức khỏe tùy chỉnh.
Trong cửa sổ Explorer, tìm kho chứa StarterCharacterScripts bên trong StarterPlayer.

Chèn một LocalScript mới vào kho chứa và đổi tên nó thành UpdateCustomMeter để mô tả mục đích của nó. Các kịch bản bên trong StarterCharacterScripts tự động chạy mỗi lần nhân vật của người chơi xuất hiện, làm cho nó trở thành một kho chứa lý tưởng để chạy một kịch bản hoàn toàn thiết lập lại đồng hồ sức khỏe trên mỗi lần tái sinh.

Trong cửa sổ thư viện cho kịch bản UpdateCustomMeter, dán đoạn mã sau vào:
UpdateCustomMeterlocal Players = game:GetService("Players")-- Tham chiếu đến người chơi địa phương, nhân vật, và humanoidlocal player = Players.LocalPlayerlocal character = player.Characterlocal humanoid = character:WaitForChild("Humanoid")-- Tham chiếu đến khung lấp đầy bên trong đồng hồlocal playerGui = player:WaitForChild("PlayerGui")local meterBarInner = playerGui.HUDContainer.MeterBar.InnerFill-- Màu sắc chuỗi gradient (đỏ, cam, vàng, xanh chanh, xanh)local gradient = {Color3.fromRGB(225, 50, 0),Color3.fromRGB(255, 100, 0),Color3.fromRGB(255, 200, 0),Color3.fromRGB(150, 225, 0),Color3.fromRGB(0, 225, 50)}-- Hàm để lấy màu trong chuỗi gradient từ điểm phân đoạnlocal function getColorFromSequence(fraction: number): Color3-- Mỗi màu trong gradient xác định sự bắt đầu và/hoặc kết thúc của một phầnlocal numSections = #gradient - 1-- Mỗi phần đại diện cho một phần của 1local sectionSize = 1 / numSections-- Xác định phần nào mà phân đoạn yêu cầu rơi vàolocal sectionStartIndex = 1 + math.clamp(fraction, 0, 1) // sectionSize-- Lấy các màu ở phần bắt đầu và kết thúc của phầnlocal sectionColorStart = gradient[sectionStartIndex]local sectionColorEnd = gradient[sectionStartIndex + 1] or sectionColorStart-- Chuẩn hóa phân đoạn thành một số từ 0 đến 1 trong phầnlocal fractionOfSection = math.clamp(fraction, 0, 1) % sectionSize / sectionSize-- Lerp giữa phần bắt đầu và phần kết thúc dựa trên phân đoạn đã chuẩn hóareturn sectionColorStart:Lerp(sectionColorEnd, fractionOfSection)endlocal function onHealthChanged()-- Tính toán sức khỏe mới dưới dạng tỷ lệ phần trăm của tối đalocal healthFraction = math.max(0, humanoid.Health / humanoid.MaxHealth)-- Đặt đồng hồ đến các kích thước/màu sắc mục tiêu mớimeterBarInner.Size = UDim2.new(healthFraction, 0, 1, 0)meterBarInner.BackgroundColor3 = getColorFromSequence(healthFraction)end-- Lắng nghe cho các thay đổi sức khỏe của humanoidhumanoid.HealthChanged:Connect(onHealthChanged)-- Ban đầu đặt (hoặc thiết lập lại) kích thước/màu sắc đồng hồ cho sức khỏe hiện tạionHealthChanged()Giải thích mãĐường Mục đích 4‑6 Lấy các tham chiếu đến người chơi địa phương, mô hình Character của họ, và lớp Humanoid bên trong nó. 9‑10 Lấy một tham chiếu đến đối tượng InnerFill của đồng hồ mà cần được thay đổi kích thước và tô màu khi sức khỏe của nhân vật thay đổi. 13‑19 Khai báo một mảng năm màu (đỏ, cam, vàng, xanh chanh, xanh) để tô màu lại đồng hồ ở các điểm khác nhau; ví dụ, xanh cho sức khỏe 100%, vàng cho 50%, đỏ cho 0%, hoặc một sự pha trộn tại bất kỳ phần trăm nào giữa các điểm chính. 22‑41 Hàm trợ giúp trả về sự pha trộn màu giữa bất kỳ màu nào của các điểm màu trong gradient. 43‑50 Hàm xử lý bất kỳ thay đổi nào về sức khỏe. Ở đây, nó tính toán sức khỏe mới dưới dạng tỷ lệ phần trăm của tối đa và điều chỉnh kích thước InnerFill theo tỷ lệ phần trăm đó và tô màu nó bằng màu được trả về từ hàm getColorFromSequence(). 53 Kết nối sự kiện chính phát hiện các thay đổi Health được sao chép từ máy chủ và gọi hàm onHealthChanged(). 56 Ban đầu (khi nhân vật xuất hiện hoặc tái sinh) gọi hàm onHealthChanged() để kích thước và màu sắc của InnerFill được điều chỉnh đúng tỷ lệ phần trăm. Thông thường sẽ là chiều rộng đầy đủ và xanh.
Nếu bạn thử nghiệm trải nghiệm bây giờ, bạn sẽ nhận thấy rằng đồng hồ tùy chỉnh sẽ tự động cập nhật cả kích thước và màu sắc khi nhân vật bị tổn thương:
Hoạt hình thanh đồng hồ
Để thêm một mức độ hoàn thiện cho đồng hồ tùy chỉnh, bạn có thể hoạt hình các thay đổi sức khỏe thông qua tweening, từ từ thay đổi kích thước và màu sắc của thanh đồng hồ trong vòng ½ giây.
Truy cập vào tab trình soạn thảo cho kịch bản UpdateCustomMeter mà bạn đã sửa trước đó.
Chọn tất cả các dòng (CtrlA hoặc ⌘A) và rồi dán lại lên chúng (CtrlV hoặc ⌘V) với đoạn mã sau:
UpdateCustomMeterlocal Players = game:GetService("Players")local TweenService = game:GetService("TweenService")-- Tham chiếu đến người chơi địa phương, nhân vật, và humanoidlocal player = Players.LocalPlayerlocal character = player.Characterlocal humanoid = character:WaitForChild("Humanoid")-- Thuộc tính tweenlocal tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)-- Tham chiếu đến khung lấp đầy bên trong đồng hồlocal playerGui = player:WaitForChild("PlayerGui")local meterBarInner = playerGui.HUDContainer.MeterBar.InnerFill-- Màu sắc chuỗi gradient (đỏ, cam, vàng, xanh chanh, xanh)local gradient = {Color3.fromRGB(225, 50, 0),Color3.fromRGB(255, 100, 0),Color3.fromRGB(255, 200, 0),Color3.fromRGB(150, 225, 0),Color3.fromRGB(0, 225, 50)}-- Hàm để lấy màu trong chuỗi gradient từ điểm phân đoạnlocal function getColorFromSequence(fraction: number): Color3-- Mỗi màu trong gradient xác định sự bắt đầu và/hoặc kết thúc của một phầnlocal numSections = #gradient - 1-- Mỗi phần đại diện cho một phần của 1local sectionSize = 1 / numSections-- Xác định phần nào mà phân đoạn yêu cầu rơi vàolocal sectionStartIndex = 1 + math.clamp(fraction, 0, 1) // sectionSize-- Lấy các màu ở phần bắt đầu và kết thúc của phầnlocal sectionColorStart = gradient[sectionStartIndex]local sectionColorEnd = gradient[sectionStartIndex + 1] or sectionColorStart-- Chuẩn hóa phân đoạn thành một số từ 0 đến 1 trong phầnlocal fractionOfSection = math.clamp(fraction, 0, 1) % sectionSize / sectionSize-- Lerp giữa phần bắt đầu và phần kết thúc dựa trên phân đoạn đã chuẩn hóareturn sectionColorStart:Lerp(sectionColorEnd, fractionOfSection)endlocal function onHealthChanged()-- Tính toán sức khỏe mới dưới dạng tỷ lệ phần trăm của tối đalocal healthFraction = math.max(0, humanoid.Health / humanoid.MaxHealth)-- Tween thanh đồng hồ đến kích thước/màu sắc mớilocal tweenGoal = {Size = UDim2.new(healthFraction, 0, 1, 0),BackgroundColor3 = getColorFromSequence(healthFraction)}local meterBarTween = TweenService:Create(meterBarInner, tweenInfo, tweenGoal)meterBarTween:Play()end-- Lắng nghe cho các thay đổi sức khỏe của humanoidhumanoid.HealthChanged:Connect(onHealthChanged)-- Ban đầu đặt (hoặc thiết lập lại) kích thước/màu sắc đồng hồ cho sức khỏe hiện tạionHealthChanged()Các bổ sung/thay đổi chínhĐường Mục đích 2 Lấy tham chiếu đến TweenService để thực hiện chức năng tweening trong kịch bản. 10 Tạo một constructor TweenInfo xác định độ dài của tween, kiểu easing, và hướng easing. 52‑57 Thay vì chỉ đơn giản là thiết lập kích thước và màu sắc của thanh như trong phiên bản trước, khai báo một bảng tweenGoal với các kích thước/màu sắc mục tiêu, tạo một tween mới sử dụng các tham số tweenInfo và tweenGoal, và chơi tween mới này.
Nếu bạn thử nghiệm trải nghiệm bây giờ, bạn sẽ nhận thấy rằng đồng hồ tùy chỉnh tween giữa mỗi thay đổi sức khỏe:
Thêm hiệu ứng tổn thương
Hệ thống đồng hồ sức khỏe mặc định bao gồm một tông đỏ nhạt, tinh tế ở các cạnh của màn hình khi nhân vật bị tổn thương. Bằng cách vô hiệu hóa đồng hồ mặc định, hiệu ứng này sẽ bị loại bỏ, nhưng bạn có thể thay thế nó bằng việc triển khai của riêng bạn.
Truy cập vào tab trình soạn thảo cho kịch bản UpdateCustomMeter mà bạn đã sửa trước đó.
Chọn tất cả các dòng và dán lại lên chúng bằng đoạn mã sau:
UpdateCustomMeterlocal Workspace = game:GetService("Workspace")local Players = game:GetService("Players")local TweenService = game:GetService("TweenService")-- Tham chiếu đến người chơi địa phương, nhân vật, và humanoidlocal player = Players.LocalPlayerlocal character = player.Characterlocal humanoid = character:WaitForChild("Humanoid")-- Thuộc tính tweenlocal tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)-- Biến để lưu trữ/cache sức khỏe của nhân vậtlocal cachedHealth = humanoid.Health / humanoid.MaxHealth-- Lấy (hoặc tạo mới) hiệu ứng điều chỉnh màu bên trong camera của người chơilocal colorCorrection = Workspace.CurrentCamera:FindFirstChildWhichIsA("ColorCorrectionEffect") or Instance.new("ColorCorrectionEffect", Workspace.CurrentCamera)colorCorrection.Name = "DamageColorEffect"-- Tham chiếu đến khung lấp đầy bên trong đồng hồlocal playerGui = player:WaitForChild("PlayerGui")local meterBarInner = playerGui.HUDContainer.MeterBar.InnerFill-- Màu sắc chuỗi gradient (đỏ, cam, vàng, xanh chanh, xanh)local gradient = {Color3.fromRGB(225, 50, 0),Color3.fromRGB(255, 100, 0),Color3.fromRGB(255, 200, 0),Color3.fromRGB(150, 225, 0),Color3.fromRGB(0, 225, 50)}-- Hàm để lấy màu trong chuỗi gradient từ điểm phân đoạnlocal function getColorFromSequence(fraction: number): Color3-- Mỗi màu trong gradient xác định sự bắt đầu và/hoặc kết thúc của một phầnlocal numSections = #gradient - 1-- Mỗi phần đại diện cho một phần của 1local sectionSize = 1 / numSections-- Xác định phần nào mà phân đoạn yêu cầu rơi vàolocal sectionStartIndex = 1 + math.clamp(fraction, 0, 1) // sectionSize-- Lấy các màu ở phần bắt đầu và kết thúc của phầnlocal sectionColorStart = gradient[sectionStartIndex]local sectionColorEnd = gradient[sectionStartIndex + 1] or sectionColorStart-- Chuẩn hóa phân đoạn thành một số từ 0 đến 1 trong phầnlocal fractionOfSection = math.clamp(fraction, 0, 1) % sectionSize / sectionSize-- Lerp giữa phần bắt đầu và phần kết thúc dựa trên phân đoạn đã chuẩn hóareturn sectionColorStart:Lerp(sectionColorEnd, fractionOfSection)endlocal function onHealthChanged()-- Tính toán sức khỏe mới dưới dạng tỷ lệ phần trăm của tối đalocal healthFraction = math.max(0, humanoid.Health / humanoid.MaxHealth)-- Tween thanh đồng hồ đến kích thước/màu sắc mớilocal tweenGoal = {Size = UDim2.new(healthFraction, 0, 1, 0),BackgroundColor3 = getColorFromSequence(healthFraction)}local meterBarTween = TweenService:Create(meterBarInner, tweenInfo, tweenGoal)meterBarTween:Play()-- Hiện thị hiệu ứng tổn thương nếu sức khỏe mới thấp hơn sức khỏe cacheif healthFraction < cachedHealth then-- Lưu trữ giá trị sức khỏe mớicachedHealth = healthFraction-- Đặt điều chỉnh màu thành đỏ như tông màu ban đầu trước khi tweeningcolorCorrection.TintColor = Color3.fromRGB(255, 25, 25)colorCorrection.Saturation = 2.5-- Tween tông màu trở lại trắng (trung tính và không thay đổi tông màu từ bình thường)local colorCorrectionTweenGoal = {TintColor = Color3.fromRGB(255, 255, 255),Saturation = 0}local colorCorrectionTween = TweenService:Create(colorCorrection, tweenInfo, colorCorrectionTweenGoal)colorCorrectionTween:Play()endend-- Lắng nghe cho các thay đổi sức khỏe của humanoidhumanoid.HealthChanged:Connect(onHealthChanged)-- Ban đầu đặt (hoặc thiết lập lại) kích thước/màu sắc đồng hồ cho sức khỏe hiện tạionHealthChanged()Các bổ sung/thay đổi chínhĐường Mục đích 14 Đặt một tham chiếu placeholder (cachedHealth) để theo dõi lượng sức khỏe của nhân vật giữa các thay đổi, để bạn có thể so sánh nếu thay đổi thì thấp hơn (tổn thương). 17‑18 Trong lần xuất hiện nhân vật đầu tiên, tạo một ColorCorrectionEffect mới bên trong Camera hiện tại của người chơi, hoặc lấy tham chiếu đến thể hiện cùng một thực thể khi tái sinh sau này. Bằng cách gán hiệu ứng hậu xử lý này cho camera của người chơi, nó chỉ áp dụng cho màn hình địa phương của họ, không phải cho màn hình của mọi người chơi trên máy chủ. 68‑83 Đầu tiên thực hiện kiểm tra điều kiện để xác nhận rằng thay đổi sức khỏe thấp hơn giá trị cachedHealth, cho thấy tổn thương; nếu có, nó đặt cachedHealth thành giá trị mới. Tiếp theo, nó đặt điều chỉnh màu của ColorCorrectionEffect thành [255, 25, 25] (đỏ) với độ bão hòa cao hơn, sau đó tween tông màu trở lại giá trị mặc định là trắng trung tính ([255, 255, 255]) với độ bão hòa bằng 0.
Nếu bạn thử nghiệm trải nghiệm bây giờ, bạn sẽ nhận thấy rằng màn hình nhấp nháy màu đỏ trong chốc lát mỗi khi nhân vật bị tổn thương:
