How to make the part look towards its target when lerping

Try removing the function for now and just have the print statement

Interesting…now it prints twice? How can this be

No worries. What’s the issue now?

It is because the module function is wrong, and probably yields

The issue you’re facing is that you’re calling coroutine.wrap(moveModule.Part(v)) inside the loop, which means you’re directly executing the moveModule.Part(v) function rather than wrapping it in a coroutine.

You should wrap the function call inside the coroutine and then call the coroutine to run it, like so:

for i, v in pairs(mobs:GetChildren()) do
    coroutine.wrap(function()
        moveModule.Part(v)
    end)()
end

I think this is the problem you had anyway. Let me know.

That’s why I wrapped it? And what do you mean the function is wrong

Ah, thankyou! But another problem has arised, with the second part, now it slowly moves to facing it again? I don’t understand why one works and the other doesn’t

I see. It’s possible that the CFrame interpolation and look-at rotation are conflicting with each other which might cause that. I’d suggest tyring to modify the moveModule.Part function to handle both the movement and rotation of each part. Instead of relying on a while loop with interpolation within the function, I’d recommend using RunService.Heartbeat

local RunService = game:GetService("RunService")

function moveModule.Part(part, targetPosition)
   local lookAtDir = (targetPosition - part.Position).unit

    while true do
       
        local newPosition = part.Position:Lerp(targetPosition, 0.1)
        part.Position = newPosition

       
        local newCFrame = CFrame.new(newPosition, newPosition + lookAtDir)
        part.CFrame = newCFrame

       
        if (newPosition - targetPosition).magnitude < 0.1 then
            break
        end

        RunService.Heartbeat:Wait()
    end
end

Then, when you call the function in the loop, pass both the part and its target position like this:

for i, v in pairs(mobs:GetChildren()) do
    coroutine.wrap(function()
        local targetPosition = randomPosition.Position  -- Put your actual target position
        moveModule.Part(v, targetPosition)
    end)()
end

Hey, I am not understanding what you are saying, so I will send my entire script and see if you can add upon that, and explain what you are doing.

local RunService = game:GetService("RunService")

local areas = game.Workspace.Areas

local function getRandomPos(part)
	local newPosition = part.CFrame * CFrame.new(
		(math.random() - 0.5) * part.Size.X,
		(math.random() - 0.5) * part.Size.Y,
		(math.random() - 0.5) * part.Size.Z
		)
	return newPosition
end

local move = {}

move.Part = function(moveObject)
	local area = areas:WaitForChild(moveObject.Name)
	
	while true do
		print("Started Loop")
		local randomPosition = getRandomPos(area)
		
		local t = 0
		local max = 10
			
		local current = moveObject.CFrame
		local connection 
		
		connection = RunService.Heartbeat:Connect(function(deltaTime)
			t += deltaTime
			local alpha = math.min(t/max, 1)
			
			local cf = CFrame.lookAt(moveObject.Position, randomPosition.Position)
			local newPos = current:Lerp(randomPosition,alpha)

			moveObject.CFrame = newPos * cf.Rotation
			
			if t >= max then connection:Disconnect() end
		end)
		
		task.wait(max)
		
		local randomInterval = math.random(3,5)
		task.wait(randomInterval)
	end
end


return move

I’ll PM you on the DevForum to prevent us flooding the thread with back and fourth comments and checks.

Alrighty

sdfsdfsdfsdfsdfsdfsdff

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