· 5 years ago · Nov 30, 2020, 05:20 PM
1local Players = game:GetService("Players")
2local player = Players.LocalPlayer
3
4local UserInputService = game:GetService("UserInputService")
5local PathfindingService = game:GetService("PathfindingService")
6
7--Used to convert a 2D position on the Camera View to a 3D worldspace position
8local function GetPositionFromCameraView(clickLocation: Vector2)
9 --Current camera
10 local camera = workspace.CurrentCamera
11 --The length of the ray we cast
12 local length = 100
13 --Temporary Ray created at the 2D screenspace position
14 local tmpRay = camera:ViewportPointToRay(clickLocation.X, clickLocation.Y, 0)
15 --Get the 3D worldspace position that our Ray intersects with
16 local raycastResult = workspace:Raycast(tmpRay.Origin, tmpRay.Direction * length)
17
18 --Make sure we collided with something, if not, go ahead and throw error, we're gonna get one anyways
19 assert(raycastResult, "RaycastResult is nil")
20
21 --Return the 3D Worldspace location
22 return raycastResult.Position
23end
24
25--The current Waypoint we're walking towards
26local currentWaypointIndex
27--A Table of all the waypoints
28local waypoints
29
30local function followPath(targetPosition)
31 local playerHumanoid = player.Character:WaitForChild("Humanoid")
32 --Pathfinding parameters, Character can't jump
33 local params = {AgentCanJump=false}
34 --Create the Path
35 local path = PathfindingService:CreatePath(params)
36 --Compute the Path
37 path:ComputeAsync(playerHumanoid.RootPart.Position, targetPosition)
38 -- Empty waypoints table after each new path computation
39
40 --If Path successfully computed
41 if path.Status == Enum.PathStatus.Success then
42 -- Get the path waypoints
43 waypoints = path:GetWaypoints()
44 --Uncomment to display waypoints in-world
45 --[[for _, waypoint in pairs(waypoints) do
46 local part = Instance.new("Part")
47 part.Shape = "Ball"
48 part.Material = "Neon"
49 part.Size = Vector3.new(0.6, 0.6, 0.6)
50 part.Position = waypoint.Position
51 part.Anchored = true
52 part.CanCollide = false
53 part.Parent = game.Workspace
54 end]]
55
56 -- Move to first waypoint
57 currentWaypointIndex = 1
58 playerHumanoid:MoveTo(waypoints[currentWaypointIndex].Position)
59 else
60 -- If path not found, stop humanoid
61 playerHumanoid:MoveTo(playerHumanoid.RootPart.Position)
62 end
63end
64
65local function onInputBegan(input, gameProcessed)
66 --We want to ignore user input if Roblox has already processed it
67 if gameProcessed then return end
68
69 --If user right clicked
70 if input.UserInputType == Enum.UserInputType.MouseButton2 then
71 --Get the location in 3D worldspace that the user clicked
72 local targetPosition = GetPositionFromCameraView(UserInputService:GetMouseLocation())
73
74 --Reset current pathing waypoints
75 currentWaypointIndex = 0
76 waypoints = {}
77
78 --Create and Walk along path to targeted position
79 followPath(targetPosition)
80
81 --If user left clicked
82 elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
83 print("User Left clicked!")
84 end
85end
86
87--Called whenever a Waypoint is reached in the path
88local function onWaypointReached(reached)
89 local playerHumanoid = player.Character:WaitForChild("Humanoid")
90
91 --If successfully reached, and there are waypoints left to walk to
92 if reached and currentWaypointIndex < #waypoints then
93 currentWaypointIndex = currentWaypointIndex + 1
94 --walk to the next waypoint
95 playerHumanoid:MoveTo(waypoints[currentWaypointIndex].Position)
96 end
97end
98
99--We dont care about User Input before the Character exists
100player.CharacterAdded:connect(function(character)
101 local playerHumanoid = player.Character:WaitForChild("Humanoid")
102
103 UserInputService.InputBegan:Connect(onInputBegan)
104 playerHumanoid.MoveToFinished:Connect(onWaypointReached)
105end)