Coorelation between part.Orientation?

I am trying to change the orientation of a model (in this case a character).

If the character is facing forward their Orientation will be:
(0,0,0)

The opposite direction will be:
(0,180,0)

The left direciton would be:
(0,90,0)

And the direction facing to the right would be:
(0,-90,0)

What I don’t get is the (seemingly) “random” Y-values.
Straight forward is 0, and backwards is 180. Why isn’t straight-forward, for instance, -180?

Is there any, chart or something where I can see all values? This just seems confusing.

I hope this helps you understand, why this is confusing to me:

Where is the “pattern”?

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)
1 Like

Thanks for the extensive answer! I appreciate that a lot!

So you’re saying that 180 is kind of 180 and -180. (Positive and negative)?

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.
Screen Shot 2021-12-21 at 2.09.05 PM
From top left to right on each row the orientations of each part is this:

Row 1:

  1. 0, 45, 0
  2. 0, 0, 0
  3. 0, -45, 0

Row 2:

  1. 0, 135, 0
  2. 0, 180, 0
  3. 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.

2 Likes

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.

1 Like

Ok, thanks for the answer!

I just had one quick question. I could’ve said this earlier, but;
I am basically trying to find out what way a part is rotating.

So, I would want to know when a part is tweening/rotating from -90 to 180 or when a part is rotating from 90 to 180.

What I was planning to do was like: if 180 (newPosition) is 90 (oldPosition) + 90 then - do something

Like, if a part/player/etc. rotates from the left side to orientation 180., like so:
from:

(0,90,0) → (0,180,0)

I can just do:

newPositon = 180
oldPosition = -90

if newPositon > oldPosition then
--rotates from left to center/back
end

but the issue is, that the same result comes if I do this:
newPosition = 180
oldPosion = 90


if newPosition > oldPosition then
--can rotate from left to center/back OR from right to center/back (aka. no way to find out)
end

I hope you guys get what I mean. Thanks!

Edit:
Do I need to do something with math.abs()? @Scottifly @BuilderBob25620

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?

It’s kind of hard to explain, but I’ll give it another shot.

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.

I’m sorry, I didn’t catch that.

How would I use that property though?

I tried this (in a normal base part):

while true do

print(script.Parent.AssemblyAngularVelocity)

wait(0.1)

end

The output is constantly 0,0,0 when not rotating the part.

And when rotating the part, it firstly prints a bunch of numbers AFTER i stopped rotating it.

I am not sure how to interpret that:

Thanks!

Edit:
I tried this, and rotated the part before the 10 second wait was done, but I just got 0,0,0 twice in the output.

	print(script.Parent.AssemblyAngularVelocity)
wait(10)

print(script.Parent.AssemblyAngularVelocity)

Edit:
I found out that I need to have them in a continous loop.Negative values are roatation to the left and positive are to the right.

However, I am not sure how to interpret these.

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.

1 Like

He wants to know:

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?

1 Like

I understand this sounds strange. But I thank you guys for your patience @BuilderBob25620 @Scottifly

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.

Thanks for reading.

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.

1 Like

I’m sorry for my late reply.

Wow, thank you so much for giving me such an extensive answer. I really appreciate that a lot!

I hope you had a lovely christmas, and a happy new year! Thanks again, best regards.