Making steering behaviors work on 3d humanoids

How do I make steering behaviors work on 3d humanoids? :MoveTo() doesn’t support moving with a velocity
Here is the current steering module I am using:

--services
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local PathfindingService = game:GetService('PathfindingService')
local ServerStorage = game:GetService('ServerStorage')

--items
local ReplicatedTools = ReplicatedStorage.ReplicatedTools

local Promise = require(ReplicatedTools.Promise)
--local Pathfind = require(script.Parent.Pathfind)
local Parenter = require(script.Parent.Parenter)

--variables
local slowing_distance = 10
local wander_distance = 7

local Steering = {}

local function closest_models(self, parent_group : string)
	local parents = Parenter:find(parent_group)
	local holder = {}
	for k, v in ipairs(parents) do
		local corrrespond_part = v.server_Part.PrimaryPart --the model being checked
		local main_part = self.server_Part.PrimaryPart --the main model 
		if corrrespond_part ~= main_part and (corrrespond_part.Position - main_part.Position).Magnitude < 10 then 
			table.insert(holder, v)
		end
	end

	return holder
end

local function getXAndZPositions(angle)
	local x = math.cos(angle) * wander_distance
	local z = math.sin(angle) * wander_distance
	return x, z
end

function Steering.check_distance(char : Model, target : Vector3)
	return (target - char.PrimaryPart.Position).Magnitude, (target - char.PrimaryPart.Position).Unit 
end

function Steering.Seperate(self, parent_group : string)
	local closest_table = closest_models(self, parent_group)

	local totalRepel_force = Vector3.new(0, 0, 0)

	if #closest_table > 0 then
		for k, v in ipairs(closest_table) do
			local repel_force = v.server_Part.PrimaryPart.Position - self.server_Part.PrimaryPart.Position
			totalRepel_force += (repel_force.Unit * (1 / repel_force.Magnitude ^ 2))
		end

		totalRepel_force *= 250
		totalRepel_force = totalRepel_force.Unit
	end

	return totalRepel_force
	--self.server_Part.PrimaryPart.VectorForce.Force = Vector3.new()
end

function Steering.Cohesion(self, parent_group : string)
	local closest_table = closest_models(self, parent_group)

	local average_pos = Vector3.new(0, 0, 0)
	if #closest_table > 0 then
		for k, v in ipairs(closest_table)  do
			average_pos += v.server_Part.PrimaryPart.Position
		end

		average_pos /= #closest_table
	end

	local desired = (self.server_Part.PrimaryPart.Position - average_pos).Unit

	return desired
end

function Steering.Align(self, parent_group : string)
	local closest_table = closest_models(self, parent_group)
	local average_look_vector = Vector3.new(0, 0, 0)

	if #closest_table > 0 then
		for k, v in ipairs(closest_table) do
			average_look_vector += v.server_Part.PrimaryPart.CFrame.LookVector
		end
		
		average_look_vector //= #closest_table
		average_look_vector = average_look_vector.Unit
	end
	
	return average_look_vector
	--self.server_Part.PrimaryPart.CFrame = CFrame.new(self.server_Part.PrimaryPart.Position, average_look_vector)
end


function Steering.Arrival(self, target : Vector3)   --implementation of the 'arrival' behavior
	local offset = (self.server_Part.PrimaryPart.Position -  target)

	local distance = offset.Magnitude
	local ramped = self.maxSpeed * (distance // slowing_distance)
	local clippedSpeed = math.min(ramped, self.maxSpeed)
	local desired = (clippedSpeed / distance) * offset
	
	return desired
end

function Steering.Wander(self)
	local x, z = getXAndZPositions(math.random() * -math.pi)
	
	local position = (self.server_Part.PrimaryPart.CFrame * CFrame.new(x, 0, z)).Position
	
	local highlight = Instance.new('Part')
	highlight.Size = Vector3.new(.5, .5, .5)
	highlight.Color = Color3.fromRGB(255, 255, 0)
	highlight.Parent = workspace
	highlight.Position = position
	highlight.CanCollide = false
	highlight.Shape = Enum.PartType.Ball
	highlight.Anchored = true
	
	return position--.Unit / math.random(1, 10)
end

function Steering.Pursuit(self, target : Vector3)
	local desired = (target * 200 - self.server_Part.PrimaryPart.Position).Unit * self.maxSpeed
	return target - desired
end

function Steering.Seek(self, target : Vector3) --implementation of the 'seek' behavior
	local desired = (self.server_Part.PrimaryPart.Position - target).Unit * self.maxSpeed
	return desired
end

--[[function Steering.Move(self, target : Vector3, state)
	Pathfind:GetPath(self, target, state)
end]]

return Steering

1 Like
2 Likes

A little over a month ago I was trying for hours every day to figure this out for my game. After I quit, I see this video. I didn’t want you to go through that :laughing:.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.