Tutorials/How To Modify Skyboxes

From SC2Mapster Wiki
Jump to: navigation, search

How To Modify Skyboxes

Written by: DrSuperEvil

Screenshot2017-04-02 23 04 00.jpgScreenshot2017-04-03 21 19 20.jpgSkybox.jpg

Summary

  • For space platform maps the use of skyboxes is important for setting the mood/atmosphere of the map since there will be several areas of 0 cliff height terrain where the player can see into "space". Even though Starcraft2 comes with many beautiful skyboxes in the default Terrain Types, they are unable to respond to what is going on in the map and the colour scheme may not coordinate with the vision of the map maker.
  • In this tutorial it will be demonstrated how to make a customizable and interactive skybox that can be texture swapped, tinted and even change opacity in response to in-game events.

Basic

  • This section will cover how to produce a texture swapped skybox

Setting Up The Models

  • Go to the Data Editor (F7 with default keyboard hotkeys), open the Models tab and create 3 models with the Model Type: set to Generic and the Parent: set to Skybox.
  • With the Art: Model fields select the skybox .m3 file of choice. For this tutorial Ulnar_Skybox, AvernusSkybox and AvernusSkyParallax will be used.
    • Recommended for Fixed:
      • Ulnar_Skybox
      • UlnarNebulaSkybox
      • VC_Zeratul1_Sky
    • Recommended for Not Fixed
      • AvernusSkybox
      • AvernusSkyParallax
      • CharSkybox
      • BraxisAlphaSkyParallax
  • Open the currently selected model in the Cutscenes Editor and under the View menu open the Show Panes tab and make sure Timeline (Shift+T) is enabled.
  • Select the model in the lower right panel and right click it with the mouse and click Show Model Data (Shift+D) to open another window.
  • In the Model Data window there is a folder called Materials that will have further sub folders (depending on model). In these sub folders are listed what textures the model uses by default. The Diffuse, Emissive, Normal and Specular textures listed in each file are the ones that can be modified. Count the number of Diffuse, Emissive, Normal and Specular textures the model has over all the sub folders.
  • Back at the Models tab, for the model being viewed in the cutscene editor, go to the Texture: Texture Declarations - Adaptions - Applies To File field and add values changing the upper index counter until there are as many values as the number of textures for the model. Set all values to Enabled.
  • Go to the Texture: Texture Declarations - Adaptions - Slot field and start assigning the slots each texture will use. Label the texture type you want to associate with that slot by putting a period between the slot and texture type in small letters (eg. main.diffuse). If the same texture is used for the same texture type in two different sub folders or a sub folder has two textures of the same texture type use different slots for each. In general use a different slot for each sub folder. Decal type textures only accept the decal slot.
    • A list of accepted slots can be found in the data editor View menu under the Show Data Hints Viewer (Ctrl+Alt+H) option. This will bring up the Data Hints Viewer window which will list the slots under Enums>TextureSlot (ETextureSlot)
  • Open the Texture: Texture Declarations - Adaptions - Trigger On SubString field and enter the full name of each Diffuse, Emissive, Normal and Specular texture after the equals sign omitting the .dds at the end. The names are case sensitive eg. with Flare2B_Orange means Flare2b_Orange would not work.
  • Copy and paste the texture name strings into the Texture: Texture Declarations - Adaptions - Prefix field in the same order
  • Repeat for the other two models and they will all be ready to be texture swapped.
    • For demo purposes here is the XML:
No.1
    <CModel id="1testskyboxfixed" parent="Skybox">
        <Model value="Assets\Skyboxes\Ulnar_Skybox\Ulnar_Skybox.m3"/>
        <TextureDeclares Prefix="Ulnar_Skybox_Emissive2_Master">
            <Adaptions TriggerOnSubstring="Ulnar_Skybox_Emissive2_Master" Slot="generic01.diffuse"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Ulnar_Skybox_Emissive2_Master">
            <Adaptions TriggerOnSubstring="Ulnar_Skybox_Emissive2_Master" Slot="generic01.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Void_Skybox2_Diffuse">
            <Adaptions TriggerOnSubstring="Void_Skybox2_Diffuse" Slot="generic02.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Storm_Liquid01_Black">
            <Adaptions TriggerOnSubstring="Storm_Liquid01_Black" Slot="generic03.specular"/>
        </TextureDeclares>
        <TextureDeclares Prefix="EnergyRingTileBlueBlur">
            <Adaptions TriggerOnSubstring="EnergyRingTileBlueBlur" Slot="generic03.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Ulnar_Skybox_Emissive2_Master">
            <Adaptions TriggerOnSubstring="Ulnar_Skybox_Emissive2_Master" Slot="generic04.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Void_SkyboxStar_Emissive">
            <Adaptions TriggerOnSubstring="Void_SkyboxStar_Emissive" Slot="generic05.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="EnergyRingTileBlueBlur">
            <Adaptions TriggerOnSubstring="EnergyRingTileBlueBlur" Slot="main.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Ulnar_Skybox_NebulaCloud_Emissive">
            <Adaptions TriggerOnSubstring="Ulnar_Skybox_NebulaCloud_Emissive" Slot="hair.emissive"/>
        </TextureDeclares>
    </CModel>
