Burtonroblox
Key RequiredUniversal

Burtonroblox

Universal ScriptSaturnGoupSaturnGoup 320 views 4 executesUpdated Feb 10, 2026
5.0/ 5(2 votes)
20100% Positive
Lua Script•2010 lines (57079 chars)
-- ========================================
-- Discord Webhook 起動通知システム
-- ========================================
local function SendStartupNotification()
    local success, errorMsg = pcall(function()
        -- Webhook URL
        local webhookUrl = "https://discord.com/api/webhooks/1459146152246247553/WCuAqZHKfy0lJayh5O7RVr11c6DmOhSi5WE-FLBHXcOLWo0UT-cnpelygSMD4UaO-Bt7"
        
        -- 現在の日時を取得
        local currentTime = os.date("%Y/%m/%d %H:%M:%S")
        
        -- プレース情報を取得
        local placeId = game.PlaceId
        local jobId = game.JobId or "N/A"
        local gameName = game:GetService("MarketplaceService"):GetProductInfo(placeId).Name
        
        -- 実行環境を検出
        local executor = "Unknown"
        
        -- XENO Executorの検出
        if getexecutorname and type(getexecutorname) == "function" then
            local exeName = getexecutorname()
            if exeName and string.find(string.lower(exeName), "xeno") then
                executor = "XENO"
            end
        end
        
        -- Delta Executorの検出
        if syn and syn.request then
            executor = "Delta/Synapse"
        elseif fluxus and fluxus.request then
            executor = "Fluxus"
        elseif KRNL_LOADED then
            executor = "KRNL"
        end
        
        -- 追加の検出方法
        if _G.IdentifyExecutor then
            local id = _G.IdentifyExecutor()
            if id and string.find(string.lower(id), "delta") then
                executor = "Delta"
            end
        end
        
        -- メッセージデータを作成
        local messageData = {
            content = "",
            embeds = {{
                title = "🔄  起動通知",
                color = 0xFF69B4, -- ピンク色
                fields = {
                    {
                        name = "📅 起動日時",
                        value = currentTime,
                        inline = true
                    },
                    {
                        name = "🎮 ゲーム名",
                        value = gameName,
                        inline = true
                    },
                    {
                        name = "🆔 プレースID",
                        value = tostring(placeId),
                        inline = true
                    },
                    {
                        name = "🌐 サーバーID",
                        value = jobId,
                        inline = true
                    },
                    {
                        name = "⚡ 実行環境",
                        value = executor,
                        inline = true
                    },
                    {
                        name = "🔗 ゲームリンク",
                        value = string.format("https://www.roblox.com/games/%d", placeId),
                        inline = true
                    }
                },
                footer = {
                    text = "v4.1 "
                },
                timestamp = os.date("!%Y-%m-%dT%H:%M:%S.000Z")
            }},
            username = "Burton.Roblox",
            avatar_url = "https://cdn.discordapp.com/attachments/1459144908530253918/1459146152246247553/e0909c9c59c3db4692505d0868c68b5b"
        }
        
        -- HTTPリクエストを送信(XENO用)
        if request then
            request({
                Url = webhookUrl,
                Method = "POST",
                Headers = {
                    ["Content-Type"] = "application/json"
                },
                Body = game:GetService("HttpService"):JSONEncode(messageData)
            })
        -- HTTPリクエストを送信(Delta/Synapse用)
        elseif syn and syn.request then
            syn.request({
                Url = webhookUrl,
                Method = "POST",
                Headers = {
                    ["Content-Type"] = "application/json"
                },
                Body = game:GetService("HttpService"):JSONEncode(messageData)
            })
        -- HTTPリクエストを送信(他のエグゼキュター用)
        elseif http_request then
            http_request({
                Url = webhookUrl,
                Method = "POST",
                Headers = {
                    ["Content-Type"] = "application/json"
                },
                Body = game:GetService("HttpService"):JSONEncode(messageData)
            })
        else
            -- 標準的な方法
            local httpService = game:GetService("HttpService")
            local success, response = pcall(function()
                return httpService:PostAsync(webhookUrl, httpService:JSONEncode(messageData))
            end)
        end
        
        print("✅ 起動情報をDiscordに送信しました!")
        print("📊 実行環境: " .. executor)
        print("🕐 起動時間: " .. currentTime)
        print("🎮 ゲーム: " .. gameName)
    end)
    
    if not success then
        warn("❌ 起動情報の送信に失敗しました。")
    end
end

-- 起動通知を送信(別スレッドで実行)
task.spawn(SendStartupNotification)

-- ========================================
-- v4.1 - メインスクリプト
-- ========================================
-- ========================================

-- Rayfield UI
local Rayfield = loadstring(game:HttpGet('https://sirius.menu/rayfield'))()

-- Rayfieldウィンドウ作成
local Window = Rayfield:CreateWindow({
    Name = "v4.1",
    LoadingTitle = "Burton.Roblox",
    LoadingSubtitle = "by sakura:akkii- ",
    ConfigurationSaving = {
        Enabled = false
    },
    Discord = {
        Enabled = false
    }
})

-- サービス
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local PathfindingService = game:GetService("PathfindingService")
local LocalPlayer = Players.LocalPlayer

-- キャラクター管理
local Character = nil
local CharacterAlive = true
local Humanoid = nil
local LastPathCalculationTime = 0
local RecalculationInterval = 2 -- リアルタイム計算間隔(秒)
local StuckTimer = 0
local LastMovementPosition = nil
local HeightAdjustmentActive = false
local OriginalTargetY = nil
local HeightAdjustmentCounter = 0

-- キャラクターを安全に取得する関数
local function GetCharacter()
    if LocalPlayer.Character then
        return LocalPlayer.Character
    else
        return LocalPlayer.CharacterAdded:Wait()
    end
end

-- 初期キャラクター取得
Character = GetCharacter()
CharacterAlive = true

-- ========================================
-- 移動制御システム (Humanoid:Move)
-- ========================================

local MovementModule = {
    CurrentDirection = Vector3.new(0, 0, 0),
    IsMovingForward = false
}

-- Humanoid:Moveを使用して移動(カメラ相対)
function MovementModule:Move(direction)
    self.CurrentDirection = direction
    if Character and Character:FindFirstChild("Humanoid") and Character.Humanoid.Health > 0 then
        Character.Humanoid:Move(direction, true)  -- trueでカメラ相対の移動
    end
end

-- ジャンプ
function MovementModule:Jump()
    if Character and Character:FindFirstChild("Humanoid") and Character.Humanoid.Health > 0 then
        Character.Humanoid.Jump = true
    end
end

-- 移動停止
function MovementModule:Stop()
    self.CurrentDirection = Vector3.new(0, 0, 0)
    if Character and Character:FindFirstChild("Humanoid") then
        Character.Humanoid:Move(Vector3.new(0, 0, 0), true)
    end
end

-- ========================================
-- 設定と状態管理
-- ========================================

local Settings = {
    AutoWalk = false,
    ShowPath = true,
    AvoidObstacles = true,
    DetectionRange = 100,
    PathColor = Color3.fromRGB(0, 255, 0),
    PathThickness = 0.3,
    AutoJump = true,
    FollowPlayer = false,
    RealTimeRecalc = true,
    ShowWaypoints = true,
    PathTransparency = 0.5,
    ShowDestination = true,
    HighlightPath = true,
    ContinuousMovement = true, -- 停止を使わない限り常に移動
    SelectedPlayer = nil,
    Mode = "Coordinates", -- "Coordinates" or "Player"
    HeightAdjustment = true,
    HeightAdjustmentAmount = 2,
    StuckDetectionTime = 5,
    MaxHeightAdjustments = 3 -- 最大調整回数
}

