Setting Local Rotation

From the CreationKit Wiki
Jump to navigation Jump to search

The SetAngle function rotates an object according to the global axes, not the local axes of an object. This means that if you were to script the movement of a ship, for example, you would be unable to account for pitch and roll (rotation about the x and y axes).

To rotate the object about its local axes, use this function:

Function SetLocalAngle(Float LocalX, Float LocalY, Float LocalZ)
	float AngleX = LocalX * Math.Cos(LocalZ) + LocalY * Math.Sin(LocalZ)
	float AngleY = LocalY * Math.Cos(LocalZ) - LocalX * Math.Sin(LocalZ)
	SetAngle(AngleX, AngleY, LocalZ)
EndFunction

So if you wanted to have the ship roll 15 degrees over to its left side, while experiencing some pitch causing it to tilt up 10 degrees, on a heading of 135 degrees, you would use:

SetLocalAngle(-10, 15, 135)

The function is meant to be put on a scripted object, and will move only that object when called. You can easily make it a global function by changing it to this:

Function SetLocalAngle(ObjectReference MyObject, Float LocalX, Float LocalY, Float LocalZ) Global
	float AngleX = LocalX * Math.Cos(LocalZ) + LocalY * Math.Sin(LocalZ)
	float AngleY = LocalY * Math.Cos(LocalZ) - LocalX * Math.Sin(LocalZ)
	MyObject.SetAngle(AngleX, AngleY, LocalZ)
EndFunction

Obviously, the 'MyObject' parameter is for the object you want to rotate.


Following script makes an object rotate indefinitely:

Scriptname RotatingObject extends ObjectReference  

Float Property RotationSpeed = 20.0 Auto

Event OnInit()
	SetMotionType(4)  ;this is needed if the script is attached to a havoc object
 	OnTranslationAlmostComplete()
EndEvent

Event OnCellLoad()
	OnTranslationAlmostComplete()
EndEvent

Event OnUpdate()
	OnTranslationAlmostComplete()
EndEvent

Event OnTranslationAlmostComplete()
	if Is3DLoaded()
		Float AngleZ = GetAngleZ() + 120
		if AngleZ >= 360
			AngleZ = AngleZ - 360
		endif
		TranslateTo(GetPositionX(), GetPositionY(), GetPositionZ(), GetAngleX(), GetAngleY(), AngleZ, 0.0, RotationSpeed)
	else
		RegisterForSingleUpdate(0.1)
	endif
EndEvent