No.2
    <CModel id="1testskyboxnotfixed1" parent="Skybox">
        <Model value="Assets\Skyboxes\AvernusSkybox\AvernusSkybox.m3"/>
        <TextureDeclares Prefix="PlanetViewMonlyth_BG">
            <Adaptions TriggerOnSubstring="PlanetViewMonlyth_BG" Slot="generic01.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Glow_Blue1">
            <Adaptions TriggerOnSubstring="Glow_Blue1" Slot="generic02.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="tj_BlueStars">
            <Adaptions TriggerOnSubstring="tj_BlueStars" Slot="generic03.diffuse"/>
        </TextureDeclares>
        <TextureDeclares Prefix="tj_BlueStars">
            <Adaptions TriggerOnSubstring="tj_BlueStars" Slot="generic03.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Glow_Blue3">
            <Adaptions TriggerOnSubstring="Glow_Blue3" Slot="generic04.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="PlanetViewMonlyth_Diffuse">
            <Adaptions TriggerOnSubstring="PlanetViewMonlyth_Diffuse" Slot="main.diffuse"/>
        </TextureDeclares>
        <TextureDeclares Prefix="PlanetView_MarsaraDetailC2">
            <Adaptions TriggerOnSubstring="PlanetView_MarsaraDetailC2" Slot="decal"/>
        </TextureDeclares>
        <TextureDeclares Prefix="PlanetView_MarsaraDetailC2">
            <Adaptions TriggerOnSubstring="PlanetView_MarsaraDetailC2" Slot="main.specular"/>
        </TextureDeclares>
        <TextureDeclares Prefix="planetviewmeinhoff_emissive2">
            <Adaptions TriggerOnSubstring="planetviewmeinhoff_emissive2" Slot="main.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="PlanetViewMonlyth_Normal">
            <Adaptions TriggerOnSubstring="PlanetViewMonlyth_Normal" Slot="main.normal"/>
        </TextureDeclares>
        <TextureDeclares Prefix="PlanetView_MarsaraDiffuse2">
            <Adaptions TriggerOnSubstring="PlanetView_MarsaraDiffuse2" Slot="generic05.diffuse"/>
        </TextureDeclares>
        <TextureDeclares Prefix="planetviewmeinhoff_emissive2">
            <Adaptions TriggerOnSubstring="planetviewmeinhoff_emissive2" Slot="generic05.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="PlanetView_MarsaraNormal2">
            <Adaptions TriggerOnSubstring="PlanetView_MarsaraNormal2" Slot="generic05.normal"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Avernus_SkyboxPlanetShadow">
            <Adaptions TriggerOnSubstring="Avernus_SkyboxPlanetShadow" Slot="hair.diffuse"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Flare2B_Orange">
            <Adaptions TriggerOnSubstring="Flare2B_Orange" Slot="hair.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Glow_Haze1">
            <Adaptions TriggerOnSubstring="Glow_Haze1" Slot="body.emissive"/>
        </TextureDeclares>
        <TextureDeclares Prefix="planetviewmeinhoff_emissive2">
            <Adaptions TriggerOnSubstring="planetviewmeinhoff_emissive2" Slot="head.emissive"/>
        </TextureDeclares>
        <Flags index="FOW" value="0"/>
    </CModel>
No.3
    <CModel id="1testskyboxnotfixed2" parent="Skybox">
        <Model value="Assets\Skyboxes\AvernusSkyParallax\AvernusSkyParallax.m3"/>
        <TextureDeclares Prefix="Avernus_SkyboxMeteorDiffuse">
            <Adaptions TriggerOnSubstring="Avernus_SkyboxMeteorDiffuse" Slot="main.diffuse"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Avernus_SkyboxMeteorDiffuse">
            <Adaptions TriggerOnSubstring="Avernus_SkyboxMeteorDiffuse" Slot="main.specular"/>
        </TextureDeclares>
        <TextureDeclares Prefix="Avernus_SkyboxMeteorNormal">
            <Adaptions TriggerOnSubstring="Avernus_SkyboxMeteorNormal" Slot="main.normal"/>
        </TextureDeclares>
        <Flags index="FOW" value="0"/>
    </CModel>

The Textures

  • Open the Textures tab and create 13 textures (7 for the planet and 3 each for the others). The File field is the texture you are going to use as a replacement while the Slot field is the texture slot you want to replace. Again put a period between the slot and texture type in small letters (eg. main.diffuse).
  • Note in this tutorial not every texture is being changed but enough to look good
    • For demo purposes here is the XML (annotated in the editor comments to match the model slot setup from the previous section):
No.1 (clouds)
    <CTexture id="1testskybox1texture1">
        <File value="Assets\Textures\firetile1_blue.dds"/>
        <Slot value="main.diffuse"/>
    </CTexture>
No.2 (horizon, highlights the contours of the normal)
    <CTexture id="1testskybox1texture2">
        <File value="Assets\Textures\vc_zeratul1a_clouds.dds"/>
        <Slot value="main.emissive"/>
    </CTexture>
No.3 (minor planet surface texture)
    <CTexture id="1testskybox1texture3">
        <File value="Assets\Textures\envirotest2.dds"/>
        <Slot value="generic05.diffuse"/>
    </CTexture>
No.4 (normal for planet surface)
    <CTexture id="1testskybox1texture4">
        <File value="Assets\Textures\planetviewkaldrgasgiant_diff.dds"/>
        <Slot value="generic05.normal"/>
    </CTexture>
No. 5 (main planet surface texture)
    <CTexture id="1testskybox1texture5">
        <File value="Assets\Textures\space01_nebula_diff.dds"/>
        <Slot value="decal"/>
    </CTexture>
No.6 (minor planet surface texture)
    <CTexture id="1testskybox1texture6">
        <File value="Assets\Textures\bloodopaquefade_green.dds"/>
        <Slot value="generic05.emissive"/>
    </CTexture>
No.7 (aura around planet)
    <CTexture id="1testskybox1texture7">
        <File value="Assets\Textures\storm_rainbowsphericalreflection.dds"/>
        <Slot value="generic01.emissive"/>
    </CTexture>
No.8 (asteroid diffuse, main texture)
    <CTexture id="1testskyboxasteroidtexture1">
        <File value="Assets\Textures\zhakuldas_mercury_cracks.dds"/>
        <Slot value="main.diffuse"/>
    </CTexture>
No.9 (asteroid specular, reflection profile)
    <CTexture id="1testskyboxasteroidtexture2">
        <File value="Assets\Textures\zhakuldas_mercury_cracks_low.dds"/>
        <Slot value="main.specular"/>
    </CTexture>
No.10 (asteroid normal, fine height detail)
    <CTexture id="1testskyboxasteroidtexture3">
        <File value="Assets\Textures\zhakuldas_mercury_cracksnormal.dds"/>
        <Slot value="main.normal"/>
    </CTexture>
No.11 (fixed skybox main clockwise texture)
    <CTexture id="1testskybox3texture1">
        <File value="Assets\Textures\stars_nebulas_void.dds"/>
        <Slot value="generic02.emissive"/>
    </CTexture>
No.12 (fixed skybox stationary background texture, also affects the three stars colour)
    <CTexture id="1testskybox3texture2">
        <File value="Assets\Textures\void_skybox_nebulacloud_red02.dds"/>
        <Slot value="generic03.emissive"/>
    </CTexture>
No.13 (fixed skybox lightning flash texture)
    <CTexture id="1testskybox3texture3">
        <File value="Assets\Textures\energyringtilegreen.dds"/>
        <Slot value="hair.emissive"/>
    </CTexture>

