With rotation negative values just mean that you are rotating the same amount but in the opposite direction on the axis. Because 180 goes all the way around it is equal to -180. You can experiment with a simple part using the rotation dragger and watching the orientation change in the properties panel.
However, in this case I’m guessing you are trying to script this in. In that case, you don’t need to do this. You can just rotate the models cframe by however many degrees you want on the y rotation axis. So something like this:
local function rotateCharacter(character: Model, degrees: number)
character:PivotTo(character:GetPivot() * CFrame.Angles(0, math.rad(degrees), 0))
end
rotateCharacter(character, 180)
No, I’m saying that 180 is equal to -180 when it comes to rotation because the both end up at the exact same place.
Here’s a picture of six parts.
From top left to right on each row the orientations of each part is this:
Row 1:
0, 45, 0
0, 0, 0
0, -45, 0
Row 2:
0, 135, 0
0, 180, 0
0, -135, 0
As you can see, they are only rotated on one axis, but which direction they are rotating in (facing) depends whether their degrees of rotation are positive or negative.
A circle is 360 degrees.
If you rotate 360 degrees you end up back at 0 degrees.
Same with rotating 180 in either direction (+ and -) since 360 divided by 2 is 180 (or -180).
This is why -90 is the same as 270 degrees.
But if you want to rotate something in 90 degree increments you would need to add 90 to the previous value, so if you start at 0 degrees and rotate 90 + 90 + 90 it’s the same as 270 degrees.
Using math.abs() wouldn’t work since if the Part rotates from 0 to 270 then it wouldn’t fit your calculations.
If you are rotating a Player could you just check the HumanoidRootPart’s Y axis BasePart | Roblox Creator Documentation to see if it’s positive or negative?
Ok, so the orange line represents a positive change/growth.
And the green line represents a negative growth/change.
Now, on the left side. It’s easy. You see that, if the value gets bigger you know that the part is rotating downwards. And if it gets smaller, it is rotating upwards.
However, on the right side, it’s not that simple. If the value gets smaller it can either mean that the part is rotating downwards and up to the right/center OR it can mean that it is rotating from upwards towards the center/right.
The same goes for if the value gets bigger. That can BOTH mean that the value is going from left/center (-90) upwards (towards 0) OR downwards (towards 180). Since both 0 and 180 is BIGGER than -90.
I hope you get a little more of what I mean guys. Thanks so much for the help so far guys! @Scottifly@BuilderBob25620
That’s exactly what I was explaining in the above post. Negative or Positive values mess with your idea.
Try using HumanoidRootPart.AngularVelocity and see if it’s - or + to find out which way the Player is rotating.
Try using the Instance | Roblox Creator Documentation. BasePart | Roblox Creator Documentation only works if the part is being rotated using Roblox’s physics engine. However, I fail to see what you need this for. If a part is being tweened then you should already know this since you are the one who set up the tween in the first place.
But you’re right, if he’s called the tween then it should already be known if it’s clockwise or counter-clockwise. @Oficcer_F why exactly do you want to know which way the player is rotating? For an animation, or something server-sided?
We need to know in order to help understand what you are doing.
As @BuilderBob25620 stated, if you have a script that is creating the tween to that position, couldn’t you just put whatever action you wanted done when that is happening into that script?
The reason I am doing this is because I want to do “sanity checks”. If a player rotates a certain way and says to the server: “Hey, I’m rotating clockwise towards the forward-facing part”, I would want to know if the player is ACTUALLY doing it.
And if I ask the client to give me the animation/tween that they are using in a remote (So I can just check what way the animation is going) they can give me the wrong info. That’s why I need to check that on the server.
If there is a better way, please tell me - as I tend to over-complicate things.
While the client does control the physics of their character, that information is still replicated to the server and other clients. This means that you already have all the information you need on the server.
If you want to check whether they are facing a certain way then you can just get their direction relative to a part and then get the dot product of the direction and the LookVector of their HumanoidRootPart. If you don’t know what the dot product is, it’s basically a single number that tells how closely related two vectors are (that’s how we will be using it). Here are two resources that can help you understand further.
Here is a relevant code sample you can use to determine how closely the direction they are facing in matches the direction they are relative to a position.
local function getFacingAccuracy(lookFrame: CFrame, position: Vector3): number
local direction: Vector3 = (position - lookFrame.Position).Unit
return lookFrame.LookVector:Dot(direction)
end
The number returned will range from -1 to 1. If the number returned is positive (number > 0), then that means the part is in front of the player. If it is neutral (number == 0) then that means the part is perpendicular to the players’ LookVector. If the number returned is negative (number < 0), then that means that the part is behind the player. The closer the number is to 1, the more likely it is that they are facing in that direction (think of it like a percentage because that’s what it basically is).
If you want to, you can remove the positional y-axis from the equation. This will make it so that the value returned by the dot product will only say if the part is in front of the player, ignorant of the height of the two relative to one another.
local function getFacingAccuracy(lookFrame: CFrame, position: Vector3): number
position = Vector3.new(position.X, 0, position.Z)
local lookPos: Vector3 = lookFrame.Position - Vector3.new(0, lookFrame.Y, 0)-- I did performance test and surprisingly "cframe.Position - Vector3.new(0, cframe.Y, 0)" is more performant than "Vector3.new(cframe.X, 0, cframe.Z)"
local direction: Vector3 = (position - lookPos).Unit
return lookFrame.LookVector:Dot(direction)
end
I would recommend this approach as the default go-to, as it will more accurately tell whether or not a part is in front of the player. However, the other approach may be more useful if you have specific use cases, such as determining if the part is in the players line of sight (if that is the case though then you should use the camera’s LookVector, not the HumanoidRootPart's) or you have a system to make the players head look at where the camera is pointing (if that is the case you should use the head’s LookVector instead of the HumanoidRootPart).
But wait! There’s more! The position of the part is only the position of the part at its center. If you have a really big part you can still be looking at it even if the part you are looking at isn’t near the center. This makes the dot product ill-suited for solely determining if we are looking at a part. Roblox does not provide any built-in method for retrieving the vertices of a part to see if there are any near the area we are looking at, so the next best thing we can do is spatial queries. This way we can tell if the player still looking at a part, even if it’s very large. It can also determine if there is something in the way. Or you could have it whitelist certain parts. So we might do something like this:
local overParams: OverlapParams = OverlapParams.new()
overParams.FilterType = Enum.RaycastFilterType.Whitelist
local function isFacingPart(character: Model, part: BasePart): boolean
overParams.FilterDescendantsInstances = {part}
local lookFrame: CFrame = character:GetPivot()
local direction: Vector3 = (part.Position - lookFrame.Position)
local distance: number = math.sqrt(direction.X^2 + direction.Z^2)
local frame: CFrame = (lookFrame + Vector3.new(0, direction.Y, 0)) + (lookFrame.LookVector * distance * 0.5)
local size: Vector3 = character:GetExtentsSize() + Vector3.new(0, 0, distance)
return (#workspace:GetPartBoundsInBox(frame, size, overParams) > 0)
end
Note: I made this function so that the spatial queries happened at the same height of the part.
If you need help understanding how I calculated the magnitude (distance) then you can check out this link.
Edit: changed functions to be more readable. I’d previously compacted some statements down to one line which made them less readable, especially when you are still trying to understand what’s happening.