【问题标题】:Pathfinder is making my NPC follow my oldest position only探路者让我的 NPC 只跟随我最老的位置
【发布时间】:2021-05-05 23:02:06
【问题描述】:

我正在尝试制作迷宫/恐怖游戏。我使用 Roblox 库中的在线模板作为我的敌人。正如您将在下面的代码中看到的那样,我使用了路径查找器。它以应有的方式找到我,但它只适用于我的最后一个职位。如下图所示,它完全跳过了我,走到了我的最后一个位置,然后开始追我。我不知道为什么它只适用于我的上一个职位,而不适用于我目前的职位。

local PathFindingS = game:GetService("PathfindingService")
local humanoid = script.Parent:WaitForChild("Humanoid")
local rootPart = script.Parent:WaitForChild("HumanoidRootPart")
local Players = game:GetService("Players")
game.Workspace.Fruity.Humanoid.WalkSpeed = 60       


--To calculate the path
while wait() do
    
    for i, player in pairs(game.Players:GetPlayers()) do
        local character = game.Workspace:WaitForChild(player.Name)
        local characterPos = character.PrimaryPart.Position
        local path = PathFindingS:CreatePath()
        path:ComputeAsync(rootPart.Position, characterPos)
        game.Workspace.Fruity.HumanoidRootPart:SetNetworkOwner(nil) 
        
        local waypoints = path:GetWaypoints()

        for i, waypoint in pairs(waypoints) do
            local part = Instance.new("Part")
            part.Shape = "Ball"
            part.Material = "Neon"
            part.Size = Vector3.new(0.6,0.6,0.6)
            part.Position = waypoint.Position + Vector3.new(0,2,0)
            part.Anchored = true
            part.CanCollide = false
            part.Parent = game.Workspace
            humanoid:MoveTo(waypoint.Position)
            humanoid.MoveToFinished:Wait()  
        end 
    end
end

【问题讨论】:

    标签: lua roblox


    【解决方案1】:

    当您致电 path:ComputeAsync(rootPart.Position, characterPos) 时,您的 NPC 的寻路功能会更新。它没有更频繁地更新的原因是你用最后一行阻止了下一个循环的开始:humanoid.MoveToFinished:Wait()

    您的代码告诉 NPC,它必须步行到每个玩家之间的每一个点,这一次可能需要几分钟,然后才能再次计算路径。

    解决这个问题的方法是让它可以快速异步地重新计算路径。为此,请尝试以下操作:

    local PathfindingService = game:GetService("PathfindingService")
    local PlayerService = game:GetService("Players") 
    local humanoid = script.Parent:WaitForChild("Humanoid")
    local rootPart = script.Parent:WaitForChild("HumanoidRootPart")
    
    
    -- create a place where pathfinding orbs can be created and destroyed quickly
    local shouldDebugPath = true
    local OrbFolder = Instance.new("Folder", game.Workspace)
    OrbFolder.Name = "Debug - Orbs"
    local OrbTemplate = Instance.new("Part")
    OrbTemplate.Shape = Enum.PartType.Ball
    OrbTemplate.Material = Enum.Material.Neon
    OrbTemplate.Size = Vector3.new(0.6,0.6,0.6)
    OrbTemplate.Anchored = true
    OrbTemplate.CanCollide = false
    local function createWaypoint(position)
        local orb = OrbTemplate:Clone()
        orb.Position = position + Vector3.new(0,2,0)
        orb.Parent = OrbFolder
        
        return orb
    end
    
    
    -- set up some navigation variables and set up a chain
    -- so that when the humanoid arrives at a waypoint,
    -- it automatically selects the next point.
    local currentOrbIndex = 0
    local currentPath = {} -- store pathfinding waypoints here 
    local function moveToNextWaypoint(previousPointReached) 
        currentOrbIndex += 1
        if currentOrbIndex > #currentPath then
            return
        end
        
        local nextWaypoint = currentPath[currentOrbIndex]
        humanoid:MoveTo(nextWaypoint.Position)
    end
    humanoid.MoveToFinished:Connect(moveToNextWaypoint)
    
    
    -- calculate and continually update the path
    local pauseLength = 1.0 --seconds (lower this number to speed up refresh rate)
    while wait(pauseLength) do
        
        -- find the closest player's character model
        local targetCharacter = nil
        local closestDist = math.huge
        local playerList = PlayerService:GetPlayers()
        for i, player in pairs(playerList) do
            -- check that the player's character has spawned in
            local character = player.Character
            if not character then
                continue
            end
            
            -- do some quick maths and select which player is closest
            local p1 = character.PrimaryPart.Position
            local p2 = rootPart.Position
            local d = math.abs((p1 - p2).Magnitude)
            if d < closestDist then
                closestDist = d
                targetCharacter = character
            end
        end
        
        -- check that there are actually players in the server
        if targetCharacter == nil then
            continue
        end
            
        -- compute the path to the character
        local characterPos = targetCharacter.PrimaryPart.Position
        local path = PathfindingService:CreatePath()
        path:ComputeAsync(rootPart.Position, characterPos)
        local waypoints = path:GetWaypoints()
        
        -- debug : show the path to the player
        if shouldDebugPath then
            OrbFolder:ClearAllChildren()    
            for i, waypoint in pairs(waypoints) do
                local position = waypoint.Position
                createWaypoint(position)
            end
        end
        
        -- start the player walking towards the nearest player
        currentOrbIndex = 0
        currentPath = waypoints
        moveToNextWaypoint()
    end
    

    此解决方案每 1 秒重新计算到最近玩家的路径。该路径存储为一系列航路点,并使用Humanoid.MoveToFinished signal 作为触发器移动到下一个已知航路点。每当重新计算路径时,我们只需重新开始该过程。

    使用此系统,循环不会被阻塞,并且可以定期重新计算到不同玩家的距离和路径。这使得 NPC 也可以动态地将目标切换到最近的玩家。

    【讨论】:

    • 非常感谢,探路者现在更有意义了!!
    • 对于第 22 行,它说“return part”,我假设您说的是“return orb”?它向我显示了一个错误,即“找不到全局错误”。
    • 啊,是的,最后一秒编辑让我明白了。没错,应该是return orb
    猜你喜欢
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多