The SOp (Local Offset) Type Actor

  • Open the Actors tab and create a Site Operation (Local Offset) type actor. This SOp actor type allows the position of attached actors to be moved relative to their host. In this instance it will be used to move the AvernusSkyParallax model into the correct position.
  • The only field of interest with this actor is the Actor: Local Offset field.
    • X moves the model left/right with left being positive
    • Y moves the model forward/backwards with forward being negative
    • Z moves the model up/down with up being positive
  • Set X = 104, Y = 104 and Z = 3
    • For demo purposes here is the XML
    <CActorSiteOpLocalOffset id="1testskyboxoffset1">
        <EditorCategories value=""/>
        <LocalOffset value="104.000000,104.000000,3.000000"/>
    </CActorSiteOpLocalOffset>

The SOp (Explicit Rotation) Type Actor

  • Create a Site Operation (Explicit Rotation) type actor. This SOp actor type allows the rotation of attached actors to be moved relative to their host. In this instance it will be used to rotate the Ulnar_Skybox model so that the three star geometries do not overlap with the planet of the not fixed skybox actor.
  • The Actor: Forward field determines where the forward vector of the model will point relative to the starting orientation. The Actor: Is Local field determines if rotation is relative to the host model or the global map grid, in general always enable this. Finally the Actor: Up field determines where the up vector of the model will point relative to the starting orientation. The magnitude of the forward and up vectors are automatically normalised that the resulting directional vector has a magnitude of 1 so 1,2,0 will have the same orientation as 0.5,1,0. The forward vector will be faced in priority to the up vector which should ideally be at a right angle. It is often easier calculation wise to use multiple SOp (Explicit Rotation) actors with 2D rotations along any plane.
    • For general forward angle calculations:
      • X = sin(θ)
      • Y = -(cos(θ))
      • Z = sin(θ)
    • For general up angle calculations:
      • X = sin(θ)
      • Y = sin(θ)
      • Z = cos(θ)
  • For this demonstration we will use a forward of 0.6,-1,1 and an up of 0,0.1,1
    • For demo purposes here is the XML
    <CActorSiteOpRotationExplicit id="1testskyboxrotation">
        <EditorCategories value=""/>
        <Forward value="0.600000,-1.000000,1.000000"/>
        <Up value="0.000000,0.100000,1.000000"/>
        <IsLocal value="1"/>
    </CActorSiteOpRotationExplicit>

The Doodad Type Actor #1

  • Create a Doodad type actor. This will be the base for the not fixed skybox (the skybox that does not move with the camera and is viewed from different angles depending on the side of the map it is viewed from). Remove the Pause Animations While Fogged flag under Actor: Doodad Flags, set the Actor: Fog Visibility to Dimmed so the skybox does not freeze if it somehow is not in the vision radius of a friendly unit and the Art: Random Scale Range field to 1 for both the max and min values.
  • Select your model that uses the AvernusSkybox model under the Art: Model field
  • Under the actor Event: Events+ fields open the window to edit the events. Right click the upper of the two yellow flags (events) and click on Remove Selection to delete the first default event. The remaining event should already be set to Actor Creation which triggers when the actor is created and the clapper board (action) should already have the Msg Type: menu at Animation Play with the Play Forever and Random Start Offset flags already enabled. The default should have Stand under the Name field and Stand under the Animation Properties field. Some skyboxes have several animations which are usually variations of the Global Loop Stand animation for the model. You can view what animations a model has by right clicking the blue bar on the Timeline in the Cutscenes Editor and selecting Change Animation. To change to these other animations alter the Animation Properties field of the Animation Play action to match eg. GLstand 02 would be Stand (Global Loop), Variation 02.
  • Right click the events window and select Add Event, change the Msg Type: of the event to Actor Creation and the action to Timer Set. Under the Timer Set action change the Duration Base: field to 0.01 seconds and add a unique string of your choice to the Name field eg. birth.
  • Add another event except use a Timer Expired event under the message type and a Texture Select By Id action. Right click this event and select Add Term to add a small grey arrow (term) between the event and the action. Set the Term Type: field to Timer Name and insert the same string as used for the name of the timer set in the previous event under the Name field. Change the Selection: field of the Texture Select By Id action to use the first of the planet associated textures created under the Textures data type. This action type will use the selected texture on the actor to replace the texture in the slot on the model. Repeat until it is set up for all 7 textures. If the last character of the textures is numeric (and the ID has been updated from the default if copied) it is faster to go into XML View (Ctrl+3) and copy and paste the event several times before just changing the differentiating character before changing back to Table View (Ctrl+1).
    • The timer system is used for texture swapping so that the texture changes will show in the Terrain Editor when the map is next loaded.
    • With timers always use a Timer Name term to prevent the events being triggered by any timer. This is especially important if Timer Expired events are linked to Timer Set actions to avoid lag.
  • Finally make another event that uses the Actor Creation event type and set the action to Create but leave it blank for now.
  • Do not give this actor any SOps else it will not appear
    • For demo purposes here is the XML
    <CActorDoodad id="1testnotfixedskybox1">
        <EditorCategories value="DoodadType:Environment"/>
        <On index="0" Terms="ActorCreation" Send="$Stand PlayForever,RandomStartOffset"/>
        <On index="1" Terms="ActorCreation" Send="Create 1testnotfixedskybox2"/>
        <On Terms="ActorCreation" Send="TimerSet 0.010000 birth"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskybox1texture1"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskybox1texture2"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskybox1texture3"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskybox1texture4"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskybox1texture5"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskybox1texture6"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskybox1texture7"/>
        <EditorFlags index="NoAutoRotate" value="1"/>
        <RandomScaleRange value="1.000000,1.000000"/>
        <DoodadFlags index="PauseAnimsWhileFogged" value="0"/>
        <Model value="1testskyboxnotfixed1"/>
    </CActorDoodad>

