Загрузка данных


local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local player = Players.LocalPlayer
local event = ReplicatedStorage:WaitForChild("CustomChatEvent")

--------------------------------------------------
-- НАСТРОЙКИ
--------------------------------------------------

local BUBBLE_TIME = 6

--------------------------------------------------
-- СОЗДАЁМ GUI
--------------------------------------------------

local gui = Instance.new("ScreenGui")
gui.Name = "CustomChat"
gui.ResetOnSpawn = false
gui.Parent = player:WaitForChild("PlayerGui")

local main = Instance.new("Frame")
main.Name = "ChatWindow"
main.Size = UDim2.new(0, 430, 0, 260)
main.Position = UDim2.new(0, 20, 1, -300)
main.BackgroundColor3 = Color3.fromRGB(20, 20, 20)
main.BackgroundTransparency = 0.15
main.BorderSizePixel = 0
main.Parent = gui

local corner = Instance.new("UICorner")
corner.CornerRadius = UDim.new(0, 10)
corner.Parent = main

--------------------------------------------------
-- СПИСОК СООБЩЕНИЙ
--------------------------------------------------

local messages = Instance.new("ScrollingFrame")
messages.Name = "Messages"
messages.Size = UDim2.new(1, -10, 1, -55)
messages.Position = UDim2.new(0, 5, 0, 5)
messages.BackgroundTransparency = 1
messages.BorderSizePixel = 0
messages.ScrollBarThickness = 5
messages.AutomaticCanvasSize = Enum.AutomaticSize.Y
messages.CanvasSize = UDim2.new(0, 0, 0, 0)
messages.Parent = main

local layout = Instance.new("UIListLayout")
layout.SortOrder = Enum.SortOrder.LayoutOrder
layout.Padding = UDim.new(0, 3)
layout.Parent = messages

--------------------------------------------------
-- ПОЛЕ ВВОДА
--------------------------------------------------

local input = Instance.new("TextBox")
input.Name = "MessageBox"
input.Size = UDim2.new(1, -80, 0, 40)
input.Position = UDim2.new(0, 5, 1, -45)
input.BackgroundColor3 = Color3.fromRGB(35, 35, 35)
input.TextColor3 = Color3.fromRGB(255, 255, 255)
input.PlaceholderColor3 = Color3.fromRGB(170, 170, 170)
input.PlaceholderText = "Напишите сообщение..."
input.Text = ""
input.TextSize = 16
input.Font = Enum.Font.Gotham
input.ClearTextOnFocus = false
input.TextXAlignment = Enum.TextXAlignment.Left
input.Parent = main

local inputCorner = Instance.new("UICorner")
inputCorner.CornerRadius = UDim.new(0, 8)
inputCorner.Parent = input

--------------------------------------------------
-- КНОПКА
--------------------------------------------------

local send = Instance.new("TextButton")
send.Name = "Send"
send.Size = UDim2.new(0, 65, 0, 40)
send.Position = UDim2.new(1, -70, 1, -45)
send.BackgroundColor3 = Color3.fromRGB(50, 50, 50)
send.TextColor3 = Color3.fromRGB(255, 255, 255)
send.Text = "SEND"
send.TextSize = 14
send.Font = Enum.Font.GothamBold
send.Parent = main

local sendCorner = Instance.new("UICorner")
sendCorner.CornerRadius = UDim.new(0, 8)
sendCorner.Parent = send

--------------------------------------------------
-- ОТПРАВКА
--------------------------------------------------

local function sendMessage()

	local text = input.Text

	if text == "" then
		return
	end

	event:FireServer(text)

	input.Text = ""

end

send.MouseButton1Click:Connect(sendMessage)

input.FocusLost:Connect(function(enterPressed)

	if enterPressed then
		sendMessage()
	end

end)

--------------------------------------------------
-- СООБЩЕНИЕ НАД ГОЛОВОЙ
--------------------------------------------------

local function createBubble(targetPlayer, message)

	local character = targetPlayer.Character

	if not character then
		return
	end

	local head = character:FindFirstChild("Head")

	if not head then
		return
	end

	-- Удаляем предыдущее облачко
	local oldBubble = head:FindFirstChild("CustomChatBubble")

	if oldBubble then
		oldBubble:Destroy()
	end

	local billboard = Instance.new("BillboardGui")
	billboard.Name = "CustomChatBubble"
	billboard.Adornee = head
	billboard.Size = UDim2.new(0, 300, 0, 60)
	billboard.StudsOffset = Vector3.new(0, 3, 0)
	billboard.AlwaysOnTop = true
	billboard.Parent = head

	local bubble = Instance.new("TextLabel")
	bubble.Size = UDim2.new(1, 0, 1, 0)
	bubble.BackgroundColor3 = Color3.fromRGB(25, 25, 25)
	bubble.BackgroundTransparency = 0.1
	bubble.TextColor3 = Color3.fromRGB(255, 255, 255)
	bubble.TextSize = 16
	bubble.Font = Enum.Font.Gotham
	bubble.TextWrapped = true
	bubble.Text = message
	bubble.Parent = billboard

	local bubbleCorner = Instance.new("UICorner")
	bubbleCorner.CornerRadius = UDim.new(0, 10)
	bubbleCorner.Parent = bubble

	task.delay(BUBBLE_TIME, function()

		if billboard and billboard.Parent then
			billboard:Destroy()
		end

	end)

end

--------------------------------------------------
-- ДОБАВЛЕНИЕ В ЧАТ
--------------------------------------------------

local function addMessage(userId, displayName, message)

	local label = Instance.new("TextLabel")

	label.Size = UDim2.new(1, -10, 0, 28)
	label.BackgroundTransparency = 1
	label.TextColor3 = Color3.fromRGB(255, 255, 255)
	label.TextSize = 16
	label.Font = Enum.Font.Gotham
	label.TextXAlignment = Enum.TextXAlignment.Left
	label.TextWrapped = true
	label.AutomaticSize = Enum.AutomaticSize.Y

	label.Text = displayName .. ": " .. message

	label.Parent = messages

	task.wait()

	messages.CanvasPosition = Vector2.new(
		0,
		messages.AbsoluteCanvasSize.Y
	)

	local targetPlayer = Players:GetPlayerByUserId(userId)

	if targetPlayer then
		createBubble(targetPlayer, message)
	end

end

--------------------------------------------------
-- ПОЛУЧЕНИЕ СООБЩЕНИЯ
--------------------------------------------------

event.OnClientEvent:Connect(function(
	userId,
	displayName,
	message
)

	addMessage(
		userId,
		displayName,
		message
	)

end)