Advanced Models SDK

Scripted custom skins

Relevance

This page is relevant to:
Skinners wishing to use custom scripting in skins for an AMS model

You will need

Source code for any Unreal Tournament model based on Advanced Model Support, and some UnrealScript experience.

About scripted skins

Scripted skins provide the framework for skins which aren't just a bunch of textures. Advanced users can use them for dynamic modification of the skin rules, as well as special effects.

When a skin is selected for an AMS model, the player or bot class's code looks in the skin package for a small Unrealscript controlling the skin. If the script doesn't exist, a default is used, making the model behave rather like older UT models with fixed skin setups.

Modellers who've followed the rest of this tutorial: when you wrote the WhateverSkinInfo class, that was the default skin info.

However, here's the innovative bit. If a script exists with the same name as the skin selected, functions in that script are called instead. This lets the skin author modify many aspects of the player or bot!

Possible uses include:

Please note: modification of a model without the author's permission is difficult (going back to their original Max or other source file is likely to be much easier), is not ethical, will usually result in the altered model being banned from sites like Polycount, and may be illegal. Even if the readme file says you can modify the model, telling the modeller what you're doing is good courtesy.

Making a scripted skin

Scripted skins aren't quite the same as normal ones, because they contain code and need to be compiled. You do this using the "UCC make" command, the same as compiling a model or mod.

Starting

Create a new folder inside your base UnrealTournament folder. The folder's name must be the name of the UTX file you want to end up with, and must start with the model's mesh name plus "Skins".

Now create a folder inside the one you just created, called "Classes". Your code goes here.

You also need to choose a 4-letter code to identify your skin. Make this something other skinners are reasonably unlikely to use. Basing it on your nickname is probably a good idea (for example, my nickname is Psychic_313, so my first skin for a model might be called Psy1 or 313A or something).

Making the skins

In all of the following examples, replace "pqrs" with the 4-letter code and # with the texture (material) number.

For each non-team non-face material, the skin needs to contain a texture called pqrs#.

For each team non-face material, the skin needs to contain textures called pqrs# (any colour), pqrs#T_0 (red), pqrs#T_1 (blue), pqrs#T_2 (green) and pqrs#T_3 (yellow or gold).

For each face material, the skin needs to contain a texture called pqrs#(Face Name), replacing (Face Name) with the name of the face. This name doesn't have to be the same as the name it appears as in the menus. If the face material is set to change with team, you also need pqrs#T_0(Face Name), pqrs#T_1(Face Name), pqrs#T_2(Face Name) and pqrs#T_3(Face Name). Repeat this for each face - you can have any number.

Finally, you can add 64x64 pixel "talktextures" which appear when the player or bot talks. If the model has no face, you can have either one of these, called pqrsC ("C" for "Chat") or five including team colours (pqrsC plus pqrsCT_0 to pqrsCT_3). If the model has faces, the names of the talktextures are the same as the names of the faces, but replacing the material number with "C" (for example, pqrsCT_3(Face Name)).

Each texture should be stored in a 256-colour BMP or PCX file named the same as the texture name above, plus ".bmp" or ".pcx". For scripted skins, you should put these in the folder named after the UTX that you created earlier.