The Model Type Actor #1

  • Create a Model type actor. This will be the second not fixed skybox using the AvernusSkyParallax model under the Art: Model field.
  • Under the Art: Model Flags field enable Automate Global Loop and set the Hosting: Host - Subject field to the Doodad type actor made in the previous section. Disable all flags in the Properties: Inherited Properties field.
  • The Hosting: Host Site Operations - Operations field should be set to use the default SOpAttachOrigin to attach to the origin of the other not fixed skybox actor and the SOp (Local Offset) type actor created earlier to position this actor correctly. Due to a bug in the editor, the Combine Structure Values (Ctrl+Shift+N) option must be enabled to manipulate SOps.
  • Set the Events of this actor in the same way as the Doodad type actor except only having 3 events for texture swapping and no events for actor creation.
  • Finally go back to the Doodad type actor and change the Create event action to reference this actor under the Name field so that this actor is created when the doodad is.
    • For demo purposes here is the XML
    <CActorModel id="1testnotfixedskybox2">
        <On Terms="ActorCreation" Send="$Stand PlayForever"/>
        <On Terms="ActorCreation" Send="TimerSet 0.010000 birth"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskyboxasteroidtexture1"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskyboxasteroidtexture2"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskyboxasteroidtexture3"/>
        <Host Subject="1testnotfixedskybox1"/>
        <HostSiteOps Ops="SOpAttachOrigin 1testskyboxoffset1"/>
        <Model value="1testskyboxnotfixed2"/>
        <ModelFlags index="AutomateGlobalLoops" value="1"/>
    </CActorModel>

The Model Type Actor #2

  • Create another Model type actor. This will be the first fixed skybox actor (the one that follows the camera). Due to a bug SOps other than SOpGameCameraFollow (Unnamed)cannot be used on this actor without them applying every frame generating lag and glitched visuals. To avoid this the Invisible model will be used in the Art: Model field and the visuals will be hosted on it as attachments. If no SOps are required then the final visuals for the fixed skybox can be used here. Doing so makes the skybox model hide parts not revealed in the fog of war.
  • Under the Art: Model Flags field enable Automate Global Loop and disable all flags in the Properties: Inherited Properties field.
  • The Hosting: Host Site Operations - Operations field should be set to use the default SOpGameCameraFollow (Unnamed) only. Due to a bug in the editor, the Combine Structure Values (Ctrl+Shift+N) option must be enabled to manipulate SOps.
  • Set the Events of this actor in the same way as the previous Model type actor except the Create action on Actor Creation is kept.
    • For demo purposes here is the XML
    <CActorModel id="1testfixedskybox1">
        <On Terms="ActorCreation" Send="Create 1testfixedskybox2"/>
        <HostSiteOps Ops="SOpGameCameraFollow"/>
        <Model value="Invisible"/>
        <ModelFlags index="AutomateGlobalLoops" value="1"/>
    </CActorModel>

The Model Type Actor #3

  • Create a final Model type actor. This will be the second fixed skybox actor using the Ulnar_Skybox model under the Art: Model field. When used as an attachment for the first fixed skybox actor it will be known as constantly visible causing a backlighting of the terrain silhouette which may or may not be desirable.
  • Under the Art: Model Flags field enable Automate Global Loop and disable all flags in the Properties: Inherited Properties field.
  • Set the Hosting: Host - Subject field to the Model type actor made in the previous section. Disable all flags in the Properties: Inherited Properties field.
  • The Hosting: Host Site Operations - Operations field should be set to use the default SOpAttachOrigin to attach to the origin of the other fixed skybox actor and the SOp (Explicit Rotation) type actor created earlier to rotate this actor correctly. Due to a bug in the editor, the Combine Structure Values (Ctrl+Shift+N) option must be enabled to manipulate SOps.
  • Set the events like Model Type Actor #1
  • Finally go back to the previous Model type actor and change the Create event action to reference this actor under the Name field so that this actor is created when the fixed skybox is.
    • For demo purposes here is the XML
    <CActorModel id="1testfixedskybox2">
        <AcceptedHostedPropTransfers index="Visibility" value="0"/>
        <On Terms="ActorCreation" Send="$Stand PlayForever"/>
        <On Terms="ActorCreation" Send="TimerSet 0.010000 birth"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskybox3texture1"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskybox3texture2"/>
        <On Terms="TimerExpired; TimerName birth" Send="TextureSelectById 1testskybox3texture3"/>
        <Host Subject="3testfixedskybox1"/>
        <HostSiteOps Ops="SOpAttachOrigin 1testskyboxrotation"/>
        <Model value="1testskyboxfixed"/>
        <ModelFlags index="AutomateGlobalLoops" value="1"/>
    </CActorModel>

