Scripted Textures
By Tag (From Tag's site, currently custody of Postal)

Advanced

  Muchos Thankiosos to Jack Porter for explaining this all to me. I had asked him pre-220 if it would be possible in Unreal Tournament to create an in-level scoreboard for my UnrealBall mod, and he told me about this class. He also told me it would be available in Unreal in the next patch. 
When I discovered the ScriptedTexture class was indeed buried away in Unreal 224, I again wrote Jack and asked for a quickie "Idiot's Guide to Creating Scripted Textures", to which he obliged almost instantly. His written instructions worked like a charm, and are basically paraphrased below. I expanded a bit in a few areas and used references to the downloadable example.

 
 
The ScriptedTexture class is an ancestor of Texture, which itself is under Bitmap. If you are a UnrealScript programmer, and you export all of your .U files to .UC text files, then you should have file ScriptedTexture.uc in your engine\classes folder under your Unreal main folder. 
If you wanted to study the class inside UnrealEd, you have to check off "Only Show Actor Classes", since the Bitmap class is not under Actor, it's under Object.

Object->Bitmap->Texture->ScriptedTexture
 
Studying this class will yield the main clues as to how it works. There are two variables declared, one as a design-time and one as a run-time variable. They are as follows: 
var Actor NotifyActor;
this run-time property is set to some custom class that you will write later that will handle the drawing on your texture.

var() Texture SourceTexture;
this design-time variable will point to the Scripted texture class that you will wish to draw on.
 
  
Also inside the class are four functions DrawTile, DrawText, DrawColoredText, and ReplaceTexture. I haven't played with each one yet, but I'm assuming they are fairly self-explanatory. 
 
What follows is a tutorial on creating a simple implementation of a scripted texture, one that displays a small message on the texture. The message cycles between four colors and bounces a bit inside the texture, just to prove that it's happening in real-time. 
  
Step 1: Create a "border" texture. 
Using PhotoShop or whatever image-editing program you prefer, create the texture that will serve as the "page" that your scripted texture will draw on. My base texture for this demo is a blue frame around a black field. I gave the frame a little 3d effect in PhotoShop.
 
  
Step 2: Import the texture into UnrealEd. 
Again, same basic rules apply here, nothing out of the ordinary. Import the texture into the package of your choice. One caution: make sure the 256 color palette of the image contains all of the possible colors that you will use to draw upon the texture. Remember that each individual brush surface uses a palettized, 256 color texture. If you have a palette of 256 shades of blue on your border texture, and wish to draw red text on it, you won't get the desired effect.

In the downloadable demo, the border texture is named STBORDER.
 
  
Step 3: Create the ScriptedTexture 
You do this the same way you create a procedural texture (FireTexture, WaterTexture, etc). Put this texture in the same package as the border texture you created above, and make it the same size as the border texture (Of course, give it a different name as the border texture). Then, right click on the ScriptedTexture to bring up its properties, and make the property "SourceTexture" point to your border texture.

In the downloadable demo, the ScriptedTexture's name is SCRIPTBORDER, and it points to texture STBORDER described above.

If you do this correctly, the border texture and the scriptedtexture will look exactly the same in the texture preview window of UnrealEd.
 
  
Step 4: Create the Base "Communicator" Class. 
This is the base class that you will code your scripted code into. The class shown below need only be created once for ALL your scripted textures. To create different types of classes, inherit off of this base class.
 
class ClientScriptedTexture expands Info; 
  
var() Texture ScriptedTexture; 
  
simulated function BeginPlay() 
{ 
if(ScriptedTexture != None) 
ScriptedTexture(ScriptedTexture).NotifyActor = Self; 
} 
  
simulated function Destroyed() 
{ 
if(ScriptedTexture != None) 
ScriptedTexture(ScriptedTexture).NotifyActor = None; 
} 
  
simulated event RenderTexture(ScriptedTexture Tex) 
{//implement in subclass 
} 
  
defaultproperties 
{ 
RemoteRole=ROLE_SimulatedProxy 
bStatic=False 
bAlwaysRelevant=True 
bNoDelete=True 
}  
  
Step 5: Create the specific "Communicator" Class. 
Inherit a new class off of ClientScriptedTexture above. This specific class is where you will put all of the code for this scriptedtexture effect. In my demo, I created a string property that the level designer can enter, and the string will be drawn on the texture surface. It will both bounce from left to right and cycle between red, green, blue, and yellow. The code for this class is below
 
  
class stBannerAd expands ClientScriptedTexture;

var(ClientScriptedTexture) string AdvertisingText;

var int nX;
var int nDelta;         //move direction

simulated function BeginPlay()
{
    Super.BeginPlay();
    nX = 16;                 //init x location
    nDelta = 1;
}

simulated event RenderTexture(ScriptedTexture Tex)
{
local color clr;
local int nSec;

nSec = Level.TimeSeconds % 4;
if (nSec == 0) {
    clr.r = 0;
    clr.g = 0;
    clr.b = 255;
} else if (nSec == 1) {
    clr.r = 255;
    clr.g = 0;
    clr.b = 0;
} else if (nSec == 2) {
    clr.r = 0;
    clr.g = 255;
    clr.b = 0;
} else {
    clr.r = 255;
    clr.g = 255;
    clr.b = 0;
}


nX += nDelta;

if (nX < 16) {        //change direction
    nX = 16;
    nDelta = 1;
}   

if (nX > 78) {        //change direction
    nX = 78;
    nDelta = -1;
}   


Tex.DrawColoredText( nX, 28, AdvertisingText, Font'WhiteFont', clr );

}

 
The main function is of course RenderTexture, which passes in the surface that it to be rendered. My little demo figures out which color to draw the text in, based on the number of seconds elaped in the level. It then adds internal value Delta to nX, which is the starting left position for the text, and then checks to see if the direction should be switched (my demo is hardcoded to a value of 78 to bounce on the right side, which will only look good for strings the same length as my demo string, which is "http://www.planetunreal.com/". A better class would check the length of the string and figure out the right bounce amount. 
Finally, RenderTexture calls DrawColoredText with the appropriate parameters.
 
  
Step 6: Set it all up in a map 
The last step is to just put all of these pieces together in a map. Create some brushes and put the ScriptedTexture on their surface (make sure to use the ScriptedTexture and not the Border Texture, since they do look exactly like. Giving them easily distinguishable names will help here).

Then, create an instance of your specific "communicator" class somewhere on the map. Make sure that its ScriptedTexture property is equal to the Scripted Texture that you created (the same one you just put on the brush surfaces).
 


  