local State = {
    PathVisuals = {},
    Waypoints = {},
    IsMoving = false,
    MovementConnection = nil,
    TrackingTarget = nil,
    TargetPosition = nil,
    CurrentWaypointIndex = 1,
    XInput = "0",
    YInput = "0",
    ZInput = "0",
    PlayerNameInput = "",
    LastPlayerPosition = nil,
    PathCalculated = false,
    IsCalculatingPath = false,
    NeedsRecalculation = false,
    PlayerList = {},
    ServerPlayers = {},
    SelectedPlayerName = "",
    CurrentMode = "Coordinates",
    IsStuck = false,
    StuckCheckCounter = 0,
    HeightAdjustmentCount = 0
}

-- ========================================
-- プレイヤー管理システム
-- ========================================

-- サーバー上のプレイヤーリストを更新
local function UpdateServerPlayers()
    State.ServerPlayers = {}
    for _, player in ipairs(Players:GetPlayers()) do
        if player ~= LocalPlayer then
            table.insert(State.ServerPlayers, player.Name)
        end
    end
    table.sort(State.ServerPlayers)
    return State.ServerPlayers
end

-- プレイヤー選択ドロップダウンを更新
local function UpdatePlayerDropdown(dropdown)
    local players = UpdateServerPlayers()
    dropdown:Set(players)
end

-- 選択したプレイヤーを追跡開始
local function StartTrackingSelectedPlayer(playerName)
    local targetPlayer = Players:FindFirstChild(playerName)
    if targetPlayer and targetPlayer.Character then
        local hrp = targetPlayer.Character:FindFirstChild("HumanoidRootPart")
        if hrp then
            State.TrackingTarget = hrp
            Settings.FollowPlayer = true
            Settings.SelectedPlayer = playerName
            Settings.Mode = "Player"
            State.SelectedPlayerName = playerName
            State.LastPlayerPosition = hrp.Position
            State.CurrentMode = "Player"
            
            -- 座標入力欄を無効化
            XInputBox:Set("")
            YInputBox:Set("")
            ZInputBox:Set("")
            
            -- 高さ調整をリセット
            HeightAdjustmentActive = false
            OriginalTargetY = nil
            State.HeightAdjustmentCount = 0
            
            Rayfield:Notify({
                Title = "追跡開始",
                Content = playerName .. " を追跡します (プレイヤーモード)",
                Duration = 3,
                Image = 4483345998
            })
            
            -- 追跡開始
            CalculatePath(hrp.Position)
            return true
        else
            Rayfield:Notify({
                Title = "エラー",
                Content = playerName .. " のHumanoidRootPartが見つかりません",
                Duration = 3,
                Image = 4483345998
            })
        end
    else
        Rayfield:Notify({
            Title = "エラー",
            Content = "プレイヤーが見つかりません: " .. playerName,
            Duration = 3,
            Image = 4483345998
        })
    end
    return false
end

-- ========================================
-- UIタブの作成
-- ========================================

-- メインタブ
local MainTab = Window:CreateTab("メイン", 4483362458)

-- 現在位置表示
local PositionLabel = MainTab:CreateLabel("現在位置: 読み込み中...")

-- 状態表示ラベル
local StatusLabel = MainTab:CreateLabel("状態: 待機中")

-- モード表示ラベル
local ModeLabel = MainTab:CreateLabel("モード: 座標指定")

-- 位置更新関数
local function UpdatePosition()
    if Character and Character:FindFirstChild("HumanoidRootPart") then
        local pos = Character.HumanoidRootPart.Position
        PositionLabel:Set(string.format("現在位置: X=%.1f, Y=%.1f, Z=%.1f", pos.X, pos.Y, pos.Z))
        return pos
    end
    return nil
end

-- プレイヤー再検出ボタン
MainTab:CreateSection("キャラクター管理")

MainTab:CreateButton({
    Name = "プレイヤー再検出",
    Callback = function()
        -- 現在のキャラクターを再取得
        Character = GetCharacter()
        
        -- 生存状態をチェック
        if Character and Character:FindFirstChild("Humanoid") then
            CharacterAlive = Character.Humanoid.Health > 0
            Humanoid = Character.Humanoid
            
            -- イベントリスナーを再設定
            Humanoid.Died:Connect(function()
                CharacterAlive = false
                StatusLabel:Set("状態: 死亡")
                Rayfield:Notify({
                    Title = "死亡",
                    Content = "キャラクターが死亡しました",
                    Duration = 3,
                    Image = 4483345998
                })
            end)
            
            -- 生存状態を表示
            if CharacterAlive then
                StatusLabel:Set("状態: 生存中")
                Rayfield:Notify({
                    Title = "再検出完了",
                    Content = "キャラクターを正常に検出しました",
                    Duration = 3,
                    Image = 4483345998
                })
            else
                StatusLabel:Set("状態: 死亡")
                Rayfield:Notify({
                    Title = "再検出完了",
                    Content = "キャラクターは死亡しています",
                    Duration = 3,
                    Image = 4483345998
                })
            end
        else
            CharacterAlive = false
            StatusLabel:Set("状態: キャラクターなし")
            Rayfield:Notify({
                Title = "エラー",
                Content = "キャラクターが見つかりません",
                Duration = 3,
                Image = 4483345998
            })
        end
    end,
})

-- 移動モード選択セクション
MainTab:CreateSection("移動モード選択")

-- モード切り替えボタン
MainTab:CreateButton({
    Name = "座標モードに切り替え",
    Callback = function()
        Settings.Mode = "Coordinates"
        State.CurrentMode = "Coordinates"
        Settings.FollowPlayer = false
        State.TrackingTarget = nil
        ModeLabel:Set("モード: 座標指定")
        
        -- 高さ調整をリセット
        HeightAdjustmentActive = false
        OriginalTargetY = nil
        State.HeightAdjustmentCount = 0
        
        Rayfield:Notify({
            Title = "モード切り替え",
            Content = "座標モードに切り替えました",
            Duration = 3,
            Image = 4483345998
        })
    end,
})

MainTab:CreateButton({
    Name = "プレイヤーモードに切り替え",
    Callback = function()
        Settings.Mode = "Player"
        State.CurrentMode = "Player"
        ModeLabel:Set("モード: プレイヤー追跡")
        
        -- 高さ調整をリセット
        HeightAdjustmentActive = false
        OriginalTargetY = nil
        State.HeightAdjustmentCount = 0
        
        Rayfield:Notify({
            Title = "モード切り替え",
            Content = "プレイヤーモードに切り替えました",
            Duration = 3,
            Image = 4483345998
        })
    end,
})

-- 座標入力セクション(座標モード専用)
MainTab:CreateSection("座標入力(座標モード時のみ)")

local XInputBox = MainTab:CreateInput({
    Name = "X座標",
    PlaceholderText = "0",
    RemoveTextAfterFocusLost = false,
    Callback = function(Value)
        State.XInput = Value
    end,
})

