How do you exclude a relative axis in CFrame.lookat

I am attempting to make something that will push somebody (using bodyVelocity). Currently I just use CFrame.lookat between the center of the part and the humanoidrootpart of the player when touching it and taking the lookvector of it and multiplying it by a constant value to get the velocity to be used in the bodyVelocity. It works just fine until the object doing the pushing is rotated. What I would like to happen is that the pushing part (green part in the image examples) to have its pushing direction rotate around one of its local axes such that no matter the height of the humanoidrootpart, it will always push relative to the rotation of the part and not the orientation of line formed when looking at the player(sorry for my poor explanation.

Below are some examples of what happens WITHOUT the constraining to the local axis orientation while using the lookat, where the green part represents the push part, the red ball represents the players humanoid root part, and the blue arrow represents the direction of the resulting force.
image
image
image
(please note that the green brick’s orientation maintains the same, but the red ball does move)

This is what I would like to happen WITH the constraining to a local axis on. The yellow block is the axis the orientation of the direction is rotating around.
image
image
image
image

What is the easiest way to achieve this?

You could do something like

local up = part.CFrame.UpVector -- or whatever your "spin axis" is
local dir = (ball.Position - part.Position).Unit
local right = dir:Cross(up)

part.CFrame = CFrame.fromMatrix(part.Position, right, up)
2 Likes