Mod Menus

From Oldunreal-Wiki
Jump to navigation Jump to search

How To Create Simple Mod Menus Introduction: This tutorial will cover the very basic elements required to create and implement a simple menu system to interact with your mutator or mod. It will NOT teach you UWindow or even offer much insight in UWindow, but will allow you to create a very simple and functional mod menu. Throughout this tutorial I will refer to various objects as YourPackage.int or YourPackageClass, etc. Please remember to replace any instance of this with your appropriate name. OK, lets get started. Step 1:Create A Mutator The first step in this process is for you to create a mutator or mod that you would like to add some sort of menu control to. Once you are at this stage, continue on to Step 2. Step 2:Modify YourPackage.int File The next step in the process is to modify YourPackage.int to include the following line under the [Public] section: Object=(Name=YourPackage.YourPackageModMenuItem,Class=Class, MetaClass=UMenu.UMenuModMenuItem,Description="Description, Help") If you don't have an .int file for your mutator, it is time to start asking yourself why. Stop and quickly reference a tutorial on the basics of making a mod so that you can create one real quick. An important announcement regarding mod menus was issued by the Epic Unreal Engine development team earlier this year. It can be found at http://unreal.epicgames.com, but I will reprint here verbatim for the lazy. "A Note to Modmakers August 25, 2000 - by Jack Porter A lot of people have noticed that it takes the UT menus a long time to start up when you have lots of mods installed. This is because the code which creates the Mod menu loads all of the mod packages into memory to add them to the mods' items to the Mod menu. We've addressed this for the next UT patch, but we need modmakers to make a small change to the way they add items to the Mod menu. Previously, mod menu items were created with an .int file entry something like this: Object=(Name=ChaosUT.ChaosUTModMenuItem,Class=Class,MetaClass=UMenu.UMenuModMenuItem) To make your mod load quicker when UT starts up, you need to add a Description field on the end. Object=(Name=ChaosUT.ChaosUTModMenuItem,Class=Class,MetaClass=UMenu.UMenuModMenuItem,Description="ChaosUT Config,Configure ChaosUT") The stuff after the comma is the text that appears on the help bar at the bottom of the screen. If you don't make the change to your int file, your mod will still work with the next UT patch, but it won't load any faster - so please make the change for the next release of your mod. - Jack" OK, so basically if you are ripping code from another mods .int file, be sure that it contains the Description field as described above. To be a little more clear on what those fields actually represent, the "Description" in the Description field is what will actually display in the mod menu and the "Help" in the Description field is what will display in the bar at the bottom of the screen when you mouseover the menu item. Once you have modified your .int file, it is time to move on to Step 3. Step 3:Create Class Files Create the following three class files:YourPackageModMenuItem.ucYourPackageConfigWindow.ucYourPackageClientWindow.ucJust create the files right now and leave them blank, we will fill them in with code in a minute. You should notice at this point that YourPackageModMenuItem is the class referenced in the .int example in Step 2. Step 3A:YourPackageModMenuItem.uc


//======================================
// YourPackageModMenuItem: Mod Menu Item.
//======================================
class YourPackageModMenuItem expands UMenuModMenuItem;
function Execute()
{
  MenuItem.Owner.Root.CreateWindow(class'YourPackageConfigWindow',10,10,150,100);
}
defaultproperties
{
  MenuCaption="&Description"
  MenuHelp="Help"
}

This class simply expands UMenuModMenuItem and sets what is actually going to happen when the menu item is selected with the Execute function. As you can see, the Execute function uses CreateWindow to load the class YourPackageConfigWindow, which is the second file to create in Step 3. The default properties set the Description and Help fields again, if they weren't set before. Just make them the same as whatever is in your .int file. Step 3B:YourPackageConfigWindow.uc