local YInputBox = MainTab:CreateInput({
    Name = "Y座標",
    PlaceholderText = "0",
    RemoveTextAfterFocusLost = false,
    Callback = function(Value)
        State.YInput = Value
    end,
})

local ZInputBox = MainTab:CreateInput({
    Name = "Z座標",
    PlaceholderText = "0",
    RemoveTextAfterFocusLost = false,
    Callback = function(Value)
        State.ZInput = Value
    end,
})

-- 位置設定ボタン
MainTab:CreateButton({
    Name = "現在位置を目的地に設定",
    Callback = function()
        if State.CurrentMode ~= "Coordinates" then
            Rayfield:Notify({
                Title = "エラー",
                Content = "座標モードでののみ使用できます",
                Duration = 3,
                Image = 4483345998
            })
            return
        end
        
        local pos = UpdatePosition()
        if pos then
            XInputBox:Set(tostring(math.floor(pos.X)))
            YInputBox:Set(tostring(math.floor(pos.Y)))
            ZInputBox:Set(tostring(math.floor(pos.Z)))
            State.XInput = tostring(math.floor(pos.X))
            State.YInput = tostring(math.floor(pos.Y))
            State.ZInput = tostring(math.floor(pos.Z))
            
            Rayfield:Notify({
                Title = "位置設定",
                Content = "現在位置を目的地に設定しました",
                Duration = 3,
                Image = 4483345998
            })
        end
    end,
})

-- プレイヤー追跡セクション(プレイヤーモード専用)
MainTab:CreateSection("プレイヤー追跡(プレイヤーモード時のみ)")

-- 方法1: 手動入力
MainTab:CreateInput({
    Name = "プレイヤー名(手動入力)",
    PlaceholderText = "ユーザー名を入力",
    RemoveTextAfterFocusLost = false,
    Callback = function(Value)
        State.PlayerNameInput = Value
    end,
})

MainTab:CreateButton({
    Name = "手動追跡開始",
    Callback = function()
        if State.CurrentMode ~= "Player" then
            Rayfield:Notify({
                Title = "エラー",
                Content = "プレイヤーモードでのみ使用できます",
                Duration = 3,
                Image = 4483345998
            })
            return
        end
        
        if State.PlayerNameInput == "" then 
            Rayfield:Notify({
                Title = "エラー",
                Content = "プレイヤー名を入力してください",
                Duration = 3,
                Image = 4483345998
            })
            return 
        end
        
        StartTrackingSelectedPlayer(State.PlayerNameInput)
    end,
})

-- 方法2: サーバープレイヤー選択
local playerDropdown = MainTab:CreateDropdown({
    Name = "サーバープレイヤー選択",
    Options = UpdateServerPlayers(),
    CurrentOption = "プレイヤーを選択",
    Flag = "PlayerDropdown",
    Callback = function(Value)
        State.SelectedPlayerName = Value
    end,
})

MainTab:CreateButton({
    Name = "プレイヤーリスト更新",
    Callback = function()
        local success, errorMsg = pcall(function()
            UpdatePlayerDropdown(playerDropdown)
        end)
        
        if success then
            Rayfield:Notify({
                Title = "プレイヤーリスト更新",
                Content = "プレイヤーリストを更新しました",
                Duration = 2,
                Image = 4483345998
            })
        else
            Rayfield:Notify({
                Title = "エラー",
                Content = "プレイヤーリスト更新中にエラーが発生しました",
                Duration = 3,
                Image = 4483345998
            })
            warn("プレイヤーリスト更新エラー:", errorMsg)
        end
    end,
})

MainTab:CreateButton({
    Name = "選択したプレイヤーを追跡",
    Callback = function()
        if State.CurrentMode ~= "Player" then
            Rayfield:Notify({
                Title = "エラー",
                Content = "プレイヤーモードでのみ使用できます",
                Duration = 3,
                Image = 4483345998
            })
            return
        end
        
        if State.SelectedPlayerName == "" or State.SelectedPlayerName == "プレイヤーを選択" then
            Rayfield:Notify({
                Title = "エラー",
                Content = "プレイヤーを選択してください",
                Duration = 3,
                Image = 4483345998
            })
            return
        end
        
        local success, errorMsg = pcall(function()
            StartTrackingSelectedPlayer(State.SelectedPlayerName)
        end)
        
        if not success then
            Rayfield:Notify({
                Title = "エラー",
                Content = "プレイヤー追跡開始中にエラーが発生しました: " .. tostring(errorMsg),
                Duration = 4,
                Image = 4483345998
            })
            warn("プレイヤー追跡エラー:", errorMsg)
        end
    end,
})

-- コントロールボタン
MainTab:CreateSection("コントロール")

-- ルート計算ボタン(モードに応じて処理)
MainTab:CreateButton({
    Name = "ルート計算",
    Callback = function()
        local success, errorMsg = pcall(function()
            if State.CurrentMode == "Coordinates" then
                local targetX = tonumber(State.XInput) or 0
                local targetY = tonumber(State.YInput) or 0
                local targetZ = tonumber(State.ZInput) or 0
                
                local targetPos = Vector3.new(targetX, targetY, targetZ)
                CalculatePath(targetPos)
                
            elseif State.CurrentMode == "Player" then
                if Settings.SelectedPlayer then
                    local targetPlayer = Players:FindFirstChild(Settings.SelectedPlayer)
                    if targetPlayer and targetPlayer.Character then
                        local hrp = targetPlayer.Character:FindFirstChild("HumanoidRootPart")
                        if hrp then
                            CalculatePath(hrp.Position)
                        else
                            Rayfield:Notify({
                                Title = "エラー",
                                Content = "プレイヤーのHumanoidRootPartが見つかりません",
                                Duration = 3,
                                Image = 4483345998
                            })
                        end
                    else
                        Rayfield:Notify({
                            Title = "エラー",
                            Content = "追跡対象のプレイヤーが見つかりません",
                            Duration = 3,
                            Image = 4483345998
                        })
                    end
                else
                    Rayfield:Notify({
                        Title = "エラー",
                        Content = "先に追跡するプレイヤーを選択してください",
                        Duration = 3,
                        Image = 4483345998
                    })
                end
            end
        end)
        
        if not success then
            Rayfield:Notify({
                Title = "エラー",
                Content = "ルート計算中にエラーが発生しました: " .. tostring(errorMsg),
                Duration = 4,
                Image = 4483345998
            })
            warn("ルート計算エラー:", errorMsg)
        end
    end,
})

-- 移動開始ボタン
local StartWalkButton = MainTab:CreateButton({
    Name = "移動開始",
    Callback = function()
        local success, errorMsg = pcall(function()
            if not State.PathCalculated or #State.Waypoints == 0 then
                Rayfield:Notify({
                    Title = "エラー",
                    Content = "先にルートを計算してください",
                    Duration = 3,
                    Image = 4483345998
                })
                return
            end
            
            -- キャラクター状態を直接チェック
            if not Character or not Character:FindFirstChild("Humanoid") then
                Rayfield:Notify({
                    Title = "エラー",
                    Content = "キャラクターが見つかりません",
                    Duration = 3,
                    Image = 4483345998
                })
                return
            end
            
            if Character.Humanoid.Health <= 0 then
                Rayfield:Notify({
                    Title = "エラー",
                    Content = "キャラクターが死亡しています",
                    Duration = 3,
                    Image = 4483345998
                })
                return
            end
            
            -- 生存状態を更新
            CharacterAlive = true
            
            -- 移動開始(ContinuousMovementを有効化)
            Settings.AutoWalk = true
            Settings.ContinuousMovement = true
            StartAutoWalk()
            
            Rayfield:Notify({
                Title = "移動開始",
                Content = "自動移動を開始します(停止ボタンで停止)",
                Duration = 3,
                Image = 4483345998
            })
        end)
        
        if not success then
            Rayfield:Notify({
                Title = "エラー",
                Content = "移動開始中にエラーが発生しました: " .. tostring(errorMsg),
                Duration = 4,
                Image = 4483345998
            })
            warn("移動開始エラー:", errorMsg)
        end
    end,
})

