I have a cube entity that’s rotated 45 degrees on the x axis. I’m trying to rotate it on the y-axis in world space.
How would I go about this?
localTransform.ValueRW = localTransform.ValueRO.RotateY(3 * deltaTime);
This code simply rotates it in local-space. I know i’m supposed to do something with LocalToWorld but no matter what I do, it just won’t work. I’ve read through the Entities documentation multiple times by now but that really doesn’t do anything for me at all.
My code currently looks like this
//Transform local-rotation to world-space
quaternion worldRotation = math.mul(localToWorld.ValueRO.Rotation, localTransform.ValueRO.Rotation);
//Rotate in world-space
worldRotation = math.mul(worldRotation, quaternion.RotateY(3 * SystemAPI.Time.DeltaTime));
//Transform rotation back to local-space
quaternion newLocalRotation = math.mul(math.inverse(localToWorld.ValueRO.Rotation), worldRotation);
localTransform.ValueRW = localTransform.ValueRO.WithRotation(newLocalRotation);
which apparently does the exact same thing as rotating it in local-space so yeah, I seem to have made lots of extra steps with no progress whatsoever.
Someone help me out.
Think you need to add Space.World in your rotation call, take a look at this
localTransform.ValueRO.Rotate(0, 3 * deltaTime, 0, Space.World);
Hey xindexer2, thanks for responding. This unfortunately isn’t the solution since i’m using DOTS. The Space.World enum seems to only work on regular transforms. I’m using the LocalTransform which only accept a quaternion as parameter for its Rotate() method.
Well I’m running into the same thing as you are now - the Rotate call on the transform does not take a second input… My work around is to parent the entity that is located at 0,0,0 then rotate that. Works great if you need the parent which I do on the majority of my entities but not all.
Quaternions always result in me just trying all combinations until one works 
Maybe :
quaternion.AxisAngle(new float3(0,1,0), someAngleInRad) → multiply this with your 45 degrees turned quaternion for the new Quaternion.
Or change the order of the parameters when you multiply the quaternions.
Or maybe something else
sorry in this case.
Is the localToWorld
in your code from the parent? I think you need to multiply with inverse first.
Also look at these:
Method ComputeWorldTransformMatrix | Entities | 1.0.11 (unity3d.com)
Transforms comparison | Entities | 1.0.11 (unity3d.com) (search for “rotate” to get the DOTS equivalent of @xindexer2 solution)
Just as Wobbers said, you need use LocalToWorld of parent to calculate transformation matrix instead of child.
/// <summary>
/// Rotate entity around axis with angle in world space.
/// </summary>
/// <param name="e"></param>
/// <param name="axis"></param>
/// <param name="angle"></param>
private void Rotate(ref SystemState state, Entity e, float3 axis, float angle)
{
// global rotation axis and angle.
var rotation = quaternion.AxisAngle(axis, angle);
// if entity has parent, transform rotation to local space.
if (SystemAPI.HasComponent<Parent>(e))
{
var parentEntity = SystemAPI.GetComponentRO<Parent>(e).ValueRO.Value;
var parentL2W = SystemAPI.GetComponentRO<LocalToWorld>(parentEntity).ValueRO.Value;
rotation = math.inverse(parentL2W).TransformRotation(rotation);
}
// rotate entity.
var localTransform = SystemAPI.GetComponent<LocalTransform>(e);
rotation = localTransform.TransformRotation(rotation);
SystemAPI.SetComponent(e, localTransform.WithRotation(rotation));
}
So I tried using MattMuko’s solution and the one in the Transform Comparison page but I always get the same thing - If I don’t have a parent on the entity, it rotates around it’s own axis. If I add a parent, then there is no problem and it rotates around world space, but that’s because the parent is at 0,0,0 and any rotation it has will be world space.
In a job, I’m setting the entities position on the Y axis:
localTransforms[i] = new LocalTransform()
{
Position = new float3
{
x = 0,
y = PositionData[entityIndexInQuery].x,
z = 0
},
Scale = 1,
Rotation = quaternion.identity
};
Then in a for loop after the job completes, I’m trying to rotate it in world space (using Matt’s function above):
for (var i = 0; i < tickArray.Length; i++)
{
Rotate(ref state, tickArray[i], new float3(0,0,1), tickAngleData[i]);
}
and this is the result

Oh, It’s my mistake that transforming quaternion incorrectly. Maybe, you can try another more direct solution, transform rotate axis to local space firstly, and then apply rotation in local space.
private void Rotate2(ref SystemState state, Entity e, float3 axis, float angle)
{
// local rotation axis.
var localAxis = axis;
// if entity has parent, transform axis to local space.
if (SystemAPI.HasComponent<Parent>(e))
{
var parentEntity = SystemAPI.GetComponentRO<Parent>(e).ValueRO.Value;
var parentL2W = SystemAPI.GetComponentRO<LocalToWorld>(parentEntity).ValueRO.Value;
localAxis = math.mul(new float3x3(math.inverse(parentL2W)), axis);
}
// rotate entity.
var localTransform = SystemAPI.GetComponent<LocalTransform>(e);
var rotation = quaternion.AxisAngle(localAxis, angle);
rotation = localTransform.TransformRotation(rotation);
SystemAPI.SetComponent(e, localTransform.WithRotation(rotation));
}
I appreciate all the help but maybe it can’t be done without a parent? Rotate2 ends up doing the same thing as Rotate.