For best results, I recommend saving your textures from your paint program as 24-bit (16 million colour, RGB) BMP files, then using the excellent utility Bright (by Epic Games' Eric de Neve) to convert these to 256-colour PCX files. Bright is slow (a few seconds per file) but it's worth using it, as its colour reduction is extremely good quality, better than Paintshop Pro or Photoshop. You can get it from Polycount's UT resources page. If you do this, be careful to make your script import only the PCX files! (24-bit images either crash UCC or look random)

The script

Create a new text file in the Classes subfolder. The name is important. It must be the UTX name without the extension, followed by an underscore (_), followed by the 4-letter code, followed by ".uc". For example, if you're making skins for a model whose mesh is called CubicMan and your chosen UTX name and 4-letter code are "CubicManSkins_Extra.utx" and "xtra", the script must be called "CubicManSkins_Extra_xtra.uc".

Open the script in Notepad or equivalent and fill in these standard headers:

class name_of_script_file extends MyModelSkinInfo abstract;

defaultproperties
{

}

Replace "name_of_script_file" with the filename without the extension (e.g. CubicManSkins_Extra_xtra) and MyModelSkinInfo with the name the modeller used for their default skin info script (e.g. CubicManSkinInfo).

You now need to tell UCC to import your textures into the package. You do this with lines in this format, placed just below the "class" line:

#exec TEXTURE IMPORT NAME=pqrs0 FILE=pqrs0.pcx LODSET=1

LODSET=1 should be used for skins; LODSET=2 should be used for talktextures.

Now you can start coding! Any of these lines, placed in the defaultproperties section between the { and } symbols, will override what the modeller specified:

As well as this, if you can write Unrealscript, you can set special effects for the model by overriding the functions SetFX and UnsetSkin. The first line of UnsetSkin should always be "Super.UnsetSkin(SkinActor,PlayerClass);" and the rest of UnsetSkin should reverse the effects of SetFX (so if you make the model emit ambient light in SetFX, you must switch off ambient light in UnsetSkin).

If you can write UnrealScript, you can also alter texture loading behaviour by overriding the function LoadSkin, which converts a string skin name to a texture.

Here's a template for overriding these functions:

static function SetFX(actor SkinActor,Class<GenericPlayer> PlayerClass)
{
	Super.SetFX(SkinActor,PlayerClass);
	// do something here. It may not work correctly in Valhalla Avatar
}

static function UnsetSkin(actor SkinActor,Class<GenericPlayer> PlayerClass)
{
	Super.UnsetSkin(SkinActor,PlayerClass);
	// undo something here.
}

static function Texture LoadSkin(String SkinName, optional bool bNoWarning)
{
	if( SkinName~="MyMeshSkins.SpecialSkinName1" )
	{
		return Texture'MyModel.SpecialSkin';
	}
	else if ( SkinName~="MyMeshSkins.SpecialSkinName2" )
	{
		return Texture'Botpack.SomeOtherSkin';
	}
	// customise the stuff above
	else
	{
		// this is important, don't change it
		return Super.LoadSkin(SkinName,bNoWarning);
	}
}

Compiling it

Open System\UnrealTournament.ini in Notepad and find the section headed "[Editor.EditorEngine]". Scroll down a bit until you see a list of EditPackages. Add these, in this order, if they're not already there:

EditPackages=AdvancedModelSupport
EditPackages=(package name containing the model)
EditPackages=(name of your UTX)

If the package you're making already exists, delete it. The UnrealScript compiler won't recompile packages which already exist.

Now go to a DOS prompt and do the following:

C:\Windows>x:
X:\>cd "\games\unrealtournament"
X:\Games\UnrealTournament>cd system
X:\Games\UnrealTournament\System>ucc make

Replace x with the drive you installed UT on and \games\unrealtournament with the path to your UT folder. If you have the "Command Prompt Here" powertoy, you can also go to your UT folder in Explorer, right-click on System, choose "Command Prompt Here" and type "ucc make".

The UCC compiler actually outputs your skin package as a U file in the System folder! It is perfectly safe to leave it there and make an INT file for it as usual, as if it was a UTX (the formats are identical).

However, this might confuse many users who're used to skins always being in UTX files, so when you've finished making the skin package, rename it to *.utx and move it to the Textures folder.

The INT file

The INT file for each skin needs to be named after the UTX (or U) file, and contain this:

[public]
Object=(Name=(skin package name).(4-letter code)1,Class=Texture,Description="(human-readable name)")
Object=(Name=(skin package name).(4-letter code)2(face name),Class=Texture,Description="(human-readable name of face)")

The 1 and 2 are required (any single-digit number will do; it's safest to use the actual material number).

If there is more than one skin, or more than one face, in your UTX file, you need one line per skin plus one line per face.

As a demonstration of the power of scripted skins, I made a version of the AMS_CubicManSkins_Test package with a pulsing light effect. Yes, it looks stupid :-)

I chose the package name AMS_CubicManSkins_Pulse and the skin code Tst1 ("test 1"). The textures went in "E:\Games\UnrealTournament\AMS_CubicManSkins_Pulse\" and this script went in "E:\Games\Unrealtournament\AMS_CubicManSkins_Pulse\Classes\AMS_CubicManSkins_Pulse_Tst1.uc".

I also enabled team-coloured faces for this model (if you've downloaded the SDK and demo models zipfile, which includes this package, look at the hair colour when you change team).

class AMS_CubicManSkins_Pulse_Tst1 extends AMS_CubicManSkinInfo;

// Import some textures. I recommend the use of "UCC Make" to compile this.
// Note that the texture names don't have to match the PCX/BMP names.

#exec TEXTURE IMPORT NAME=Tst10 FILE=Test0.pcx
#exec TEXTURE IMPORT NAME=Tst10t_0 FILE=Test0t_0.pcx
#exec TEXTURE IMPORT NAME=Tst10t_1 FILE=Test0t_1.pcx
#exec TEXTURE IMPORT NAME=Tst10t_2 FILE=Test0t_2.pcx
#exec TEXTURE IMPORT NAME=Tst10t_3 FILE=Test0t_3.pcx

#exec TEXTURE IMPORT NAME=Tst11Test FILE=Test1Test.pcx
#exec TEXTURE IMPORT NAME=Tst11t_0Test FILE=Test1t_0Test.bmp
#exec TEXTURE IMPORT NAME=Tst11t_1Test FILE=Test1t_1Test.bmp
#exec TEXTURE IMPORT NAME=Tst11t_2Test FILE=Test1t_2Test.bmp
#exec TEXTURE IMPORT NAME=Tst11t_3Test FILE=Test1t_3Test.bmp

#exec TEXTURE IMPORT NAME=Tst12 FILE=Test2.pcx
#exec TEXTURE IMPORT NAME=Tst12t_0 FILE=Test2t_0.pcx
#exec TEXTURE IMPORT NAME=Tst12t_1 FILE=Test2t_1.pcx
#exec TEXTURE IMPORT NAME=Tst12t_2 FILE=Test2t_2.pcx
#exec TEXTURE IMPORT NAME=Tst12t_3 FILE=Test2t_3.pcx

#exec TEXTURE IMPORT NAME=Tst1CTest FILE=TestCTest.pcx

// A silly example of how scripted skins can alter skin behaviour.
// Enables team-coloured faces and adds pulsing ambient light for
// this skin only.

// There's really not much code here, is there?

static function SetFX(actor SkinActor,Class<GenericPlayer> PlayerClass)
{
    Super.SetFX(SkinActor,PlayerClass);
    SkinActor.AmbientGlow = 255; // 0=none, 1 to 254=steady, 255=pulsing
}

static function UnsetSkin(actor SkinActor,Class<GenericPlayer> PlayerClass)
{
    Super.UnsetSkin(SkinActor,PlayerClass);
    SkinActor.AmbientGlow = SkinActor.default.AmbientGlow; //reset to default
}

// Use defaultproperties to enable team-coloured face (the face is material 1)

defaultproperties
{
	ChangesWithTeam(1)=1
}

(Note: the version included in the SDK isn't exactly the same)


Previous page

Extra options specific to AMS

Next page

Custom sounds and status dolls

Back to index


AMSDK compiled by Simon `Psychic_313' McVittie, http://www.pseudorandom.co.uk
This page by Simon McVittie