Make part lerp away from player

My goal is to have interactive bushes by lerping the bush away from the player.

local standardcf = workspace.Bush2.CFrame

game:GetService("RunService").RenderStepped:Connect(function(dt)
	local hrp = player.Character.HumanoidRootPart
	local goal = CFrame.new(standardcf.p, hrp.Velocity)
	bush.CFrame = bush.CFrame:lerp(goal, dt * 6)
end)

Demonstration of it borderline working:
https://gyazo.com/9c6d4f06b41980629ea79e5d6c55d584

Anyone know what I’m doing wrong here? It should be facing completely away from me, evenly distributed no matter the angle.

2 Likes

You’re making the rotation of the bush move depending on the velocity the humanoid root part is going at, also if you don’t want this to happen to bushes that are far away from the player, use magnitude to determine if it can do that code if closer.

Also, i don’t really know how to use CFrame to make it lean away from the player but you’ll figure it out.

I’m aware of that already, just concerned with the formula behind turning a part away from the player.

You want to get the inverse difference of the two with the formula

bush.CFrame = bush.CFrame + hrp.CFrame * -magnitude then lerp that

this is what it should look like Good thing I know basic algebra

Can you elaborate further? I don’t believe you can add CFrames like that and I’m not sure how magnitude would tie into anything.

Let me open my old games code back up maybe i misspelled something

This was the specific code i used ```
cam.CFrame = ((part.CFrame + (part.CFrame.LookVector * -5)) + (part.CFrame.RightVector * 2))

The humanoid root part’s velocity is the direction they’re going in (as a unit vector), multiplied by their walk speed. This vector does not originate from your character – it originates from the world origin (0, 0, 0), so the vector is going to be close to the origin.

CFrame.new(pos, lookat) expects the lookat argument to be a position in world space, not a relative vector, so the solution would be to add their velocity to their current position:

local standardcf = workspace.Bush2.CFrame

game:GetService("RunService").RenderStepped:Connect(function(dt)
	local hrp = player.Character.HumanoidRootPart
	local goal = CFrame.new(standardcf.p, hrp.Position + hrp.Velocity)
	bush.CFrame = bush.CFrame:lerp(goal, dt * 6)
end)

@Diamond_Plus1 You multiply cframes, not add them. Nor can you can multiply a cframe by a scalar

4 Likes

I dont know why it got rid of my other text but cam is player and part is bush

Works as I expected it to, thanks! Do you know how to take this a step further and have it only rotate on a specific axis so that the bush doesn’t rotate all the way around like this?
image

https://gyazo.com/276f7fcbd87fcd3f11125874aaf06368

It shouldn’t really rotate all the way around like that, only tilting the top away from the player, keeping a base point at the bottom of the bush. I don’t know how else to describe it, as it is, a bush wouldn’t normally tilt like that in the real world.

Is this your intended behaviour?
https://gyazo.com/1f04e3fb6cdfad1f8e1216970c970cb3

Looks like it, just shouldn’t flip around if you walk through it. Have you given it an anchor point at the bottom?

You can consider it so – yes. Here’s the code used:

local bush = workspace.Bush
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local hrp = character:WaitForChild("HumanoidRootPart")

local function highestPointAtBase(cf)
	local function dir_vec(v)
		if v.y == 0 then
			return Vector3.new()
		else
			return (v.y < 0) and -v or v
		end
	end
	
	local size = bush.Size/2
	local x = dir_vec(cf.RightVector) * size.X
	local y = -cf.UpVector * size.Y
	local z = dir_vec(cf.LookVector) * size.Z
	return (cf + x + y + z).Position
end

local initial = bush.CFrame

game:GetService("RunService").Heartbeat:Connect(function(dt)
	local target = hrp.Position
	local origin = CFrame.new(initial.Position) * CFrame.new(0, -bush.Size.Y / 2, 0)
	
	local dir = (target - initial.Position).Unit * Vector3.new(1, 0, 1)
	local axis = Vector3.new(0, 1, 0):Cross(dir)
	local angle = math.rad(-15)
	
	if axis.magnitude == 0 then
		axis = Vector3.new(1)
		angle = 0
	end
	
	local cf = CFrame.new(initial.Position) * CFrame.fromAxisAngle(axis, angle)
	local point_at_base = CFrame.new(highestPointAtBase(cf))
	local t = (origin:inverse() * point_at_base).y
	cf = origin  * CFrame.fromAxisAngle(axis, angle) * CFrame.new(0, bush.Size.Y/2 - t, 0)
	bush.CFrame = bush.CFrame:lerp(cf, dt * 6) 
end)
3 Likes