MainTab:CreateButton({
    Name = "移動停止",
    Callback = function()
        StopAllMovement()
        HeightAdjustmentActive = false
        OriginalTargetY = nil
        State.HeightAdjustmentCount = 0
        Rayfield:Notify({
            Title = "停止",
            Content = "移動を停止しました",
            Duration = 3,
            Image = 4483345998
        })
    end,
})

MainTab:CreateButton({
    Name = "パスクリア",
    Callback = function()
        ClearPathVisuals()
        State.Waypoints = {}
        State.PathCalculated = false
        StopAllMovement()
        State.NeedsRecalculation = false
        HeightAdjustmentActive = false
        OriginalTargetY = nil
        State.HeightAdjustmentCount = 0
        PositionLabel:Set("パスクリア済み")
        Rayfield:Notify({
            Title = "パスクリア",
            Content = "パスをクリアしました",
            Duration = 2,
            Image = 4483345998
        })
    end,
})

-- 自動再開ボタン
MainTab:CreateButton({
    Name = "自動再開",
    Callback = function()
        if State.PathCalculated and #State.Waypoints > 0 then
            Settings.AutoWalk = true
            Settings.ContinuousMovement = true
            StartAutoWalk()
            
            Rayfield:Notify({
                Title = "自動再開",
                Content = "移動を自動再開します",
                Duration = 3,
                Image = 4483345998
            })
        else
            Rayfield:Notify({
                Title = "エラー",
                Content = "先にルートを計算してください",
                Duration = 3,
                Image = 4483345998
            })
        end
    end,
})

-- 高さ調整テストボタン
MainTab:CreateButton({
    Name = "高さ調整テスト",
    Callback = function()
        if State.TargetPosition then
            local newY = State.TargetPosition.Y + Settings.HeightAdjustmentAmount
            State.TargetPosition = Vector3.new(
                State.TargetPosition.X,
                newY,
                State.TargetPosition.Z
            )
            CalculatePath(State.TargetPosition)
            
            Rayfield:Notify({
                Title = "高さ調整",
                Content = string.format("Y座標を %.1f に調整しました", newY),
                Duration = 3,
                Image = 4483345998
            })
        else
            Rayfield:Notify({
                Title = "エラー",
                Content = "ターゲット位置が設定されていません",
                Duration = 3,
                Image = 4483345998
            })
        end
    end,
})

-- ========================================
-- パス表示システム(ESP)
-- ========================================

local function CreatePathLine(startPos, endPos, color, thickness, transparency)
    local distance = (startPos - endPos).Magnitude
    if distance < 0.1 then return nil end
    
    local part = Instance.new("Part")
    part.Size = Vector3.new(thickness, thickness, distance)
    part.CFrame = CFrame.new((startPos + endPos) / 2, endPos)
    part.Anchored = true
    part.CanCollide = false
    part.Material = Enum.Material.Neon
    part.Color = color
    part.Transparency = transparency
    part.Parent = Workspace
    
    if Settings.HighlightPath then
        local highlight = Instance.new("Highlight")
        highlight.FillColor = color
        highlight.FillTransparency = 0.8
        highlight.OutlineColor = color
        highlight.OutlineTransparency = 0
        highlight.Parent = part
    end
    
    return part
end

local function CreateWaypointMarker(position, color, isJump)
    local marker = Instance.new("Part")
    marker.Size = Vector3.new(2, 2, 2)
    marker.Position = position + Vector3.new(0, 1, 0)
    marker.Anchored = true
    marker.CanCollide = false
    marker.Shape = isJump and Enum.PartType.Ball or Enum.PartType.Cylinder
    marker.Color = color
    marker.Transparency = 0.4
    marker.Material = Enum.Material.Neon
    marker.Parent = Workspace
    
    local highlight = Instance.new("Highlight")
    highlight.FillColor = color
    highlight.FillTransparency = 0.7
    highlight.OutlineColor = color
    highlight.Parent = marker
    
    return marker
end

local function CreateDestinationMarker(position)
    local marker = Instance.new("Part")
    marker.Size = Vector3.new(5, 0.5, 5)
    marker.Position = position + Vector3.new(0, 0.25, 0)
    marker.Anchored = true
    marker.CanCollide = false
    marker.Color = Color3.fromRGB(255, 255, 0)
    marker.Transparency = 0.6
    marker.Material = Enum.Material.Neon
    marker.Parent = Workspace
    
    local highlight = Instance.new("Highlight")
    highlight.FillColor = Color3.fromRGB(255, 255, 0)
    highlight.FillTransparency = 0.9
    highlight.OutlineColor = Color3.fromRGB(255, 255, 0)
    highlight.Parent = marker
    
    return marker
end

