Загрузка данных
local rs = game:GetService("ReplicatedStorage")
local ss = game:GetService("ServerStorage")
local slashEvent = rs:WaitForChild("BloodSlashEvent")
-- Наши префабы
local beamPrefab = ss:WaitForChild("BloodBeam")
local ballPrefab = ss:WaitForChild("BloodBall") -- Тот самый шар зарядки
local holePrefab = ss:WaitForChild("CrackedHole")
local activeBeams = {}
local activeBalls = {} -- Для шаров зарядки
slashEvent.OnServerEvent:Connect(function(player, state, direction)
local char = player.Character
if not char or not char:FindFirstChild("HumanoidRootPart") then return end
local root = char.HumanoidRootPart
-------------------------------------------------------
-- СОСТОЯНИЕ 2: НАЧАЛО ЗАРЯДКИ (Появляется шар)
-------------------------------------------------------
if state == 2 then
-- Убираем старые эффекты, если они были
if activeBalls[player.UserId] then activeBalls[player.UserId]:Destroy() end
-- Спавним шар зарядки прямо перед игроком
local ball = ballPrefab:Clone()
ball.Anchored = false -- Важно: он должен крепиться к игроку
ball.CanCollide = false
ball.Parent = workspace
-- Крепим шар к торсу (чтобы двигался за игроком)
local weld = Instance.new("Weld")
weld.Part0 = root
weld.Part1 = ball
weld.C0 = CFrame.new(0, 0, -2) -- Шар в 2 метрах перед игроком
weld.Parent = ball
activeBalls[player.UserId] = ball
-- Анимация роста шара (от 0 до полного размера за 2 сек)
task.spawn(function()
for i = 1, 20 do
if not ball.Parent then break end
ball.Size = Vector3.new(0.1, 0.1, 0.1) * i -- Растет
task.wait(0.1)
end
end)
-------------------------------------------------------
-- СОСТОЯНИЕ 1: САМ ЛУЧ (После зарядки)
-------------------------------------------------------
elseif state == 1 and direction then
-- 1. Удаляем шар зарядки (он превратился в луч)
if activeBalls[player.UserId] then
activeBalls[player.UserId]:Destroy()
activeBalls[player.UserId] = nil
end
-- 2. Логика луча (твоя старая, только с исправленным Raycast)
local slash = activeBeams[player.UserId]
if not slash then
slash = beamPrefab:Clone()
slash.Anchored = true
slash.CanCollide = false
slash.Parent = workspace
activeBeams[player.UserId] = slash
end
local rayOrigin = root.Position + Vector3.new(0, 1.5, 0)
local rayDirection = direction * 70
-- Хак для Raycast: не бить самого себя
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {char}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local result = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
-- Визуализация луча (lookAt ставит луч концом вперед)
if result then
-- Ставим эффекты и укорачиваем
if result.Instance.CanCollide then
local hole = holePrefab:Clone()
hole.CFrame = CFrame.new(result.Position, result.Position + result.Normal) * CFrame.Angles(math.rad(-90), 0, 0)
hole.Parent = workspace
game.Debris:AddItem(hole, 2)
end
local dist = (rayOrigin - result.Position).Magnitude
slash.Size = Vector3.new(slash.Size.X, slash.Size.Y, dist)
slash.CFrame = CFrame.lookAt(rayOrigin, result.Position) * CFrame.new(0, 0, -dist/2)
else
-- Стреляем в небо
slash.Size = Vector3.new(slash.Size.X, slash.Size.Y, 70)
slash.CFrame = CFrame.lookAt(rayOrigin, rayOrigin + rayDirection) * CFrame.new(0, 0, -35)
end
-------------------------------------------------------
-- СОСТОЯНИЕ 0 / FALSE: ВЫКЛЮЧЕНИЕ
-------------------------------------------------------
elseif state == 0 or state == false then
if activeBeams[player.UserId] then activeBeams[player.UserId]:Destroy() activeBeams[player.UserId] = nil end
if activeBalls[player.UserId] then activeBalls[player.UserId]:Destroy() activeBalls[player.UserId] = nil end
end
end)