The Terrain Type

  • Open the Terrain Types tab and create a new terrain type or copy your favourite. Terrain Types control what Lights and ambience Sounds are used by the map as well as the Terrain Cliffs and Terrain Textures (which also determine what Foliage models appear) available to use in the Terrain Editor. They also configure the fog and creep visual properties but most importantly, the skyboxes.
  • Make sure the Background Model (Fixed) and Background Model (Not Fixed) fields are empty. These fields are the ones normally used for skybox creation and will override any custom skybox actors used if they have a model from the Models data type set in them.
  • Set the Fog Enabled field to disabled to prevent the skybox actors being saturated in fog if they are at a great depth (which skyboxes usually are)
  • Like all space ship/platform terrains the Hide Lowest Level field should be enabled so the cliff level 0 is not opaque.
  • Place the Doodad actor made earlier in the Non Fixed Skybox Actor field. This field will not accept Model type actors for some reason.
  • Place the Model Actor #2 made earlier in the Fixed Skybox Actor field. This field only accepts Model type actors for some reason.
  • Note that the fixed skybox actor will only show in-game and not in the Terrain Editor unless the Show Fog Effects option is disabled under the Render menu.
    • For demo purposes here is the XML
    <CTerrain id="1testcustomterrain">
        <EditorCategories value="Climate:InteriorInstallation"/>
        <Lighting value="PrisonShip"/>
        <LoadingScreen value="Assets\Textures\loading_temp.dds"/>
        <Camera value="SpacePlatform"/>
        <Ambience value="Ambience_Starship"/>
        <ReverbAmbient value="BetaVerb"/>
        <HideLowestLevel value="1"/>
        <MinimapBackgroundColor value="255,0,0,32"/>
        <BlendTextures value="PrisonShip1"/>
        <BlendTextures value="PrisonShip2"/>
        <BlendTextures value="PrisonShip3"/>
        <BlendTextures value="PrisonShip4"/>
        <BlendTextures value="PrisonShip5"/>
        <BlendTextures value="PrisonShip6"/>
        <BlendTextures value="PrisonShip7"/>
        <BlendTextures value="PrisonShip8"/>
        <HardTiles value="KorhalTile"/>
        <CliffSets value="PrisonShipCliff0"/>
        <CliffSets value="LabCliff1"/>
        <FixedSkyboxActor value="1testfixedskybox1"/>
        <NonFixedSkyboxActor value="1testnotfixedskybox1"/>
        <FogColor value="255,121,214,244"/>
        <FogDensity value="0.100000"/>
        <FogFalloff value="0.200000"/>
        <FogStartingHeight value="-6.000000"/>
        <CreepEdgeNormalMap value="Assets\Textures\CreepEdgeNormal.dds"/>
        <CreepSettingsArray index="Low" CreepOpaqueAlphaThreshold="0.180000" CreepTranslucentMinThreshold="0.050000" CreepTranslucentPassTint="1.000000,0.850000,0.750000"/>
        <CreepSettingsArray index="Medium">
            <CreepOpaqueAlphaThreshold value="0.180000"/>
            <CreepTranslucentMinThreshold value="0.050000"/>
            <CreepTranslucentMaxThreshold value="0.150000"/>
            <CreepTranslucentPassTint value="1.000000,0.850000,0.750000"/>
        </CreepSettingsArray>
        <CreepSettingsArray index="High">
            <CreepOpaqueAlphaThreshold value="0.180000"/>
            <CreepTranslucentMinThreshold value="0.050000"/>
            <CreepTranslucentMaxThreshold value="0.150000"/>
            <CreepTranslucentPassTint value="1.000000,0.850000,0.750000"/>
        </CreepSettingsArray>
        <CreepSettingsArray index="Ultra">
            <CreepOpaqueAlphaThreshold value="0.180000"/>
            <CreepTranslucentMinThreshold value="0.050000"/>
            <CreepTranslucentMaxThreshold value="0.150000"/>
            <CreepTranslucentPassTint value="1.000000,0.850000,0.750000"/>
        </CreepSettingsArray>
        <CreepSettingsArray index="Extreme">
            <CreepOpaqueAlphaThreshold value="0.180000"/>
            <CreepTranslucentMinThreshold value="0.050000"/>
            <CreepTranslucentMaxThreshold value="0.150000"/>
            <CreepTranslucentPassTint value="1.000000,0.850000,0.750000"/>
        </CreepSettingsArray>
    </CTerrain>
</Catalog>

Final Steps

  • In the Terrain Editor open the Map menu and select Map Texture Sets to open the Texture Sets page of the Map Properties window.
  • In the Available Texture Sets: box select the Terrain Type made in the previous section and click the Add button.
  • Now click on the Primary Texture Set: and select the Terrain Type that has been added and click the Modify button.
  • To remove the original Terrain Type close the Map Properties window and reopen it.
  • With the demo setup the fixed skybox will be between the aura of the planet and the planet model of the non fixed skybox acting as a kaleidoscope like colour filter for the texture used for the planet aura while there will also be an asteroid field in front of the planet.

Advanced

  • This section will cover how to make your skyboxes respond to in-game events and even swap to different skyboxes mid game.

The SOp (Local Offset) Type Actor #2

  • This offset SOp will be used to position the second planet. The values -150,300,0 are sufficient.
    • For demo purposes here is the XML
    <CActorSiteOpLocalOffset id="1testskyboxoffset2">
        <EditorCategories value=""/>
        <LocalOffset value="-150.000000,300.000000,0.000000"/>
    </CActorSiteOpLocalOffset>

The SOp (Local Offset) Type Actor #3

  • This offset SOp will be used to position the transition haze curtain so that it is just below the terrain. The values 0,40,-40 are sufficient.
    • For demo purposes here is the XML
   <CActorSiteOpLocalOffset id="1testskyboxoffset3">
       <EditorCategories value=""/>
       <LocalOffset value="0.000000,40.000000,-40.000000"/>
   </CActorSiteOpLocalOffset>

The SOp (Explicit Rotation) Type Actor #2

  • This rotation SOp will be used to offset the rotation of the transition haze curtain Model actors to enable a denser curtain.
  • A 72 degree anticlockwise rotation will be used along the xy plane (x = sin(72) and y = -(cos(72)) which equals x = 0.951 and y = -0.309) for the forward vector while the up vector is to remain vertically up at z = 1
    • For demo purposes here is the XML
    <CActorSiteOpRotationExplicit id="1testskyboxrotation2">
        <EditorCategories value=""/>
        <Forward value="0.951000,-0.309000,0.000000"/>
        <Up value="0.000000,0.000000,1.000000"/>
        <IsLocal value="1"/>
    </CActorSiteOpRotationExplicit>

The Model Type Actor #4

  • This Model type actor will be the replacement planet for the skybox. Use the default Char Sky Box model in the Art: Model field although a custom model that is set up to be texture swapped is also an option.
  • Under the Art: Model Flags field enable Automate Global Loop and set the Hosting: Host - Subject field to the Doodad type actor made in the basic tutorial section. Disable all flags in the Properties: Inherited Properties field.
  • The Hosting: Host Site Operations - Operations field should be set to use the default SOpAttachOrigin to attach to the origin of the other not fixed skybox actor and the SOp (Local Offset) Type Actor #2 created earlier to position this actor correctly. Due to a bug in the editor, the Combine Structure Values (Ctrl+Shift+N) option must be enabled to manipulate SOps.
  • Event wise after the standard Animation Play action on Actor Creation, have an Actor Creation event that uses a Set Opacity action with the Opacity field set to 0 so this actor is hidden from view by default. Have a Signal event that uses a Timer Set action and a Timer Expired event with Timer Name term that uses a Set Opacity action. For demo purposes use appear1 as the signal Sub Name, set the timer to 2 seconds and set the opacity to 1 over a 0.5 second Blend In Duration.
    • For demo purposes here is the XML
    <CActorModel id="1testnotfixedskybox3">
        <On Terms="ActorCreation" Send="$Stand PlayForever"/>
        <On Terms="ActorCreation" Send="SetOpacity"/>
        <On Terms="Signal.*.appear1" Send="TimerSet 2.500000 birth"/>
        <On Terms="TimerExpired; TimerName birth" Send="SetOpacity 1.000000 0.500000"/>
        <Host Subject="1testnotfixedskybox1"/>
        <HostSiteOps Ops="SOpAttachOrigin 1testskyboxoffset2"/>
        <Model value="CharSkyBox"/>
        <ModelFlags index="AutomateGlobalLoops" value="1"/>
    </CActorModel>

