--[[ Naoya Zenin - Projection Sorcery ]] local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local RunService = game:GetService("RunService") local TweenService = game:GetService("TweenService") local player = Players.LocalPlayer local character = player.Character or player.CharacterAdded:Wait() local humanoid, hrp local camera = workspace.CurrentCamera -- ======================= НАСТРОЙКИ ======================= local KEY = Enum.KeyCode.Z local SETTINGS = { MOVE_SPEED = 130, JUMP_POWER = 60, TRAIL_INTERVAL = 0.04, FALL_ACCEL = 196, MAX_FALL_SPEED = 80, TELEPORT_STEP = 1, TELEPORT_DELAY = 0.05, PROJ_COLOR = Color3.fromRGB(180, 70, 255), TRAIL_TRANSP = 0.55, CLONE_TRANSP = 0.25, } -- ======================= СТАН ======================= local isActive = false local projHitbox = nil local projClone = nil -- рухома проекція (Model в workspace) local projCloneParts = {} -- {clone=part, orig=part} local trailTimer = 0 -- Кожен фрейм зберігає CFrame + TimePosition анімацій local savedFrames = {} -- { cf=CFrame, animTimes={animId -> timePos} } local savedTrails = {} -- Model об'єкти слідів для видалення local velocityY = 0 local canJump = true -- ======================= ІНІЦІАЛІЗАЦІЯ ======================= local function setupCharacter(char) character = char humanoid = char:WaitForChild("Humanoid") hrp = char:WaitForChild("HumanoidRootPart") char.Archivable = true end setupCharacter(character) player.CharacterAdded:Connect(function(char) setupCharacter(char) if isActive then endProjection() end end) -- ======================= УТИЛИТИ ======================= local function flashEffect(color) if not hrp then return end local flash = Instance.new("Part") flash.Size = Vector3.new(4, 6, 4) flash.CFrame = hrp.CFrame flash.Anchored = true flash.CanCollide = false flash.Material = Enum.Material.Neon flash.Color = color flash.Transparency = 0.3 flash.CastShadow = false flash.Parent = workspace local tw = TweenService:Create(flash, TweenInfo.new(0.25), { Transparency = 1, Size = Vector3.new(6, 8, 6) }) tw:Play() tw.Completed:Connect(function() flash:Destroy() end) end -- Зберігає Transform кожного Motor6D персонажа (= поточна поза анімації) -- Motor6D.Transform — це те що аніматор пише кожен кадр щоб рухати кінцівки local function captureMotorTransforms() local transforms = {} for _, motor in ipairs(character:GetDescendants()) do if motor:IsA("Motor6D") then transforms[motor.Name] = motor.Transform end end return transforms end -- Тримає позу активною протягом duration секунд. -- Аніматор пише Transform між PreAnimation→PreSimulation кожен кадр. -- Ми підключаємось до PreSimulation і КОЖЕН кадр перезаписуємо його значення. -- Повертає функцію що відключає override. local function holdPose(transforms, duration) local conn = RunService.PreSimulation:Connect(function() for _, motor in ipairs(character:GetDescendants()) do if motor:IsA("Motor6D") and transforms[motor.Name] then motor.Transform = transforms[motor.Name] end end end) task.delay(duration, function() conn:Disconnect() end) return conn end -- Невидимий hitbox для фізики local function createHitbox(cframe) local p = Instance.new("Part") p.Size = Vector3.new(2, 5, 1) p.CFrame = cframe p.Anchored = false p.CanCollide = true p.Transparency = 1 p.Name = "ProjHitbox" p.CustomPhysicalProperties = PhysicalProperties.new(0.5, 0.3, 0.5) p.Parent = workspace return p end -- Стилізує BasePart: неон, без колізій local function stylePart(part, transparency) part.Anchored = true part.CanCollide = false part.CanTouch = false part.CanQuery = false part.Transparency = transparency part.Color = SETTINGS.PROJ_COLOR part.Material = Enum.Material.Neon part.CastShadow = false end -- Рухома проекція: per-part snapshot що оновлюється кожен кадр local function createProjClone(hitboxCF) if not hrp then return nil, {} end local model = Instance.new("Model") model.Name = "ProjectionClone" model.Parent = workspace local parts = {} local hrpInv = hrp.CFrame:Inverse() for _, part in ipairs(character:GetChildren()) do if part:IsA("BasePart") and part.Name ~= "HumanoidRootPart" then local clone = part:Clone() clone:ClearAllChildren() stylePart(clone, SETTINGS.CLONE_TRANSP) clone.CFrame = hitboxCF * (hrpInv * part.CFrame) clone.Parent = model table.insert(parts, {clone = clone, orig = part}) end end return model, parts end -- Оновлює рухому проекцію кожен кадр local function updateProjClone(hitboxCF) if not hrp or not hrp.Parent then return end local hrpInv = hrp.CFrame:Inverse() for _, e in ipairs(projCloneParts) do if e.clone.Parent and e.orig.Parent then e.clone.CFrame = hitboxCF * (hrpInv * e.orig.CFrame) end end end -- Статичний слід: per-part знімок поточної пози local function createTrail(hitboxCF) if not hrp then return end local model = Instance.new("Model") model.Name = "ProjectionTrail" model.Parent = workspace local hrpInv = hrp.CFrame:Inverse() for _, part in ipairs(character:GetChildren()) do if part:IsA("BasePart") and part.Name ~= "HumanoidRootPart" then local clone = part:Clone() clone:ClearAllChildren() stylePart(clone, SETTINGS.TRAIL_TRANSP) clone.CFrame = hitboxCF * (hrpInv * part.CFrame) clone.Parent = model end end table.insert(savedTrails, model) return model end -- Очищає всі залишки local function cleanupAll() if projHitbox and projHitbox.Parent then projHitbox:Destroy() end if projClone and projClone.Parent then projClone:Destroy() end projHitbox = nil projClone = nil projCloneParts = {} for _, obj in ipairs(workspace:GetChildren()) do if obj.Name == "ProjectionTrail" or obj.Name == "ProjectionClone" or obj.Name == "ProjHitbox" then obj:Destroy() end end savedFrames = {} savedTrails = {} end -- ======================= ЗДІБНІСТЬ ======================= function startProjection() if isActive then return end if not humanoid or not hrp then return end cleanupAll() isActive = true trailTimer = 0 velocityY = 0 canJump = true flashEffect(SETTINGS.PROJ_COLOR) -- Відключаємо Animate скрипт щоб він не перемикав на idle -- поки персонаж заморожений — так збережені трансформи будуть реальними local animScript = character:FindFirstChild("Animate") if animScript then animScript.Disabled = true end humanoid.WalkSpeed = 0 humanoid.JumpPower = 0 hrp.Anchored = true local startCF = hrp.CFrame projHitbox = createHitbox(startCF) projClone, projCloneParts = createProjClone(startCF) camera.CameraType = Enum.CameraType.Custom camera.CameraSubject = projHitbox end function endProjection() if not isActive then return end isActive = false local finalCF = projHitbox and projHitbox.CFrame or nil local localFrames = savedFrames local localTrails = savedTrails savedFrames = {} savedTrails = {} -- Камера одразу назад camera.CameraType = Enum.CameraType.Custom camera.CameraSubject = humanoid if humanoid and hrp then humanoid.WalkSpeed = 16 humanoid.JumpPower = 50 hrp.Anchored = false end -- Вмикаємо Animate скрипт назад після телепортації local animScript = character:FindFirstChild("Animate") if animScript then task.delay(#localFrames * SETTINGS.TELEPORT_DELAY + 0.1, function() if animScript and animScript.Parent then animScript.Disabled = false end end) end if projHitbox then projHitbox:Destroy() projHitbox = nil end if projClone then projClone:Destroy() projClone = nil end projCloneParts = {} task.spawn(function() if hrp and #localFrames > 0 then humanoid.AutoRotate = false for i = 1, #localFrames, SETTINGS.TELEPORT_STEP do local frame = localFrames[i] if hrp and hrp.Parent then -- Ставимо позицію і тримаємо позу весь час поки стоїмо на точці hrp.CFrame = frame.cf holdPose(frame.transforms, SETTINGS.TELEPORT_DELAY) end task.wait(SETTINGS.TELEPORT_DELAY) end if finalCF and hrp and hrp.Parent then hrp.CFrame = finalCF end humanoid.AutoRotate = true end flashEffect(Color3.fromRGB(220, 120, 255)) for _, trail in ipairs(localTrails) do if trail and trail.Parent then trail:Destroy() end end end) end -- ======================= ВВІД ======================= UserInputService.InputBegan:Connect(function(input, gp) if gp then return end if input.KeyCode == KEY then startProjection() end end) UserInputService.InputEnded:Connect(function(input, gp) if gp then return end if input.KeyCode == KEY then endProjection() end end) -- ======================= ГОЛОВНИЙ ЦИКЛ ======================= RunService.Heartbeat:Connect(function(delta) if not isActive or not projHitbox then return end local look = camera.CFrame.LookVector local right = camera.CFrame.RightVector local moveVec = Vector3.new() if UserInputService:IsKeyDown(Enum.KeyCode.W) then moveVec += Vector3.new(look.X, 0, look.Z) end if UserInputService:IsKeyDown(Enum.KeyCode.S) then moveVec -= Vector3.new(look.X, 0, look.Z) end if UserInputService:IsKeyDown(Enum.KeyCode.A) then moveVec -= Vector3.new(right.X, 0, right.Z) end if UserInputService:IsKeyDown(Enum.KeyCode.D) then moveVec += Vector3.new(right.X, 0, right.Z) end if moveVec.Magnitude > 0 then moveVec = moveVec.Unit * SETTINGS.MOVE_SPEED end if UserInputService:IsKeyDown(Enum.KeyCode.Space) and canJump then velocityY = SETTINGS.JUMP_POWER canJump = false end velocityY = math.max(velocityY - SETTINGS.FALL_ACCEL * delta, -SETTINGS.MAX_FALL_SPEED) local newPos = projHitbox.Position + Vector3.new( moveVec.X * delta, velocityY * delta, moveVec.Z * delta ) local newCF if moveVec.Magnitude > 0 then newCF = CFrame.lookAt(newPos, newPos + Vector3.new(moveVec.X, 0, moveVec.Z).Unit) else newCF = CFrame.new(newPos) * (projHitbox.CFrame - projHitbox.CFrame.Position) end projHitbox.CFrame = newCF updateProjClone(newCF) if camera.CameraSubject ~= projHitbox then camera.CameraSubject = projHitbox end if projHitbox.Position.Y <= (hrp and hrp.Position.Y or 0) + 0.1 then velocityY = 0 canJump = true end trailTimer += delta if trailTimer >= SETTINGS.TRAIL_INTERVAL then -- Зберігаємо CFrame І Transform кожного Motor6D (= точна поза анімації) table.insert(savedFrames, { cf = newCF, transforms = captureMotorTransforms() }) createTrail(newCF) trailTimer = 0 end end)