Setting Local Rotation
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:
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