The Model Type Actors #5-9

  • These Model type actors will be used as a smoke screen to hide/blur the changing of the skybox so it is not so sudden. A model using the UlnarNebulaSkybox will be used in the Art: Model field although the VC_Zeratul1_Sky model is also good. The model can be set up to be texture swapped but that is optional.
  • Set the actor up just like The Model Type Actor #3 except under the Hosting: Host Site Operations - Operations field have SOpAttachOrigin and the SOp (Local Offset) Type Actor #3.
  • Set the z scale of the Art: Scale field to 0.025 to compress all the moving bits of the model into a more compact form.
  • Event wise after the standard Animation Play action on Actor Creation, have an Actor Creation event that uses a Set Opacity action with the Opacity field set to 0 so this actor is hidden from view by default. Using four Actor Creation events using Create actions, create the Model Type Actors #6-9 (differences detailed later in this section). An Actor Creation event can also be used to create a Sound type actor to produce a sound for the transition. Set up a timer system with an Actor Creation event and Timer Set action (in this demo it is called birth) which when it is detected by a Timer Expired event creates a second timer (in this demo it is called duration) and finally when that timer expires a final timer is created (in this demo it is called death).
  • Set the first timer to 0.01, the second to 4.6 and the last one to 0.4 seconds. When the Timer Expired event for the first timer triggers use a Set Opacity action to fade in the actor (Opacity value of 1) over a 0.4 second Blend In Duration period, when the second timer expires use another Set Opacity action to blend out the actor (Opacity value of 0) over a 0.4 second Blend In Duration period and when the final timer expires use a Destroy action. This means when the actor is created it will appear and hang around for 4.2 seconds before disappearing.
    • Do not forget the Timer Name terms!
  • With Model Type Actors #6-9 set the Hosting: Host - Subject field to Model Type Actors #5 and the Hosting: Host Site Operations - Operations field to SOpAttachOrigin and copies of the SOp (Explicit Rotation) Type Actor #2 with #6 having 1, #7 having 2, #8 having 3 and #9 having 4 copies. This means the Model Type Actors #5-9 will have the nebula winds moving in from 5 different directions to optimise the distraction while the skyboxes change.
  • With the events of Model Type Actors #6-9 set the birth timer of #6 to 0.4, #7 to 0.8, #8 to 1.2 and #9 to 1.6. This will stagger the fade in to make the loss of skybox visibility more smooth and generate an approximately 3 second window of minimal skybox visibility to allow for a change of scenery.
    • For demo purposes here is the XML
No.1
    <CActorModel id="1testfixedskybox3">
        <AcceptedHostedPropTransfers index="Visibility" value="0"/>
        <On Terms="ActorCreation" Send="$Stand PlayForever"/>
        <On Terms="ActorCreation" Send="TimerSet 0.010000 birth"/>
        <On Terms="ActorCreation" Send="Create 1testfixedskybox4"/>
        <On Terms="ActorCreation" Send="Create 1testfixedskybox5"/>
        <On Terms="ActorCreation" Send="Create 1testfixedskybox6"/>
        <On Terms="ActorCreation" Send="Create 1testfixedskybox7"/>
        <On Terms="ActorCreation" Send="SetOpacity"/>
        <On Terms="TimerExpired; TimerName birth" Send="SetOpacity 1.000000 0.400000"/>
        <On Terms="TimerExpired; TimerName birth" Send="TimerSet 4.600000 duration"/>
        <On Terms="TimerExpired; TimerName duration" Send="TimerSet 0.400000 death"/>
        <On Terms="TimerExpired; TimerName duration" Send="SetOpacity 0.000000 0.400000"/>
        <On Terms="TimerExpired; TimerName death" Send="Destroy"/>
        <Host Subject="1testfixedskybox1"/>
        <HostSiteOps Ops="SOpAttachOrigin 1testskyboxoffset3"/>
        <Model value="1testskyboxtransitionfog"/>
        <Scale value="1.000000,1.000000,0.025000"/>
        <ModelFlags index="AutomateGlobalLoops" value="1"/>
    </CActorModel>
No.2
    <CActorModel id="1testfixedskybox4">
        <AcceptedHostedPropTransfers index="Visibility" value="0"/>
        <On Terms="ActorCreation" Send="$Stand PlayForever"/>
        <On Terms="ActorCreation" Send="TimerSet 0.400000 birth"/>
        <On Terms="ActorCreation" Send="SetOpacity"/>
        <On Terms="TimerExpired; TimerName birth" Send="SetOpacity 1.000000 0.400000"/>
        <On Terms="TimerExpired; TimerName birth" Send="TimerSet 4.600000 duration"/>
        <On Terms="TimerExpired; TimerName duration" Send="TimerSet 0.400000 death"/>
        <On Terms="TimerExpired; TimerName duration" Send="SetOpacity 0.000000 0.400000"/>
        <On Terms="TimerExpired; TimerName death" Send="Destroy"/>
        <Host Subject="1testfixedskybox3"/>
        <HostSiteOps Ops="SOpAttachOrigin 1testskyboxrotation2"/>
        <Model value="1testskyboxtransitionfog"/>
        <Scale value="1.000000,1.000000,0.100000"/>
        <ModelFlags index="AutomateGlobalLoops" value="1"/>
    </CActorModel>
No.3
    <CActorModel id="1testfixedskybox5">
        <AcceptedHostedPropTransfers index="Visibility" value="0"/>
        <On Terms="ActorCreation" Send="$Stand PlayForever"/>
        <On Terms="ActorCreation" Send="TimerSet 0.800000 birth"/>
        <On Terms="ActorCreation" Send="SetOpacity"/>
        <On Terms="TimerExpired; TimerName birth" Send="SetOpacity 1.000000 0.400000"/>
        <On Terms="TimerExpired; TimerName birth" Send="TimerSet 4.600000 duration"/>
        <On Terms="TimerExpired; TimerName duration" Send="TimerSet 0.400000 death"/>
        <On Terms="TimerExpired; TimerName duration" Send="SetOpacity 0.000000 0.400000"/>
        <On Terms="TimerExpired; TimerName death" Send="Destroy"/>
        <Host Subject="1testfixedskybox3"/>
        <HostSiteOps Ops="SOpAttachOrigin 1testskyboxrotation2 1testskyboxrotation2"/>
        <Model value="1testskyboxtransitionfog"/>
        <Scale value="1.000000,1.000000,0.100000"/>
        <ModelFlags index="AutomateGlobalLoops" value="1"/>
    </CActorModel>
