I recently wrote code that forces your character to look at your mouse. However, the problem is that if you move your mouse in a specific direction, your character will start floating in the air, with the legs not touching the ground.
Although this is easily understandable from the code I wrote, I am not sure how to fix it. I want both feet to remain firmly planted on the ground, with the mouse only affecting how the torso rotates left and right. This is more easily understandable with a simple test - just plop this code in a LocalScript in StarterGui and start moving the mouse around.
The following is a LocalScript inside StarterGui. No errors appear in the Output.
local plr = game.Players.LocalPlayer repeat wait() until plr.Character local chr = plr.Character local mouse = plr:GetMouse() chr:WaitForChild("Humanoid").AutoRotate = false mouse.Move:connect(function() chr:WaitForChild("Torso").CFrame = CFrame.new( chr.Torso.Position, --Position mouse.Hit.p) --Look at end)
First, let's consider a different way of looking at the CFrame.new(from, to)
constructor.
Instead, think about it like a CFrame.new(from, from + direction)
-- that is, at the position from
and looking in the direction of direction
.
Simple solving from to = from + direction
gives us direction = to - from
.
In this case,
direction = mouse.Hit.p - chr.Torso.Position
However, we want to change direction
to only care about X and Z, which is simple enough using *
:
direction = (mouse.Hit.p - chr.Torso.Position) * Vector3.new(1, 0, 1)
Now we just use the above:
chr.Torso.CFrame = CFrame.new( chr.Torso.Position, chr.Torso.Position + direction)
One note: This will keep the player always upright -- they will be unable to tilt because this overwrites the orientation, which may or may not be desirable depending on what you need.
Using "Direction" is easier to think about that "from", "to" for this purpose, but the two ways are equivalent (by the algebra given above direction = to - from
)
Since Hit.p
is a position in the world -- setting the Y component of it to zero and pointing to that point will just look at some arbitrary point along the X, Z plane, which means if you're above it, (probably you are) then you'll be looking slightly down.
That's a result of position not having a meaningful origin (some other arbitrary place), while direction does have a meaningful origin (no motion).
By multiplying the position mouse.Hit.p
by (1, 0, 1) you adjust y
to not be variable, but it also happens to be that the new y
is an arbitrary other location.
When doing the same with direction, you are denoting that it now is horizontal, which is what is intended.