Life as an unresolved external symbol.
Beginning Your Game Part 3
IMPORTANT
This tutorial was created with the March build of UDK, as opposed to the February build.
This is a big -MY BAD- on my part.
The rest of the tutorials flow nicely after this. I promise.
Here is what you do:
You download the March build.
You install it.
You set up the config files just like you have been doing in Part 1 and Part 2.
Open UTGame\Config\DefaultGame.ini
Replace the Engine.GameInfo block with the following:
[Engine.GameInfo] DefaultGame=UDKGame.UDKGame DefaultServerGame=UDKGame.UDKGame PlayerControllerClassName=UDKGame.HTPlayerController GameDifficulty=+1.0 MaxPlayers=32 DefaultMapPrefixes=(Prefix="HT",GameType="UDKGame.TheHuntGame")
What we did there was move the DefaultMapPrefixes from DefaultProperties to this .ini file, as thats where the March build put it. You will learn how to do stuff like this later on as well.
When you compile, you will get a warning about HTInventoryManager. This will fix itself when you complete step 4.
Then continue to Step 4.
Also, skip Migrating From Feb. To March. since you are now using the March build. <_<
Sorry. These were my first tutorials I’ve made and I was bound to mess up somewhere. All the future tutorials after this will go smoothly. I will try to redo these first three later when I have some spare time.
Video Version
Subject: Beginning Your Game Part 3
Skill Level: Beginner
Run-Time: 16 Minutes
Author: Michael Allar
Notes: The project I’m working on as I’m creating this documentation requires the classes we’ve made to be based off higher level classes. These were the changes made.
Download: Low-Res (32MB) Hi-Res (72MB)
Written Version
Subject: Beginning Your Game Part 3
Skill Level: Beginner
Author: Michael Allar
Notes: The project I’m working on as I’m creating this documentation requires the classes we’ve made to be based off higher level classes. These were the changes made.
In order to make these changes, you must be using the February build or later of UDK.
Why Is There A Part 3?
I am the Lead Programmer for a student ran project at The Art Institute of Orange County called The Hunt. It is a standalone game using Unreal Engine 3 being developed with the Unreal Development Kit. I am creating these tutorials as I progress in development of The Hunt and we’ve recently had a need to base our code off of higher level classes within the engine. Our goal is to stay away from as much UT code as possible without rewriting too much of everything. Instead of extending UTGame, UTPlayerController, and UTPawn, we will be extending GameInfo, UDKPlayerController, and UDKPawn.
UDKGame now extends GameInfo
/*******************************************************************************
UDKGame
Creation date: 14/01/2010 13:55
Copyright (c) 2010, Michael Allar, Epic
*******************************************************************************/
class UDKGame extends GameInfo
config(UDKGame);
struct GameTypePrefix
{
var string Prefix;
var string GameType;
};
var array<GameTypePrefix> DefaultMapPrefixes;
static event class<GameInfo> SetGameType(string MapName, string Options, string Portal)
{
local string ThisMapPrefix;
local int i,pos;
local class<GameInfo> NewGameType;
if (Left(MapName, 10) ~= "HTFrontEnd")
{
return class'UDKGame';
}
// strip the UEDPIE_ from the filename, if it exists (meaning this is a Play in Editor game)
if (Left(MapName, 6) ~= "UEDPIE")
{
MapName = Right(MapName, Len(MapName) - 6);
}
else if ( Left(MapName, 5) ~= "UEDPC" )
{
MapName = Right(MapName, Len(MapName) - 5);
}
else if (Left(MapName, 6) ~= "UEDPS3")
{
MapName = Right(MapName, Len(MapName) - 6);
}
else if (Left(MapName, 6) ~= "UED360")
{
MapName = Right(MapName, Len(MapName) - 6);
}
// replace self with appropriate gametype if no game specified
pos = InStr(MapName,"-");
ThisMapPrefix = left(MapName,pos);
// change game type
for ( i=0; i<Default.DefaultMapPrefixes.Length; i++ )
{
if ( Default.DefaultMapPrefixes[i].Prefix ~= ThisMapPrefix )
{
NewGameType = class<GameInfo>(DynamicLoadObject(Default.DefaultMapPrefixes[i].GameType,class'Class'));
if ( NewGameType != None )
{
return NewGameType;
}
}
}
return class'UDKGame';
}
defaultproperties
{
DefaultPawnClass=class'UDKGame.HTPawn'
PlayerControllerClass=class'UDKGame.HTPlayerController'
DefaultMapPrefixes(0)=(Prefix="HT",GameType="UDKGame.TheHuntGame")
}
struct GameTypePrefix
{
var string Prefix;
var string GameType;
};
var array<GameTypePrefix> DefaultMapPrefixes;
static event class<GameInfo> SetGameType(string MapName, string Options, string Portal)
{
local string ThisMapPrefix;
local int i,pos;
local class<GameInfo> NewGameType;
if (Left(MapName, 10) ~= "HTFrontEnd")
{
return class'UDKGame';
}
// strip the UEDPIE_ from the filename, if it exists (meaning this is a Play in Editor game)
if (Left(MapName, 6) ~= "UEDPIE")
{
MapName = Right(MapName, Len(MapName) - 6);
}
else if ( Left(MapName, 5) ~= "UEDPC" )
{
MapName = Right(MapName, Len(MapName) - 5);
}
else if (Left(MapName, 6) ~= "UEDPS3")
{
MapName = Right(MapName, Len(MapName) - 6);
}
else if (Left(MapName, 6) ~= "UED360")
{
MapName = Right(MapName, Len(MapName) - 6);
}
// replace self with appropriate gametype if no game specified pos = InStr(MapName,"-"); ThisMapPrefix = left(MapName,pos);
// change game type
for ( i=0; i<Default.DefaultMapPrefixes.Length; i++ )
{
if ( Default.DefaultMapPrefixes[i].Prefix ~= ThisMapPrefix )
{
NewGameType = class<GameInfo>(DynamicLoadObject(Default.DefaultMapPrefixes[i].GameType,class'Class'));
if ( NewGameType != None )
{
return NewGameType;
}
}
}
return class'UDKGame'; }
defaultproperties
{
DefaultPawnClass=class'UDKGame.HTPawn'
PlayerControllerClass=class'UDKGame.HTPlayerController'
DefaultMapPrefixes(0)=(Prefix="HT",GameType="UDKGame.TheHuntGame")
}
{var string Prefix;var string GameType;};
HTPawn now extends UDKPawn
HTPawn now has a defaultproperties block identical to UTPawn, with the UTPawn specific properties removed. It is really long so here is a link to the script instead.
HTPlayerController now extends UDKPlayerController
/*******************************************************************************
HTPlayerController
Creation date: 14/01/2010 14:31
Copyright (c) 2010, Michael Allar
*******************************************************************************/
class HTPlayerController extends UDKPlayerController
config(UDKGame);
TheHuntGame is a second GameInfo class that extends UDKGame
So that we can use UDKGame as a generic GameInfo class for things like front-ends while having the majority of our game code in a subclass of it.
/*******************************************************************************
TheHuntGame
Creation date: 19/01/2010 22:24
Copyright (c) 2010, Michael Allar
*******************************************************************************/
class TheHuntGame extends UDKGame;
var array< class<Inventory> > DefaultInventory;
event PlayerController Login(string Portal, string Options, const UniqueNetID UniqueID, out string ErrorMessage)
{
local PlayerController PC;
PC = super.Login(Portal, Options, UniqueID, ErrorMessage);
ChangeName(PC, "New Player", true);
return PC;
}
function AddDefaultInventory( pawn PlayerPawn )
{
local int i;
for (i=0; i<DefaultInventory.Length; i++)
{
// Ensure we don't give duplicate items
if (PlayerPawn.FindInventoryType( DefaultInventory[i] ) == None)
{
// Only activate the first weapon
PlayerPawn.CreateInventory(DefaultInventory[i], (i > 0));
}
}
PlayerPawn.AddDefaultInventory();
}
defaultproperties
{
DefaultPawnClass=class'UDKGame.HTPawn'
PlayerControllerClass=class'UDKGame.HTPlayerController'
ConsolePlayerControllerClass=class'UTGame.UTConsolePlayerController'
PlayerReplicationInfoClass=class'UTGame.UTPlayerReplicationInfo'
GameReplicationInfoClass=class'UTGame.UTGameReplicationInfo'
//DefaultInventory(0)=class'UDKGame.HTWP_LittleBang'
bRestartLevel=False
bDelayedStart=False
bUseSeamlessTravel=true
}
Thats all the changes made.
Now you are ready to continue to set up your game!
March 17, 2010 - 1:19 pm
I so wish you had not done that, I was understanding what was going on up to the start of this one.
March 17, 2010 - 2:09 pm
I plan on re-doing this tutorial, many have given me similar input. However if you blindly accept the code the rest of the tutorials go way indepth and make the changes here easier to understand. I might do that tonight.
April 10, 2010 - 9:34 am
Without comments in UDKGame.uc
Line 5: Warning, ‘GameTypePrefix’ obscures ‘GameTypePrefix’ defined in base class ‘GameInfo’.
Line 10: Warning, Variable declaration: ‘DefaultMapPrefixes’ conflicts with previously defined field in ‘GameInfo’
Line 50: Error, Unknown member ‘GameTypes’ in struct ‘GameTypePrefix’
I’m still looking for typos, but can someone look for possible mistakes in our developers code
?
Btw. I’m using the March build as well
April 10, 2010 - 9:37 am
@Line 50: GameTypes possible typo to GameType
April 10, 2010 - 9:48 am
The .zip file instructed to download to fix the issues in this part of the tutorial (at the top labeled IMPORTANT) rip all the lines above because this code was then moved up to the base GameInfo class in the March build, and this tutorial was made with the Feb. build in mind.
Been too busy to recreate these beginning few tutorials, but if you can get past em, the rest of these tutorials are pretty solid.
April 10, 2010 - 10:28 am
Oh, I’m very sorry. I though it was the same as the tutorials offers.
Dudes, if you read that you know what to do
April 18, 2010 - 11:05 am
Let me make sure I got this;
You created a higher class for the game,
moved the relevant code into the new class,
removed original code from the UT class,
And in doing this- we transfer control to the new high level class, and don’t have to worry about modifying the UT classes.
Does that pretty much cover the change?
April 18, 2010 - 1:45 pm
Pretty much. Definitely need to redo this tut.
May 2, 2010 - 6:15 am
thnks for the tutorials so far (the first 2 where realy good). But after this one if i jump into the game it doesnt work properly is this normal?
May 2, 2010 - 6:19 am
PS: (no first person camera arms, cant shoot, camera overall acts weird)
May 5, 2010 - 10:02 am
As others said, it is a little hard to follow trhought this tutorial. I hope you to rewrite it ^_^
So , my doubt, am i the only getting this error Error, Unknown Property ‘DefaultMapPrefixes’ in ‘Function UDKGame.UDKGame:SetGameType’
when using the zipped scripts?
Can’t figure out what happens
May 5, 2010 - 10:30 am
Use the March build. Sorry.
May 5, 2010 - 2:49 pm
Oh thanks i thought it would work with april’s also.
May 22, 2010 - 6:02 am
I’m using the April build, all scripts compile fine and when I load the map with given prefix I can walk around like a regular pawn. Thing is in the defaultproperties block we set the crouch. double jump and pickup inventory to true, yet I can’t crouch, can’t perform the double jump nor pick up the rocket launcher. Is this a normal behaviour?
May 22, 2010 - 10:58 am
Indeed it is normal, the base Pawn class isn’t set up to crouch or use UT inventory items. To add crouching, check out PlayerController and UTPlayerController’s CheckJumpAndDuck() functions along with UTPlayerInput to implement your own ducking.
May 23, 2010 - 1:14 pm
Ok so I added this change to my APlayerController:
function CheckJumpOrDuck()
{
Super.CheckJumpOrDuck();
if(Pawn != None && (Pawn.Physics != PHYS_Falling && Pawn.bCanCrouch))
{
Pawn.ShouldCrouch(bDuck != 0);
}
}
defaultproperties
{
InputClass=class’Arilienta.APlayerInput’
}
And made a class APlayerInput:
class APlayerInput extends UDKPlayerInput within APlayerController;
var float LastDuckTime;
var bool bHoldDuck;
simulated exec function Duck()
{
if(APawn(Pawn) != None)
{
if(bHoldDuck)
{
bHoldDuck = false;
bDuck = 0;
return;
}
bDuck = 1;
if(WorldInfo.TimeSeconds – LastDuckTime < DoubleClickTime)
{
bHoldDuck = true;
}
LastDuckTime = WorldInfo.TimeSeconds;
}
}
simulated exec function UnDuck()
{
if(!bHoldDuck)
{
bDuck = 0;
}
}
So crouching works fine, but instead of interpolating the camera height it just "pops out". I looked through UTPawn, UTPlayerController and UTPlayerInput but i didn't found anything related to this. Do you have any idea how to make the interpolation just like the UTPawn has?
May 24, 2010 - 2:29 am
Hmmm, this is something I have not looked into. You might have to do this with some custom logic in your Pawn’s CalcCamera function.
May 23, 2010 - 4:06 am
I am also using the April build, but I get the colliding noclip/spectator pawn on both HTGame and TheHuntGame (Files from ZIP).
I have re-named the files, classes and all references of HT to the names I use, but I still spectate, unless I make HTGame extend from UTGame, but that makes this pointless
May 23, 2010 - 4:35 am
Update:
Fixed the above problem. Simply had to add:
+DefaultMapPrefixes=(Prefix=”HT”,bUsesCommonPackage=FALSE,GameType=”UDKGame.TheHuntGame”)
to DefaultGame.ini and comment out the corresponding line in the code you gave us in the UDKGame class. UDK from April doesn’t seem to like defining default game types in hard code :/
Also, I had to copy a test map and stick a HT- infront of it, but that was just me.
May 23, 2010 - 5:43 am
A small note:
For those of you who are getting incorrectly lit weapon models (ie, They are completely black no-matter how well lit the world is), simply replace:
Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment
bSynthesizeSHLight=TRUE
End Object
in HTPawn with:
Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment
bSynthesizeSHLight=TRUE
bIsCharacterLightEnvironment=TRUE
End Object
Components.Add(MyLightEnvironment)
LightEnvironment=MyLightEnvironment
Done!
May 23, 2010 - 12:12 pm
Didn’t see the ‘Fixing Character lighting’ chapter. Ignore the above.