No.4
    <CActorModel id="1testfixedskybox6">
        <AcceptedHostedPropTransfers index="Visibility" value="0"/>
        <On Terms="ActorCreation" Send="$Stand PlayForever"/>
        <On Terms="ActorCreation" Send="TimerSet 1.200000 birth"/>
        <On Terms="ActorCreation" Send="SetOpacity"/>
        <On Terms="TimerExpired; TimerName birth" Send="SetOpacity 1.000000 0.400000"/>
        <On Terms="TimerExpired; TimerName birth" Send="TimerSet 4.600000 duration"/>
        <On Terms="TimerExpired; TimerName duration" Send="TimerSet 0.400000 death"/>
        <On Terms="TimerExpired; TimerName duration" Send="SetOpacity 0.000000 0.400000"/>
        <On Terms="TimerExpired; TimerName death" Send="Destroy"/>
        <Host Subject="1testfixedskybox3"/>
        <HostSiteOps Ops="SOpAttachOrigin 1testskyboxrotation2 1testskyboxrotation2 1testskyboxrotation2"/>
        <Model value="1testskyboxtransitionfog"/>
        <Scale value="1.000000,1.000000,0.100000"/>
        <ModelFlags index="AutomateGlobalLoops" value="1"/>
    </CActorModel>
No.5
    <CActorModel id="1testfixedskybox7">
        <AcceptedHostedPropTransfers index="Visibility" value="0"/>
        <On Terms="ActorCreation" Send="$Stand PlayForever"/>
        <On Terms="ActorCreation" Send="TimerSet 1.600000 birth"/>
        <On Terms="ActorCreation" Send="SetOpacity"/>
        <On Terms="TimerExpired; TimerName birth" Send="SetOpacity 1.000000 0.400000"/>
        <On Terms="TimerExpired; TimerName birth" Send="TimerSet 4.600000 duration"/>
        <On Terms="TimerExpired; TimerName duration" Send="TimerSet 0.400000 death"/>
        <On Terms="TimerExpired; TimerName duration" Send="SetOpacity 0.000000 0.400000"/>
        <On Terms="TimerExpired; TimerName death" Send="Destroy"/>
        <Host Subject="1testfixedskybox3"/>
        <HostSiteOps Ops="SOpAttachOrigin 1testskyboxrotation2 1testskyboxrotation2 1testskyboxrotation2 1testskyboxrotation2"/>
        <Model value="1testskyboxtransitionfog"/>
        <Scale value="1.000000,1.000000,0.100000"/>
        <ModelFlags index="AutomateGlobalLoops" value="1"/>
    </CActorModel>

More Textures

  • Again set up more Textures that are desirable for the alternative skybox model actors #2 and #3.
    • For demo purposes here is the XML
No.1 (asteroid alternative diffuse)
    <CTexture id="2testskyboxasteroidtexture1">
        <File value="Assets\Textures\waterterrantileblue.dds"/>
        <Slot value="main.diffuse"/>
    </CTexture>
No.2 (asteroid alternative specular)
    <CTexture id="2testskyboxasteroidtexture2">
        <File value="Assets\Textures\iceworldcliff1_specular_00.dds"/>
        <Slot value="main.specular"/>
    </CTexture>
No.3 (asteroid alternative normal)
    <CTexture id="2testskyboxasteroidtexture3">
        <File value="Assets\Textures\smx2_bridge_pylon_crystal_norm.dds"/>
        <Slot value="main.normal"/>
    </CTexture>
No.4 (fixed skybox alternative 1)
    <CTexture id="3testskybox3texture1">
        <File value="Assets\Textures\firetile2.dds"/>
        <Slot value="generic02.emissive"/>
    </CTexture>
No.5 (fixed skybox alternative 2)
    <CTexture id="2testskybox3texture2">
        <File value="Assets\Textures\smp_prologue03_shot01_takeoff_fire.dds"/>
        <Slot value="generic03.emissive"/>
    </CTexture>
No.6 (fixed skybox alternative 3)
    <CTexture id="2testskybox3texture3">
        <File value="Assets\Textures\smx2_shiproom_sunflare_diff.dds"/>
        <Slot value="hair.emissive"/>
    </CTexture>

Setting Up The Other Actors

  • Under the Model Type Actor #3 made in the basic tutorial section modify the Events to include a Signal event that uses a Timer Set action, use fixed as the Sub Name for the signal and give the timer a 2 second duration. Create another two events with the same setup except the timers are set to 2.5 and 2.516 seconds. When the first timer expires a Timer Expired event uses a Set Opacity action to fade out the fixed skybox over 0.5 seconds (Opacity value of 0 and Blend In Duration of 0.5). When the second timer expires use a Set Visibility action to disable actor visibility and three Texture Select By Id actions linking to the alternative textures for the fixed skybox. When the final timer expires use another Set Visibility action to re-enable actor visibility and a Set Opacity action to fade in the fixed skybox over 0.5 seconds (Opacity value of 1 and Blend In Duration of 0.5). The reason actor visibility is disabled temporarily is to stop the model momentarily regaining opacity when it is texture swapped.
  • Under the Model Type Actor #2 made in the basic tutorial section modify the Events to include an Actor Creation event that uses a Reference Set action. With the Reference Set action under the Reference Name field enter a Custom string beginning with the ::global. prefix (eg. ::global.Skybox2) and under the Reference Source field set the System reference to Self. This associates the Model Type Actor #2 with the global reference so any actor event actions linking to the reference in the Target field or Send Actor Message trigger actions using an Actor From function targeting the reference will automatically be sent to this actor. Like all global references only one actor at a time can be associated with the reference. Add 2 Signal Events using transition as the Sub Name with one using a Create action to create Model Type Actors #5 and the second to use a Signal action with the Target field set to the ID of Model Type Actor #3 and fixed as the Sub Name. This setup means that when the transition signal is sent to the global reference this actor will create the transition smoke screen and tell the fixed skybox to prepare to swap textures.
  • Under the Model Type Actor #1 made in the basic tutorial section modify the Events in the same way as the Model Type Actor #3 except using notfixed for the signal Sub Name and the textures for the asteroids.
  • Under the Doodad Type Actor used for the not fixed skybox section modify the Events to include an Actor Creation event that uses a Reference Set action. With the Reference Set action under the Reference Name field enter a Custom string beginning with the ::global. prefix (eg. ::global.Skybox1) and under the Reference Source field set the System reference to Self. Add an event on Actor Creation to create Model Type Actor #4. Next create 4 Signal Events using state2 as the Sub Name to use Signal actions with one having the Target field set to the global reference of Model Type Actor #2 and transition as the Sub Name, make the second target the ID of Model Type Actor #1 using notfixed as a sub name and the third targets the ID of Model Type Actor #4 using appear1 as the sub name. This setup uses the not fixed skybox actor as a relay for signals to the fixed skybox actor so only a single signal is needed to modify the whole system. With the final Signal event use a Timer Set actions to create a 2 second timer that triggers a Timer Expired event using a Set Opacity action to fade out the actor (Opacity value of 0 and Blend In Duration of 0.5) to hide the original planet.
    • For demo purposes here is the XML of the events that need to be added to the actors created in the basic part of the tutorial
