UDN
Search public documentation:
MakingACommandlet
日本語訳
中国翻译
한국어
Interested in the Unreal Engine?
Visit the Unreal Technology site.
Looking for jobs and company info?
Check out the Epic games site.
Questions about support via UDN?
Contact the UDN Staff
中国翻译
한국어
Interested in the Unreal Engine?
Visit the Unreal Technology site.
Looking for jobs and company info?
Check out the Epic games site.
Questions about support via UDN?
Contact the UDN Staff
UE3 Home > Commandlets > How To Make a Commandlet
How To Make a Commandlet
Overview
game.exe make
executes the make
commandlet that compiles UnrealScript classes.
The engine automatically tries to see whether a command you passed on the commandline is a commandlet, and if it matches, executes the associated code.
Check out UContentCommandlets.cpp and UnPackageUtilities for some examples on commandlets.
How To Make a Commandlet in Script
class HelloWorldCommandlet extends Commandlet; event int Main( string Params ) { log( " hello world " ); return 0; }Or for a native commandlet:
class HelloWorldCommandlet extends Commandlet native; cpptext { INT Main(const FString& CmdLine) { warnf(TEXT("hello world")); return 0; } } native event int Main( string Params );The Main() function is the entry point for your commandlet. The commandlet is passed a string containing all of the parameters for a given run. Note that for
gamename.exe helloworld param1 param2 param3Your commandlet would see the string
param1 param2 param3
as the command line parameters.
How To Make a Commandlet in Native Code
EditorCommandlets.h
.
First, declare your class in a header file like EditorCommandlets.h
:
BEGIN_COMMANDLET(Name,Package) // declare additional methods here. END_COMMANDLETThe commandlet will have a classname of "UNameCommandlet" and will be placed in the package you specify (like Editor). Then, in a .cpp file (like
UContentCommandlets.cpp
), implement your commandlet's Main()
function. If necessary, you can also override the virtual CreateCustomEngine()
function. See the UCommandlet source for more details.
INT UNameCommandlet::Main(const FString& Params) { // do yer stuff here... return 0; }But you're not done yet! Since this is an intrinsic class, you must inform the script system of its presence. To do this you'll have to manually edit the
UnrealEdClasses.h
file, specifically the AUTO_INITIALIZE_REGISTRANTS_UNREALED #define. In that list, add a call to the StaticClass()
function for your commandlet:
#define AUTO_INITIALIZE_REGISTRANTS_UNREALED \ UNameCommandlet::StaticClass(); \The next time you rebuild script the compiler will overwrite this file with your Commandlet class in this list in alphabetical order.
Giving Users Some Help
[HelloWorldCommandlet] HelpDescription="This commandlet displays hello world" HelpUsage="gamename.exe helloworld" HelpWebLink="https://udn.epicgames.com/bin/view/Three/MakingACommandlet" HelpParamNames[0]="param1" HelpParamDescriptions[0]="Ignored since helloworld doesn't need params"Notice that the section name must include the commandlet as part of the class name. Without this, the commandlet wouldn't be found. To see how this information is used, run the following commands:
game.exe help help game.exe help list game.exe help webhelp help
How To Use a Commandlet
examplegame make -fulllaunches the make commandlet inside of ExampleGame. Note that you do not have to specify the package name for native commandlets. If the make commandlet was a script-only commandlet, then it would be invoked using:
examplegame editor.make -fullsince it wouldn't be loaded at startup. Also notice that the commandlet portion of the name isn't needed. The startup code automatically appends _commandlet= when trying to find the specified commandlet.
Common Commandlet Tasks
UContentCommandlets.cpp
) can get you started:
// Below is a template commandlet than can be used when you want to perform an operation on all packages. INT UPerformAnOperationOnEveryPackage::Main(const FString& Params) { // Parse command line args. TArray<FString> Tokens; TArray<FString> Switches; const TCHAR* Parms = *Params; ParseCommandLine(Parms, Tokens, Switches); // Build package file list. const TArray<FString> FilesInPath( GPackageFileCache->GetPackageFileList() ); if( FilesInPath.Num() == 0 ) { warnf( NAME_Warning, TEXT("No packages found") ); return 1; } // Iterate over all files doing stuff. for( INT FileIndex = 0 ; FileIndex < FilesInPath.Num() ; ++FileIndex ) { const FFilename& Filename = FilesInPath(FileIndex); warnf( NAME_Log, TEXT("Loading %s"), *Filename ); UPackage* Package = UObject::LoadPackage( NULL, *Filename, LOAD_None ); if( Package == NULL ) { warnf( NAME_Error, TEXT("Error loading %s!"), *Filename ); } ///////////////// // // Do your thing here // ///////////////// TObjectIterator<UStaticMesh> It;... UStaticMesh* StaticMesh = *It; if( StaticMesh->IsIn( Package ) UObject::CollectGarbage( RF_Native ); } return 0; }You might also want to look at
NormalizePackageNames()
in PackageHelperFunctions.h
(which appeared in QA_APPROVED_BUILD_JUNE_2007). This function can create a filtered list of packages to iterate over, with a few more niceties beyond just iterating over GPackageFileCache
(see the code for details).