Rotating an object around another object with a script

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search

See this discussion for background.

The example proof-of-concept script rotates the object it's attached to horizontally around the player at a constant speed. Replacing the player reference with any other would let this object rotate around any other reference (for example, creating a bunch of slowly rotating rocks and platforms around a tower; although that's better done via an animation). This will mess up Havok collisions, though - changes to the script to deal with it are highy welcome.

The script uses the ESM Math Library for its trigonometric functions. Read the Stage function repository for a detailed description. Any other function returning cos() and sin() values - including a simple table lookup with optional linear interpolation - will suffice.

ScriptName CirclingAroundThePlayerScript

short constantsset ; did we set the constants?

float rspeed ; in degrees/s
float hdist ; horizontal distance from the player
float rpos ; position on the circle
float mod_x ; positions relative to the player
float mod_y
float mod_z
float org_x ; position of the player
float org_y
float org_z

Begin GameMode

    ; setting up constants
    if constantsset == 0
        set rspeed       to  10 ; constant radial speed
        set mod_z        to 128 ; constant height
        set hdist        to 160 ; constant distance
        set constantsset to   1 ; done setting up the constants
    endif

    ; updating the position on the circle (rpos)
    set rpos to rpos + ( rspeed * getSecondsPassed )
    if rpos > 360
        set rpos to rpos - 360
    endif

    ; setting the mods, via the SinCosTan function
    set math.fin1 to rpos
    setStage math 15                ; SinCosTan(rpos) function call
    set mod_x to math.fout  * hdist ; sin(rpos) * hdist
    set mod_y to math.fout2 * hdist ; cos(rpos) * hdist

    ; getting the player's position
    set org_x to Player.getPos X
    set org_y to Player.getPos Y
    set org_z to Player.getPos Z

    ; setting my own position
    set org_x to org_x + mod_x
    setPos X, org_x
    set org_y to org_y + mod_y
    setPos Y, org_y
    set org_z to org_z + mod_z
    setPos Z, org_z

End


The following is in addition to the above with the effect that the object oscillates in and out, and up and down slowly dependant upon the values set in boolean, and zboolean.

add these variables to the top of the script short boolean short zboolean


and add this following code right after setting the mods, and before setting the players position (thats where I put it at least). The .2 value determines the speed at which the object oscillates on the mod_z and hdist dimensions, a larger value will cause the object to oscillate quickly, a smaller value subsequently means it will oscillate slowly.

   if mod_z > 390 + ( .06 * getRandomPercent )
       set zboolean to 1
   endif
   if mod_z < 290 + ( .06 * getRandomPercent )
       set zboolean to 0
   endif
   if zboolean == 0
       set mod_z to mod_z + .2
   endif   
   if zboolean == 1
       set mod_z to mod_z - .2
   endif
   if hdist > 350 + ( .06 * getRandomPercent )
       set boolean to 1
   endif
   if hdist < 250 - ( .06 * getRandomPercent )
       set boolean to 0
   endif
   if boolean == 0
       set hdist to hdist + .2 
   endif   
   if boolean == 1
       set hdist to hdist - .2
   endif