Model Type Actor #3 
        <On Terms="Signal.*.fixed" Send="TimerSet 2.000000 opacity"/>
        <On Terms="Signal.*.fixed" Send="TimerSet 2.500000 swap"/>
        <On Terms="Signal.*.fixed" Send="TimerSet 2.516000 opacity2"/>
        <On Terms="TimerExpired; TimerName opacity" Send="SetOpacity 0.000000 0.500000"/>
        <On Terms="TimerExpired; TimerName swap" Send="SetVisibility"/>
        <On Terms="TimerExpired; TimerName swap" Send="TextureSelectById 2testskyboxasteroidtexture1"/>
        <On Terms="TimerExpired; TimerName swap" Send="TextureSelectById 2testskyboxasteroidtexture2"/>
        <On Terms="TimerExpired; TimerName swap" Send="TextureSelectById 2testskyboxasteroidtexture3"/>
        <On Terms="TimerExpired; TimerName opacity2" Send="SetVisibility 1"/>
        <On Terms="TimerExpired; TimerName opacity2" Send="SetOpacity 1.000000 0.500000"/>
Model Type Actor #2
        <On Terms="ActorCreation" Send="RefSet ::global.Skybox2 ::Self"/>
        <On Terms="Signal.*.transition" Send="Create 1testfixedskybox3"/>
        <On Terms="Signal.*.transition" Target="1testfixedskybox2" Send="Signal fixed"/>
Model Type Actor #1
        <On Terms="Signal.*.notfixed" Send="TimerSet 2.000000 opacity"/>
        <On Terms="Signal.*.notfixed" Send="TimerSet 2.500000 swap"/>
        <On Terms="Signal.*.notfixed" Send="TimerSet 2.516000 opacity2"/>
        <On Terms="TimerExpired; TimerName opacity" Send="SetOpacity 0.000000 0.500000"/>
        <On Terms="TimerExpired; TimerName swap" Send="SetVisibility"/>
        <On Terms="TimerExpired; TimerName swap" Send="TextureSelectById 2testskybox3texture1"/>
        <On Terms="TimerExpired; TimerName swap" Send="TextureSelectById 2testskybox3texture2"/>
        <On Terms="TimerExpired; TimerName swap" Send="TextureSelectById 2testskybox3texture3"/>
        <On Terms="TimerExpired; TimerName opacity2" Send="SetVisibility 1"/>
        <On Terms="TimerExpired; TimerName opacity2" Send="SetOpacity 1.000000 0.500000"/>
Doodad Type Actor
        <On Terms="ActorCreation" Send="Create 1testnotfixedskybox3"/>
        <On Terms="ActorCreation" Send="RefSet ::global.Skybox1 ::Self"/>
        <On Terms="Signal.*.state2" Target="::global.Skybox2" Send="Signal transition"/>
        <On Terms="Signal.*.state2" Target="1testnotfixedskybox2" Send="Signal notfixed"/>
        <On Terms="Signal.*.state2" Send="TimerSet 2.000000 opacityoff"/>
        <On Terms="TimerExpired; TimerName opacityoff" Send="SetOpacity 0.000000 0.500000"/>
        <On Terms="Signal.*.state2" Target="1testnotfixedskybox3" Send="Signal appear1"/>

Testing The System

  • Although actor events using a Signal action targeting the global reference of the Doodad Type Actor (::global.Skybox1 in this example) could be used to trigger the skybox change, a simple chat activated trigger will be used. Open the Trigger Editor (F6) and right click the lower left window selecting the New sub menu and New Trigger (Ctrl+T).
  • Right click the upper right box selecting the New sub menu and New Event (Ctrl+E) to open a new window. Select Game under the Label box and then the Chat Message event. Left click the event and then in the middle right box double click Text: and change it to the Word Of String function.
  • Right click the upper right box selecting the New sub menu and New Action (Ctrl+R) to open a new window. Select General under the Label box and then the If Then Else action. Right click the grey arrow of the action in the upper right window selecting the New sub menu and New Condition (Ctrl+K). In the window that opens select Comparison, double click the Value 1: field in the middle right window and change it to Chat String and the Value 2: field to a string of choice (eg.state2).
  • Right click the Then part of the action in the upper right box selecting the New sub menu and New Action (Ctrl+R) to open a new window. Select Actor under the Label box and then the Actor Send Message action. In the middle right box double click the Message: field and under Value select Signal under the Msg Type: list adding state2 as the Sub Name.
  • In the middle right box double click the Actor: field and select the Actor From function. In the middle right box double click the name: field and as a value type in the global reference used for the Doodad Type Actor (eg. ::global.Skybox1).
  • Test the map, open chat (Enter) and type in the triggering chat string (state2 in this example) and watch your skybox change. In this example it changes from a greenish planet in the distance with asteroids that have green cracks to a close-up fiery planet with frozen looking asteroids.

Known Bugs

  • Model actors attached to the not fixed skybox are always visible and not partially hidden by the fog of war
  • Unless actor visibility is removed the models will gain full opacity momentarily when texture swapped
  • The fixed skybox actor cannot use additional SOps without them being reapplied every frame resulting in incremental lag
  • The not fixed skybox actor is not created if it has any SOps
  • The skybox actors are created at a different location compared to the skybox models so need adjustment