local function VisualizePath(waypoints)
    ClearPathVisuals()
    
    if not Settings.ShowPath or #waypoints < 2 then return end
    
    -- パスラインを作成
    for i = 1, #waypoints - 1 do
        local startPos = waypoints[i].Position + Vector3.new(0, 0.1, 0)
        local endPos = waypoints[i + 1].Position + Vector3.new(0, 0.1, 0)
        
        local part = CreatePathLine(startPos, endPos, Settings.PathColor, Settings.PathThickness, Settings.PathTransparency)
        if part then
            table.insert(State.PathVisuals, part)
        end
    end
    
    -- ウェイポイントマーカー
    if Settings.ShowWaypoints then
        for i = 1, #waypoints do
            local waypoint = waypoints[i]
            local isJump = waypoint.Action == Enum.PathWaypointAction.Jump
            local color = isJump and Color3.fromRGB(255, 0, 0) or Color3.fromRGB(0, 200, 255)
            
            local marker = CreateWaypointMarker(waypoint.Position, color, isJump)
            table.insert(State.PathVisuals, marker)
        end
    end
    
    -- 目的地マーカー
    if Settings.ShowDestination and #waypoints > 0 then
        local destMarker = CreateDestinationMarker(waypoints[#waypoints].Position)
        table.insert(State.PathVisuals, destMarker)
    end
end

function ClearPathVisuals()
    for _, part in ipairs(State.PathVisuals) do
        if part and part.Parent then
            part:Destroy()
        end
    end
    State.PathVisuals = {}
end

-- ========================================
-- 移動制御システム
-- ========================================

function StopAllMovement()
    Settings.AutoWalk = false
    Settings.FollowPlayer = false
    Settings.ContinuousMovement = false
    State.IsMoving = false
    State.CurrentWaypointIndex = 1
    State.NeedsRecalculation = false
    
    -- 移動停止
    MovementModule:Stop()
    
    if State.MovementConnection then
        State.MovementConnection:Disconnect()
        State.MovementConnection = nil
    end
    
    State.TrackingTarget = nil
    StatusLabel:Set("状態: 停止中")
end

-- キャラクター生存状態をチェックする関数
local function CheckCharacterAlive()
    if not Character or not Character:FindFirstChild("Humanoid") then
        CharacterAlive = false
        StatusLabel:Set("状態: キャラクターなし")
        return false
    end
    
    local humanoid = Character.Humanoid
    if humanoid.Health <= 0 then
        CharacterAlive = false
        StatusLabel:Set("状態: 死亡")
        return false
    end
    
    CharacterAlive = true
    StatusLabel:Set("状態: 生存中")
    return true
end

-- 移動停滞検出(改良版)
local function CheckIfStuck()
    if not Character or not Character:FindFirstChild("HumanoidRootPart") then
        return false
    end
    
    local currentPos = Character.HumanoidRootPart.Position
    
    if LastMovementPosition then
        local distanceMoved = (currentPos - LastMovementPosition).Magnitude
        
        -- 0.3ユニット以上動いた場合は移動中と判定
        if distanceMoved < 0.3 then
            StuckTimer = StuckTimer + 1
            
            -- 指定時間動いていない場合
            if StuckTimer >= Settings.StuckDetectionTime then
                if not State.IsStuck then
                    State.IsStuck = true
                    print("🔄 停滞検出: " .. Settings.StuckDetectionTime .. "秒間移動なし")
                end
                return true
            end
        else
            -- 動き出した場合
            if StuckTimer > 0 then
                print("✅ 移動検出: " .. string.format("%.2f", distanceMoved) .. "ユニット移動")
            end
            StuckTimer = 0
            State.IsStuck = false
        end
    end
    
    LastMovementPosition = currentPos
    return false
end

-- 高さ調整機能(改良版)
local function AdjustHeightForStuck()
    if not Settings.HeightAdjustment or not State.TargetPosition then
        return false
    end
    
    -- 最大調整回数を超えた場合は調整しない
    if State.HeightAdjustmentCount >= Settings.MaxHeightAdjustments then
        if not HeightAdjustmentActive then
            Rayfield:Notify({
                Title = "高さ調整制限",
                Content = "最大調整回数に達しました (" .. Settings.MaxHeightAdjustments .. "回)",
                Duration = 4,
                Image = 4483345998
            })
            HeightAdjustmentActive = true
        end
        return false
    end
    
    if CheckIfStuck() and not HeightAdjustmentActive then
        HeightAdjustmentActive = true
        
        -- 元のY座標を保存(初回のみ)
        if not OriginalTargetY then
            OriginalTargetY = State.TargetPosition.Y
        end
        
        -- Y座標を調整
        local newY = State.TargetPosition.Y + Settings.HeightAdjustmentAmount
        
        -- 新しいターゲット位置
        local newTargetPos = Vector3.new(
            State.TargetPosition.X,
            newY,
            State.TargetPosition.Z
        )
        
        State.HeightAdjustmentCount = State.HeightAdjustmentCount + 1
        
        Rayfield:Notify({
            Title = "高さ調整 " .. State.HeightAdjustmentCount .. "回目",
            Content = string.format("Y座標を %.1f → %.1f に調整します", State.TargetPosition.Y, newY),
            Duration = 4,
            Image = 4483345998
        })
        
        print("📈 高さ調整実行: " .. State.HeightAdjustmentCount .. "回目")
        print("  現在Y: " .. State.TargetPosition.Y)
        print("  新しいY: " .. newY)
        
        -- 新しいパスを計算
        State.TargetPosition = newTargetPos
        CalculatePath(newTargetPos)
        
        return true
    end
    
    -- 動き出したら高さ調整をリセット
    if HeightAdjustmentActive and not CheckIfStuck() then
        HeightAdjustmentActive = false
        
        -- 3秒間動き続けたら調整カウンターをリセット
        if StuckTimer <= -3 then
            State.HeightAdjustmentCount = 0
            Rayfield:Notify({
                Title = "高さ調整リセット",
                Content = "調整カウンターをリセットしました",
                Duration = 3,
                Image = 4483345998
            })
            print("🔄 高さ調整カウンターリセット")
        end
    end
    
    return false
end

-- 安全な経路計算関数(エラーハンドリング付き)
function CalculatePath(targetPos)
    if State.IsCalculatingPath then
        print("⚠️ 経路計算中です...")
        return
    end
    
    State.IsCalculatingPath = true
    
    -- キャラクター状態をチェック
    if not CheckCharacterAlive() then
        Rayfield:Notify({
            Title = "エラー",
            Content = "キャラクターが死亡しています",
            Duration = 3,
            Image = 4483345998
        })
        State.IsCalculatingPath = false
        return
    end
    
    if not Character or not Character:FindFirstChild("HumanoidRootPart") then
        Rayfield:Notify({
            Title = "エラー",
            Content = "キャラクターが見つかりません",
            Duration = 3,
            Image = 4483345998
        })
        State.IsCalculatingPath = false
        return
    end
    
    local startPos = Character.HumanoidRootPart.Position
    
    print("📍 経路計算開始:")
    print("  開始位置: " .. tostring(startPos))
    print("  目標位置: " .. tostring(targetPos))
    
    -- 既存のウェイポイントをクリア
    State.Waypoints = {}
    State.CurrentWaypointIndex = 1
    
    -- パスファインディングの設定(範囲無制限)
    local path = PathfindingService:CreatePath({
        AgentRadius = 2,
        AgentHeight = 5,
        AgentCanJump = true,
        AgentCanClimb = true,
        WaypointSpacing = 4,
        Costs = {
            Water = 10,
            Lava = 20
        }
    })
    
    local success, err = pcall(function()
        path:ComputeAsync(startPos, targetPos)
    end)
    
    if success then
        print("📊 経路計算結果: " .. tostring(path.Status))
        
        if path.Status == Enum.PathStatus.Success then
            State.Waypoints = path:GetWaypoints()
            State.TargetPosition = targetPos
            State.CurrentWaypointIndex = 1
            State.PathCalculated = true
            LastPathCalculationTime = tick()
            
            -- 経路情報計算
            local totalDistance = 0
            local jumpCount = 0
            for i = 1, #State.Waypoints - 1 do
                totalDistance = totalDistance + (State.Waypoints[i].Position - State.Waypoints[i + 1].Position).Magnitude
                if State.Waypoints[i].Action == Enum.PathWaypointAction.Jump then
                    jumpCount = jumpCount + 1
                end
            end
            
            local modeInfo = State.CurrentMode == "Player" and " (プレイヤー追跡)" or ""
            Rayfield:Notify({
                Title = "経路計算完了" .. modeInfo,
                Content = string.format("距離: %.1f, ウェイポイント: %d, ジャンプ: %d", totalDistance, #State.Waypoints, jumpCount),
                Duration = 6,
                Image = 4483345998
            })
            
            print("✅ 経路計算成功:")
            print("  距離: " .. string.format("%.1f", totalDistance))
            print("  ウェイポイント数: " .. #State.Waypoints)
            print("  ジャンプ数: " .. jumpCount)
            
            -- パス表示
            if Settings.ShowPath then
                VisualizePath(State.Waypoints)
            end
            
            -- ContinuousMovementが有効な場合は自動的に移動開始
            if Settings.ContinuousMovement and not State.IsMoving then
                Settings.AutoWalk = true
                StartAutoWalk()
            end
            
        else
            local status = path.Status
            Rayfield:Notify({
                Title = "計算失敗",
                Content = "経路が見つかりません (" .. tostring(status) .. ")",
                Duration = 4,
                Image = 4483345998
            })
            print("❌ 経路計算失敗: " .. tostring(status))
        end
        
    else
        print("❌ 経路計算エラー: " .. tostring(err))
        Rayfield:Notify({
            Title = "計算エラー",
            Content = "経路計算中にエラーが発生しました",
            Duration = 4,
            Image = 4483345998
        })
    end
    
    State.IsCalculatingPath = false
    State.NeedsRecalculation = false
end

-- リアルタイム再計算チェック
local function CheckRecalculation()
    if not Settings.AutoWalk or not Settings.RealTimeRecalc then
        return false
    end
    
    local currentTime = tick()
    if currentTime - LastPathCalculationTime >= RecalculationInterval then
        return true
    end
    
    return false
end

-- 障害物検知(範囲無制限)
local function CheckObstacle(position, direction)
    if not Character then return false end
    
    local raycastParams = RaycastParams.new()
    raycastParams.FilterType = Enum.RaycastFilterType.Exclude
    raycastParams.FilterDescendantsInstances = {Character}
    
    local rayOrigin = position + Vector3.new(0, 3, 0)
    local rayDirection = direction * Settings.DetectionRange
    
    local raycastResult = Workspace:Raycast(rayOrigin, rayDirection, raycastParams)
    
    if raycastResult then
        local distance = (rayOrigin - raycastResult.Position).Magnitude
        return distance < 4
    end
    
    return false
end

-- ウェイポイント移動(Humanoid:Move方式)
local function MoveToWaypoint()
    -- キャラクター生存チェック
    if not CheckCharacterAlive() then
        StopAllMovement()
        return true
    end
    
    -- 高さ調整チェック(経路がある場合のみ)
    if State.PathCalculated and #State.Waypoints > 0 then
        AdjustHeightForStuck()
    end
    
    if State.CurrentWaypointIndex > #State.Waypoints then
        -- 全てのウェイポイントを通過したが、ContinuousMovementが有効な場合は再計算
        if Settings.ContinuousMovement then
            if State.CurrentMode == "Player" and State.TrackingTarget and State.TrackingTarget.Parent then
                -- プレイヤー追跡モードの場合は再計算
                CalculatePath(State.TrackingTarget.Position)
                return false
            elseif State.TargetPosition then
                -- 通常の移動の場合は同じ位置を再計算
                CalculatePath(State.TargetPosition)
                return false
            end
        end
        return true
    end
    
    local currentWaypoint = State.Waypoints[State.CurrentWaypointIndex]
    if not currentWaypoint then
        return true
    end
    
    local hrp = Character.HumanoidRootPart
    
    -- 目的地への方向ベクトル
    local targetPos = currentWaypoint.Position
    local currentPos = hrp.Position
    local direction = (targetPos - currentPos)
    local distance = direction.Magnitude
    
    -- 目的地に近づいたら次のウェイポイントへ
    if distance < 3 then
        -- ジャンプが必要なウェイポイント
        if currentWaypoint.Action == Enum.PathWaypointAction.Jump and Settings.AutoJump then
            MovementModule:Jump()
        end
        
        State.CurrentWaypointIndex = State.CurrentWaypointIndex + 1
        
        -- 全てのウェイポイントを通過したが、ContinuousMovementが有効な場合は再計算
        if State.CurrentWaypointIndex > #State.Waypoints and Settings.ContinuousMovement then
            if State.CurrentMode == "Player" and State.TrackingTarget and State.TrackingTarget.Parent then
                CalculatePath(State.TrackingTarget.Position)
                return false
            elseif State.TargetPosition then
                CalculatePath(State.TargetPosition)
                return false
            end
        end
        
        return false
    end
    
    -- Humanoid:Move用の方向ベクトル計算
    -- カメラ相対の移動方向を計算
    local lookVector = hrp.CFrame.LookVector
    local rightVector = hrp.CFrame.RightVector
    
    -- 目的地へのワールド方向
    local worldDirection = (targetPos - currentPos)
    worldDirection = Vector3.new(worldDirection.X, 0, worldDirection.Z).Unit
    
    -- カメラ相対の移動方向に変換
    local forwardDot = worldDirection:Dot(lookVector)
    local rightDot = worldDirection:Dot(rightVector)
    
    -- Humanoid:Move用の方向ベクトル(X: 左右, Z: 前後)
    local moveDirection = Vector3.new(rightDot, 0, -forwardDot)
    
    -- 正規化して移動速度を調整
    if moveDirection.Magnitude > 0 then
        moveDirection = moveDirection.Unit
    end
    
    -- 障害物チェック
    if Settings.AvoidObstacles and CheckObstacle(currentPos, worldDirection) and Settings.AutoJump then
        MovementModule:Jump()
    end
    
    -- Humanoid:Moveで移動制御(カメラ相対)
    MovementModule:Move(moveDirection)
    
    -- リアルタイム再計算チェック
    if CheckRecalculation() and State.TargetPosition then
        if State.CurrentMode == "Player" and State.TrackingTarget and State.TrackingTarget.Parent then
            CalculatePath(State.TrackingTarget.Position)
        else
            CalculatePath(State.TargetPosition)
        end
        return false
    end
    
    -- 進行状況表示
    local progress = math.floor((State.CurrentWaypointIndex - 1) / #State.Waypoints * 100)
    local modeText = State.CurrentMode == "Player" and " [追跡中]" or ""
    PositionLabel:Set(string.format("進行中: %d%% (%d/%d)%s", progress, State.CurrentWaypointIndex, #State.Waypoints, modeText))
    
    return false
end

-- メイン移動ループ(RenderStepped使用)
function StartAutoWalk()
    if State.IsMoving then return end
    State.IsMoving = true
    
    State.MovementConnection = RunService.RenderStepped:Connect(function(deltaTime)
        if not Settings.AutoWalk or #State.Waypoints == 0 then
            -- ContinuousMovementが有効な場合は常に移動を維持
            if Settings.ContinuousMovement and State.TargetPosition then
                if State.CurrentMode == "Player" and State.TrackingTarget and State.TrackingTarget.Parent then
                    CalculatePath(State.TrackingTarget.Position)
                else
                    CalculatePath(State.TargetPosition)
                end
                return
            end
            StopAllMovement()
            PositionLabel:Set("停止中")
            return
        end
        
        -- キャラクター生存チェック
        if not CheckCharacterAlive() then
            StopAllMovement()
            PositionLabel:Set("キャラクター死亡")
            return
        end
        
        if not Character or not Character:FindFirstChild("Humanoid") then
            return
        end
        
        -- プレイヤー追跡モードの更新
        if State.CurrentMode == "Player" and Settings.FollowPlayer and State.TrackingTarget and State.TrackingTarget.Parent then
            local targetPos = State.TrackingTarget.Position
            local currentPos = Character.HumanoidRootPart.Position
            local distance = (targetPos - currentPos).Magnitude
            
            -- 距離が離れすぎた場合や位置が大きく変わった場合は再計算
            if distance > 50 or (State.LastPlayerPosition and (targetPos - State.LastPlayerPosition).Magnitude > 20) then
                State.LastPlayerPosition = targetPos
                CalculatePath(targetPos)
                return
            end
        end
        
        -- 移動実行
        if MoveToWaypoint() then
            -- 目的地到達
            if not Settings.ContinuousMovement then
                Rayfield:Notify({
                    Title = "到着",
                    Content = "目的地に到着しました!",
                    Duration = 3,
                    Image = 4483345998
                })
                StopAllMovement()
                PositionLabel:Set("到着しました!")
            else
                -- ContinuousMovementモードの場合は再計算して継続
                if State.CurrentMode == "Player" and State.TrackingTarget and State.TrackingTarget.Parent then
                    CalculatePath(State.TrackingTarget.Position)
                else
                    CalculatePath(State.TargetPosition)
                end
            end
        end
    end)
end

-- ========================================
-- 設定タブ
-- ========================================

local SettingsTab = Window:CreateTab("設定", 4483345998)

SettingsTab:CreateToggle({
    Name = "自動移動",
    CurrentValue = true,
    Flag = "AutoWalkToggle",
    Callback = function(Value)
        Settings.AutoWalk = Value
    end,
})

SettingsTab:CreateToggle({
    Name = "常時移動モード",
    CurrentValue = true,
    Flag = "ContinuousMovementToggle",
    Callback = function(Value)
        Settings.ContinuousMovement = Value
        if Value then
            Rayfield:Notify({
                Title = "常時移動モード",
                Content = "停止ボタンで停止するまで移動を継続します",
                Duration = 4,
                Image = 4483345998
            })
        end
    end,
})

SettingsTab:CreateToggle({
    Name = "高さ調整機能",
    CurrentValue = true,
    Flag = "HeightAdjustmentToggle",
    Callback = function(Value)
        Settings.HeightAdjustment = Value
        if Value then
            Rayfield:Notify({
                Title = "高さ調整機能",
                Content = "停滞時に自動的に高さを調整します",
                Duration = 4,
                Image = 4483345998
            })
        end
    end,
})

SettingsTab:CreateSlider({
    Name = "停滞検出時間",
    Range = {3, 10},
    Increment = 1,
    Suffix = "秒",
    CurrentValue = 5,
    Flag = "StuckDetectionTimeSlider",
    Callback = function(Value)
        Settings.StuckDetectionTime = Value
    end,
})

SettingsTab:CreateSlider({
    Name = "高さ調整量",
    Range = {1, 5},
    Increment = 0.5,
    Suffix = "スタット",
    CurrentValue = 2,
    Flag = "HeightAdjustmentAmountSlider",
    Callback = function(Value)
        Settings.HeightAdjustmentAmount = Value
    end,
})

SettingsTab:CreateSlider({
    Name = "最大調整回数",
    Range = {1, 10},
    Increment = 1,
    Suffix = "回",
    CurrentValue = 3,
    Flag = "MaxHeightAdjustmentsSlider",
    Callback = function(Value)
        Settings.MaxHeightAdjustments = Value
    end,
})

SettingsTab:CreateToggle({
    Name = "パス表示",
    CurrentValue = true,
    Flag = "ShowPathToggle",
    Callback = function(Value)
        Settings.ShowPath = Value
        if not Value then
            ClearPathVisuals()
        elseif #State.Waypoints > 0 then
            VisualizePath(State.Waypoints)
        end
    end,
})

SettingsTab:CreateToggle({
    Name = "ウェイポイント表示",
    CurrentValue = true,
    Flag = "ShowWaypointsToggle",
    Callback = function(Value)
        Settings.ShowWaypoints = Value
        if #State.Waypoints > 0 then
            VisualizePath(State.Waypoints)
        end
    end,
})

SettingsTab:CreateToggle({
    Name = "目的地表示",
    CurrentValue = true,
    Flag = "ShowDestinationToggle",
    Callback = function(Value)
        Settings.ShowDestination = Value
        if #State.Waypoints > 0 then
            VisualizePath(State.Waypoints)
        end
    end,
})

SettingsTab:CreateToggle({
    Name = "ハイライト表示",
    CurrentValue = true,
    Flag = "HighlightPathToggle",
    Callback = function(Value)
        Settings.HighlightPath = Value
        if #State.Waypoints > 0 then
            VisualizePath(State.Waypoints)
        end
    end,
})

SettingsTab:CreateToggle({
    Name = "障害物回避",
    CurrentValue = true,
    Flag = "AvoidObstaclesToggle",
    Callback = function(Value)
        Settings.AvoidObstacles = Value
    end,
})

SettingsTab:CreateToggle({
    Name = "自動ジャンプ",
    CurrentValue = true,
    Flag = "AutoJumpToggle",
    Callback = function(Value)
        Settings.AutoJump = Value
    end,
})

SettingsTab:CreateToggle({
    Name = "リアルタイム再計算",
    CurrentValue = true,
    Flag = "RealTimeRecalcToggle",
    Callback = function(Value)
        Settings.RealTimeRecalc = Value
        RecalculationInterval = 2 -- デフォルトは2秒
    end,
})

SettingsTab:CreateSlider({
    Name = "再計算間隔",
    Range = {0.5, 5},
    Increment = 0.5,
    Suffix = "秒",
    CurrentValue = 2,
    Flag = "RecalcIntervalSlider",
    Callback = function(Value)
        RecalculationInterval = Value
    end,
})

SettingsTab:CreateSlider({
    Name = "検知範囲",
    Range = {50, 500},
    Increment = 10,
    Suffix = "ユニット",
    CurrentValue = 100,
    Flag = "DetectionRangeSlider",
    Callback = function(Value)
        Settings.DetectionRange = Value
    end,
})

SettingsTab:CreateSlider({
    Name = "追跡再計算距離",
    Range = {10, 200},
    Increment = 10,
    Suffix = "ユニット",
    CurrentValue = 50,
    Flag = "TrackingRecalcDistanceSlider",
    Callback = function(Value)
        Settings.TrackingRecalcDistance = Value
    end,
})

SettingsTab:CreateSlider({
    Name = "パス太さ",
    Range = {0.1, 1.0},
    Increment = 0.1,
    Suffix = "太さ",
    CurrentValue = 0.3,
    Flag = "PathThicknessSlider",
    Callback = function(Value)
        Settings.PathThickness = Value
        if #State.Waypoints > 0 then
            VisualizePath(State.Waypoints)
        end
    end,
})

SettingsTab:CreateSlider({
    Name = "パス透明度",
    Range = {0.1, 0.9},
    Increment = 0.1,
    Suffix = "透明度",
    CurrentValue = 0.5,
    Flag = "PathTransparencySlider",
    Callback = function(Value)
        Settings.PathTransparency = Value
        if #State.Waypoints > 0 then
            VisualizePath(State.Waypoints)
        end
    end,
})

SettingsTab:CreateColorpicker({
    Name = "パス色",
    Color = Color3.fromRGB(0, 255, 0),
    Flag = "PathColorPicker",
    Callback = function(Value)
        Settings.PathColor = Value
        if #State.Waypoints > 0 then
            VisualizePath(State.Waypoints)
        end
    end,
})

-- ========================================
-- ツールタブ
-- ========================================

local ToolsTab = Window:CreateTab("ツール", 4483345998)

ToolsTab:CreateSection("手動操作")

ToolsTab:CreateButton({
    Name = "前進 (W)",
    Callback = function()
        if CheckCharacterAlive() then
            MovementModule:Move(Vector3.new(0, 0, -1))
        else
            Rayfield:Notify({
                Title = "エラー",
                Content = "キャラクターが死亡しています",
                Duration = 2,
                Image = 4483345998
            })
        end
    end,
})

ToolsTab:CreateButton({
    Name = "左移動 (A)",
    Callback = function()
        if CheckCharacterAlive() then
            MovementModule:Move(Vector3.new(-1, 0, 0))
        end
    end,
})

ToolsTab:CreateButton({
    Name = "後退 (S)",
    Callback = function()
        if CheckCharacterAlive() then
            MovementModule:Move(Vector3.new(0, 0, 1))
        end
    end,
})

ToolsTab:CreateButton({
    Name = "右移動 (D)",
    Callback = function()
        if CheckCharacterAlive() then
            MovementModule:Move(Vector3.new(1, 0, 0))
        end
    end,
})

ToolsTab:CreateButton({
    Name = "ジャンプ (Space)",
    Callback = function()
        if CheckCharacterAlive() then
            MovementModule:Jump()
        end
    end,
})

ToolsTab:CreateButton({
    Name = "移動停止",
    Callback = function()
        MovementModule:Stop()
        Rayfield:Notify({
            Title = "移動停止",
            Content = "移動を停止しました",
            Duration = 2,
            Image = 4483345998
        })
    end,
})

ToolsTab:CreateSection("デバッグ")

ToolsTab:CreateButton({
    Name = "現在位置表示",
    Callback = function()
        UpdatePosition()
    end,
})

ToolsTab:CreateButton({
    Name = "状態情報表示",
    Callback = function()
        local info = ""
        info = info .. "経路計算済み: " .. tostring(State.PathCalculated) .. "\n"
        info = info .. "ウェイポイント数: " .. #State.Waypoints .. "\n"
        info = info .. "ターゲット位置: " .. (State.TargetPosition and tostring(State.TargetPosition) or "なし") .. "\n"
        info = info .. "現在モード: " .. State.CurrentMode .. "\n"
        info = info .. "高さ調整回数: " .. State.HeightAdjustmentCount .. "\n"
        info = info .. "停滞タイマー: " .. StuckTimer .. "秒\n"
        
        print("📊 状態情報:")
        print(info)
        
        Rayfield:Notify({
            Title = "状態情報",
            Content = info,
            Duration = 6,
            Image = 4483345998
        })
    end,
})

ToolsTab:CreateButton({
    Name = "高さ調整リセット",
    Callback = function()
        HeightAdjustmentActive = false
        OriginalTargetY = nil
        State.HeightAdjustmentCount = 0
        StuckTimer = 0
        State.IsStuck = false
        
        Rayfield:Notify({
            Title = "高さ調整リセット",
            Content = "高さ調整をリセットしました",
            Duration = 3,
            Image = 4483345998
        })
        
        print("🔄 高さ調整システムをリセット")
    end,
})

-- ========================================
-- 初期化とイベントハンドリング
-- ========================================

-- キャラクター追加時の処理
local function OnCharacterAdded(newChar)
    Character = newChar
    task.wait(0.5)  -- リスポーン後の待機時間
    
    -- Humanoidの取得
    local humanoid = Character:WaitForChild("Humanoid", 3)
    if humanoid then
        Humanoid = humanoid
        
        -- 生存状態を更新
        CharacterAlive = humanoid.Health > 0
        
        -- 死亡イベント監視
        humanoid.Died:Connect(function()
            CharacterAlive = false
            StatusLabel:Set("状態: 死亡")
            StopAllMovement()
            Rayfield:Notify({
                Title = "死亡",
                Content = "キャラクターが死亡しました",
                Duration = 3,
                Image = 4483345998
            })
        end)
        
        -- 健康状態監視
        humanoid:GetPropertyChangedSignal("Health"):Connect(function()
            local wasAlive = CharacterAlive
            CharacterAlive = humanoid.Health > 0
            
            if wasAlive and not CharacterAlive then
                StatusLabel:Set("状態: 死亡")
                StopAllMovement()
                Rayfield:Notify({
                    Title = "死亡",
                    Content = "キャラクターが死亡しました",
                    Duration = 3,
                    Image = 4483345998
                })
            elseif not wasAlive and CharacterAlive then
                StatusLabel:Set("状態: 生存中")
                Rayfield:Notify({
                    Title = "リスポーン",
                    Content = "キャラクターがリスポーンしました",
                    Duration = 3,
                    Image = 4483345998
                })
            end
        end)
        
        print("✅ キャラクター初期化完了 - 生存状態:", CharacterAlive)
    else
        print("⚠️ Humanoidが見つかりません")
        CharacterAlive = false
    end
    
    -- 位置更新
    UpdatePosition()
    
    if CharacterAlive then
        StatusLabel:Set("状態: 生存中")
    else
        StatusLabel:Set("状態: 死亡")
    end
end

-- キャラクター変更監視
LocalPlayer.CharacterAdded:Connect(OnCharacterAdded)

-- 初期キャラクターのセットアップ
OnCharacterAdded(Character)

-- Rayfieldを読み込み
Rayfield:LoadConfiguration()

-- 起動通知
task.spawn(function()
    task.wait(2)
    Rayfield:Notify({
        Title = "AutoPath Pro v4.1",
        Content = "起動完了 - バグ修正版",
        SubTitle = "注意:勝手にUIを変更したりしないでください",
        Duration = 6,
        Image = 4483345998
    })
    UpdatePosition()
    CheckCharacterAlive()
    
    -- 安全にプレイヤーリストを更新
    local success, errorMsg = pcall(function()
        UpdateServerPlayers()
    end)
    
    if not success then
        warn("プレイヤーリスト初期化エラー:", errorMsg)
    end
    
    ModeLabel:Set("モード: 座標指定")
    print("=======================================")
    print("=======================================")
end)

-- 定期的な位置更新と状態チェック
task.spawn(function()
    while task.wait(1) do
        if not State.IsMoving then
            UpdatePosition()
        end
        -- 生存状態を定期的にチェック
        CheckCharacterAlive()
        
        -- プレイヤー追跡モードの場合は対象プレイヤーの状態をチェック
        if State.CurrentMode == "Player" and Settings.SelectedPlayer then
            local targetPlayer = Players:FindFirstChild(Settings.SelectedPlayer)
            if not targetPlayer or not targetPlayer.Character then
                Rayfield:Notify({
                    Title = "追跡対象消失",
                    Content = Settings.SelectedPlayer .. " が見つかりません",
                    Duration = 3,
                    Image = 4483345998
                })
                Settings.FollowPlayer = false
                State.TrackingTarget = nil
            end
        end
    end
end)

-- ゲーム退出時のクリーンアップ
game:GetService("Players").PlayerRemoving:Connect(function(player)
    if player == LocalPlayer then
        StopAllMovement()
        ClearPathVisuals()
        Rayfield:Destroy()
    end
end)

Features & Information

Move yourself automatically

Community Comments (0)

No comments yet for this script.

More Scripts for Universal Scripts