//===================================================
// YourPackageConfigWindow: Actual Configuration Window.
//===================================================
class YourPackageConfigWindow expands UWindowFramedWindow;
function BeginPlay()
{
  Super.BeginPlay();
  WindowTitle = "YourPackage Config Window";
  ClientClass = class'YourPackageClientWindow';
  bSizable = False;
}
function Created()
{
  Super.Created();
  SetSize(220, 140);
  WinLeft = (Root.WinWidth - WinWidth) / 2;
  WinTop = (Root.WinHeight - WinHeight) / 2;
}
defaultproperties
{
}

YourPackageConfigWindow is the class that creates the window that is called from the menu item created with YourPackageModMenuItem. So, when somebody clicks the mod menu item, it calls the YourPackageConfigWindow which actually creates the configuration window. The two important things to note about the above code is the WindowTitle and ClientClass. WindowTitle is unsuprisingly what the title of the config window is going to be. Set this to whatever you want. ClientClass is the class file that is actually going to control the functionality of the configuration window. Up until this point all we have is an empty window titled "YourPackage Config Window". The YourPackageClientWindow class is going to fill in all the neat little buttons and checkboxes, etc. You should notice at this point that the ClientClass is YourPackageClientWindow, which is the third class file I told you to create earlier. If you feel like messing around with the window size and/or position of the window created with this class, tweak the numbers in the Created function. Step 3C:YourPackageClientWindow.uc


//================================
// YourPackageClientWindow.
//================================
class YourPackageClientWindow expands UWindowDialogClientWindow;
var UWindowCheckBox Option;
var UWindowSmallCloseButton CloseButton;
function Created()
{
  // Checkbox Option For Your Mutator
  Option = UWindowCheckBox(CreateControl(class'UWindowCheckBox', 10, 25, 150, 1));
  Option.SetText("Your Option: ");
  Option.bChecked = class'YourClass'.default.bOption;
  // Finished button
  CloseButton = UWindowSmallCloseButton(CreateWindow(class'UWindowSmallCloseButton',
  152, 100, 48, 16));
  CloseButton.SetText( "Finished" );
}
function Notify(UWindowDialogControl C, byte E)
{
  switch(E) {
    case DE_Change: // the message sent by sliders and checkboxes
      switch(C) {
        case Option:
          class'YourClass'.default.bOption=Option.bChecked;
          class'YourClass'.static.StaticSaveConfig();
          break;
        }
    case DE_Click: // the message sent by buttons
      switch(C){
        case CloseButton:
          class'YourClass'.default.bOption=Option.bChecked;
          class'YourClass'.static.StaticSaveConfig();
          break;
        }
    break;
    }
}
defaultproperties
{
}

This example creates a window with a single checkbox and a button in the Created function. Obviously, you could add a thousand controls to the window, but for now this will do. The other important function of this class is the Notify function. This is what actions will take place when a user manipulates a control. Most controls will fall under the DE_Change Notify but note that buttons fall under the DE_Click Notify. Let us examine both functions a little more closely. Created Function:The createcontrol actually creates the checkbox. SetText sets what text is displayed next to the checkbox. This next line is important: Option.bChecked = class'YourClass'.default.bOption; This sets the default value of the checkbox. Obviously, you can set this to whatever you want, but for this case we are going to set it equal to the DEFAULT value of the option within the CLASS THAT YOU ARE GOING TO CHANGE with this menu item. So within the class you are going to affect the following code needs to placed: DEFINE THE VARIABLE:var() globalconfig bool bOption; SET THE DEFAULT (under defaultproperties):bOption=True So the default for bOption is set to True and when the window is created, the checkbox will be checked. Notify Function:The Notify function handles user input for the controls. I have placed two controls within the window, because even though you don't need a button, it helps users I think. Both controls do exactly the same thing, with the exception that the button will close the window also. Both controls set the default option of the variable bOption to whatever the checkbox is set to (ie: checked=true, unchecked=false). So if you uncheck the checkbox, it sets the default option of bOption to False within the class file. Step 4:Use Option In Class File Of course, the next step is to use the bOption variable within your class to create the effect you want. example:if ( bOption ) i = rand(9); if ( !bOption ) i = rand(8); Or whatever. Step 5:Enjoy Sit back with your mutator or mod and start killing.

I also suggest the following tutorials for people interested in learning more about