Making a player walk until an obstacle

Hello everyone, I am currently working on a “commanding system” with multiple levels. Basically the player can send commands to control their player and then eventually reach the end and move on to the next level. I have commanded my “guy” to go forward, then right and then forward again (to pass the level)

However I am stuck on a few points:

  • When sending the RemoteEvent to command the player to walk, I want it to stop when an obstacle is in the way (for example the wall in the middle or the wall on the right after the “right” command is done (which should then move on to forward walking again)

What I tried:

  • I have written down the Vectors for each direction (for example “Up/Straight” being 1, 0, 0), which would not be good because every level has different orientations and so Right may be straight walking or the other way around in some levels.
local vectorTables = {
    ["Up"] = Vector3.new(1, 0, 0),
    ["Down"] = Vector3.new(-1, 0, 0),
    ["Right"] = Vector3.new(0, 1, 0),
    ["Left"] = Vector3.new(0, -1, 0)
}

Basically, the main issue being that I don’t know how to make the player walk until there is an obstacle in the way, also taking in the orientation.
I am sending over a table to the server which is the directions, so {"Up", "Right", "Up"} in this case which should then be processed to make the player walk server-side and check the win-condition if walked over a yellow neon field.

This is what I’ve tried so far:

function module.executeOperation(player, informationTable)
	local data = Data.getData(player)
	if not informationTable or typeof(informationTable) ~= "table" then return end
	if not data then return end
	if not data.InGame then return end
	
	local levelFolder = Levels:FindFirstChild(data.SelectedLevel)
	if #informationTable ~= levelFolder:GetAttribute("Moves") then return end
	
	local vectorTables = {
		["Up"] = Vector3.new(-1, 0, 0),
		["Down"] = Vector3.new(1, 0, 0),
		["Right"] = Vector3.new(0, -1, 0),
		["Left"] = Vector3.new(0, 1, 0)
	}

	local character = player.Character
	local hrp = character.PrimaryPart
	local humanoid = character:WaitForChild("Humanoid")

	for index, direction in informationTable do
		
	end
	
	-- now check location if on winner pad and move on 
end

image

4 Likes

You could draw a raycast in the LookVector of the HumanoidRootPart to detect whats in front of the character. In your case, it’ll hit a wall the raycast will return the hit position which you could use to make the player move to.

1 Like

Hey, Thank you!
Do you know anything about the other issue because of the directions?

I think I know how you could fix the issue with the directions!
You can use the HumanoidRootPart of whatever character you’re trying to animate!
You can do the follorwing (as an example):

if move == "Up" then
	local direction = hrp.CFrame.LookVector
	
elseif move == "Down" then
	local direction = -hrp.CFrame.LookVector
	
elseif move == "Right" then
	local direction = hrp.CFrame.RightVector
	
elseif move == "Left" then
	local direction = -hrp.CFrame.RightVector
	
end

Basically we are just going to get the relative vectors by getting them from the chars cframe directly!

You could try to base the directions on the SpawnPoint in the middle of the level. If you have it oriented correctly, it’s LookVectors should correlate with the character.

Thank you guys for answering, I really appreciate it.
So I can combine raycasting with the solution of the vectors to find the obstacle in the way and then move on with the loop (using MoveTo and MoveToFinished)?

Yeah that should work. At least in my head.

Alright, I will try some things and let both of you know if it works or not, thank you so far :smiley:

Hmm, I have implemented as said and all 3 directions return nil, however I am looking at the obstacle and even if not it should return the wall…

function module.findDirection(player, move)
	local character = player.Character
	local hrp = character.PrimaryPart
	
	if move == "Up" then
		return hrp.CFrame.LookVector
	elseif move == "Down" then
		return -hrp.CFrame.LookVector
	elseif move == "Right" then
		return hrp.CFrame.RightVector
	elseif move == "Left" then
		return -hrp.CFrame.RightVector
	end
	-- should not happen
	return nil
end
for index, direction in informationTable do
		local direction = module.findDirection(player, direction)
		if not direction then 
			warn("No direction vector - should not happen")
			continue
		end 
		local ray = workspace:Raycast(hrp.Position, direction)
		print(ray)
	end

Change the directions to the following:

local Directions = {
    ["Up"] = Vector3.new(0, 0, -50),
    ["Down"] = Vector3.new(0, 0, 50),
    ["Left"] = Vector3.new(-50, 0, 0),
    ["Right"] = Vector3.new(50, 0, 0),
}

You don’t want to use the LookVectors for this because we are just wanting to draw the ray in a straight line in a specific direction from the HumanoidRootPart.

Oh wow! That seems to work… Thank you!

However, I am not getting a result on the right to me… Which I should have the wall

You’ll also want to add the character to be excluded.

local RayParams = RaycastParams.new()
RayParams.FilterDescendantsInstance = {Character}
RayParams.FilterType = Enum.RaycastFilterType.Exclude

local ray = workspace:Raycast(hrp.Position, direction, RayParams)

Ah okay, will add that part to the ray

Alright, the NPC is now walking straight, however as mentioned above it does not find a ray at the right (which should be a wall and I am guessing it doesn’t work if it is too far away)

Update the values in the Directions table. The wall may be further than 50 studs away. Bump it up to 100 and see if that works.

Can you explain why this did not work? It worked for me!

maybe add a:

ìf not character then
player.CharacterAdded:Wait()
character = player.Character 
end

Ah I see, I thought they were fixed for directions

I don’t know much about Vectors and never really wanted to take my time to learn them. I think what Tax said is probably true and you may want to ask him.

I will adjust the studs now and see if everything works and then I’ll mark something as solution and we are done here, thank you everyone :slight_smile: