<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Allar's AWESOME Blog</title>
	
	<link>http://forecourse.com</link>
	<description>Life as an unresolved external symbol.</description>
	<lastBuildDate>Wed, 10 Mar 2010 15:07:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/AllarsAwesomeBlog" /><feedburner:info uri="allarsawesomeblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>HTHUD: Part 1 – Building The Base Class + Displaying Ammo</title>
		<link>http://feedproxy.google.com/~r/AllarsAwesomeBlog/~3/I_aTdtHbV_8/</link>
		<comments>http://forecourse.com/2010/03/hthud-part-1-building-the-base-class-displaying-ammo/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 15:00:44 +0000</pubDate>
		<dc:creator>Allar</dc:creator>
				<category><![CDATA[Unreal]]></category>
		<category><![CDATA[ammo]]></category>
		<category><![CDATA[display]]></category>
		<category><![CDATA[draw]]></category>
		<category><![CDATA[HTHUD]]></category>
		<category><![CDATA[HTWeapon]]></category>
		<category><![CDATA[HUD]]></category>
		<category><![CDATA[m16]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[udk]]></category>
		<category><![CDATA[weapons]]></category>

		<guid isPermaLink="false">http://forecourse.com/?p=308</guid>
		<description><![CDATA[






Video Version
Subject: HTHUD: Part 1 &#8211; Building The Base Class + Displaying Ammo
Skill Level: Beginner
Run-Time: 1 Hour and 30 Minutes
Author: Michael Allar
Notes: Creating a new HUD class and having it display our current weapons ammo.
Streaming:     720×480 1920×1080
Download:     Low-Res   (236MB) Hi-Res (337MB)
Written Version
Subject: HTHUD: Part 1 &#8211; Building The Base Class + Displaying Ammo
Skill [...]]]></description>
			<content:encoded><![CDATA[<p><!--CusAds1--><br />
<h2>Video Version</h2>
<p>Subject: HTHUD: Part 1 &#8211; Building The Base Class + Displaying Ammo<br />
Skill Level: Beginner<br />
Run-Time: 1 Hour and 30 Minutes<br />
Author: Michael Allar<br />
Notes: Creating a new HUD class and having it display our current weapons ammo.</p>
<p>Streaming:     <a href="http://www.forecourse.com/unreal/UDKHTHUDPart1720/UDKHTHUDPart1UDKHTHUDPart1720.html" class="broken_link" >720×480</a> <a href="http://www.forecourse.com/unreal/UDKHTHUDPart1/UDKHTHUDPart1.html" target="_blank">1920×1080</a></p>
<p>Download:     <a href="http://www.forecourse.com/unreal/UDKBuildingHTWeaponPart1720/UDKBuildingHTWeaponPart1720.mp4">Low-Res   (236MB)</a> <a href="http://www.forecourse.com/unreal/UDKHTHUDPart1/UDKHTHUDPart1.mp4" target="_blank">Hi-Res (337MB)</a></p>
<h2>Written Version</h2>
<p>Subject: HTHUD: Part 1 &#8211; Building The Base Class + Displaying Ammo<br />
Skill Level: Beginner<br />
Author: Michael Allar<br />
Notes: Creating a new HUD class and having it display our current weapons ammo.</p>
<p>See video for an in-depth explanation. Sorry about the indentation,  it seems like my indentation will not survive copy paste… D: I will create a written tutorial soon.</p>
<p><span id="more-308"></span></p>
<h3>HTHUD</h3>
<pre class="brush: csharp;">/*******************************************************************************
 HTHUD

 Creation date: 09/03/2010 05:04
 Copyright (c) 2010, Allar

*******************************************************************************/

class HTHUD extends UDKHUD;

/** The Pawn that is currently owning this hud */
var Pawn PawnOwner;

/** Points to the UT Pawn.  Will be resolved if in a vehicle */
var HTPawn HTPawnOwner;

/** Cached reference to the another hud texture */
var const Texture2D HudTexture;

var linearcolor HudTint;

var bool bShowAmmo;
var vector2d AmmoPosition;
var TextureCoordinates AmmoBGCoords;

/** Resolution dependent HUD scaling factor */
var float HUDScaleX, HUDScaleY;
/** Holds the scaling factor given the current resolution.  This is calculated in PostRender() */
var float ResolutionScale, ResolutionScaleX;

/** The percentage of the view that should be considered safe */
var float SafeRegionPct;
/** Holds the full width and height of the viewport */
var float FullWidth, FullHeight;

/**
 * Perform any value precaching, and set up various safe regions
 *
 * NOTE: NO DRAWING should ever occur in PostRender.  Put all drawing code in DrawHud().
 */
event PostRender()
{
 PawnOwner = Pawn(PlayerOwner.ViewTarget);
 if ( PawnOwner == None )
 {
 PawnOwner = PlayerOwner.Pawn;
 }

 HTPawnOwner = HTPawn(PawnOwner);

 // draw any debug text in real-time
 PlayerOwner.DrawDebugTextList(Canvas,RenderDelta);

 HUDScaleX = Canvas.ClipX/1280;
 HUDScaleY = Canvas.ClipX/1280;

 ResolutionScaleX = Canvas.ClipX/1024;
 ResolutionScale = Canvas.ClipY/768;

 FullWidth = Canvas.ClipX;
 FullHeight = Canvas.ClipY;

 if ( bShowHud )
 {
 DrawHud();
 }

 // let iphone draw any always present overlays
 DrawInputOverlays();
}

/**
 * This is the main drawing pump.  It will determine which hud we need to draw (Game or PostGame).  Any drawing that should occur
 * regardless of the game state should go here.
 */
function DrawHUD()
{
 local float x,y,w,h;

 // Create the safe region
 w = FullWidth * SafeRegionPct;
 X = Canvas.OrgX + (Canvas.ClipX - w) * 0.5;

 // We have some extra logic for figuring out how things should be displayed
 // in split screen.

 h = FullHeight * SafeRegionPct;

 Y = Canvas.OrgY + (Canvas.ClipY - h) * 0.5;

 Canvas.OrgX = X;
 Canvas.OrgY = Y;
 Canvas.ClipX = w;
 Canvas.ClipY = h;
 Canvas.Reset(true);

 // Set up delta time
 RenderDelta = WorldInfo.TimeSeconds - LastHUDRenderTime;
 LastHUDRenderTime = WorldInfo.TimeSeconds;

 PlayerOwner.DrawHud( Self );
 if (bShowGameHUD)
 {
 DrawGameHud();
 }
}

function DrawGameHud()
{
 DrawLivingHud();
}

/**
 * Anything drawn in this function will be displayed ONLY when the player is living.
 */
function DrawLivingHud()
{
 local HTWeapon Weapon;

 // Manage the weapon.  NOTE: Vehicle weapons are managed by the vehicle
 // since they are integrated in to the vehicle health bar
 if( PawnOwner != none )
 {
 if ( bShowAmmo )
 {
 Weapon = HTWeapon(PawnOwner.Weapon);
 if ( Weapon != none )
 {
 DisplayAmmo(Weapon);
 }
 }
 }
}

function DisplayAmmo(HTWeapon Weapon)
{
 local vector2d POS;
 local string Amount;
 local int AmmoCount;

 // Resolve the position
 POS = ResolveHudPosition(AmmoPosition,AmmoBGCoords.UL,AmmoBGCoords.VL);

 // Figure out if we should be pulsing
 AmmoCount = Weapon.GetAmmoCount();

 // Draw the background
 Canvas.SetPos(POS.X,POS.Y);// - (AmmoBarOffsetY * ResolutionScale));
 Canvas.DrawColorizedTile(HudTexture, AmmoBGCoords.UL * ResolutionScale, AmmoBGCoords.VL * ResolutionScale, AmmoBGCoords.U, AmmoBGCoords.V, AmmoBGCoords.UL, AmmoBGCoords.VL, HudTint);

 // Draw the amount
 Amount = &quot;&quot;$AmmoCount;
 Canvas.DrawColor = WhiteColor;
 Canvas.DrawText(Amount,,3.0f,3.0f);
}

/**
 * Given a default screen position (at 1024x768) this will return the hud position at the current resolution.
 * NOTE: If the default position value is &lt; 0.0f then it will attempt to place the right/bottom face of
 * the &quot;widget&quot; at that offset from the ClipX/Y.
 *
 * @Param Position        The default position (in 1024x768 space)
 * @Param Width            How wide is this &quot;widget&quot; at 1024x768
 * @Param Height        How tall is this &quot;widget&quot; at 1024x768
 *
 * @returns the hud position
 */
function Vector2D ResolveHUDPosition(vector2D Position, float Width, float Height)
{
 local vector2D FinalPos;
 FinalPos.X = (Position.X &lt; 0) ? Canvas.ClipX - (Position.X * ResolutionScale) - (Width * ResolutionScale)  : Position.X * ResolutionScale;
 FinalPos.Y = (Position.Y &lt; 0) ? Canvas.ClipY - (Position.Y * ResolutionScale) - (Height * ResolutionScale) : Position.Y * ResolutionScale;

 return FinalPos;
}

defaultproperties
{
 HudTexture=Texture2D'HTUI.Textures.T_UI_HUD_BaseA'

 HudTint=(R=1.0f,G=1.0f,B=1.0f,A=1.0f)

 AmmoPosition=(X=0,Y=-1)
 AmmoBGCoords=(U=0,UL=76,V=0,VL=126)

 SafeRegionPct = 1.0f

 bShowAmmo=true
}</pre>
<h3>UDKGame</h3>
<p>Update your defaultproperties as shown:</p>
<pre class="brush: csharp;">defaultproperties
{
 DefaultPawnClass=class'UDKGame.HTPawn'
 PlayerControllerClass=class'UDKGame.HTPlayerController'
 HUDType=class'UDKGame.HTHUD'

 DefaultMapPrefixes(0)=(Prefix=&quot;HT&quot;,GameType=&quot;UDKGame.TheHuntGame&quot;)
}</pre>
<h3>T_UI_HUD_BaseA.psd</h3>
<p>Compressed into a .zip file.</p>
<p><a href="http://www.forecourse.com/unreal/T_UI_HUD_BaseA.zip" target="_blank">T_UI_HUD_BaseA.zip</a></p>
<div style="font-size:0px;height:0px;line-height:0px;margin:0;padding:0;clear:both"></div>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fforecourse.com%2F2010%2F03%2Fhthud-part-1-building-the-base-class-displaying-ammo%2F&amp;linkname=HTHUD%3A%20Part%201%20%26%238211%3B%20Building%20The%20Base%20Class%20%2B%20Displaying%20Ammo">Share/Save</a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/AZxMQ6B1citb_CKk-q1Lw2rT5NA/0/da"><img src="http://feedads.g.doubleclick.net/~a/AZxMQ6B1citb_CKk-q1Lw2rT5NA/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/AZxMQ6B1citb_CKk-q1Lw2rT5NA/1/da"><img src="http://feedads.g.doubleclick.net/~a/AZxMQ6B1citb_CKk-q1Lw2rT5NA/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/AllarsAwesomeBlog/~4/I_aTdtHbV_8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://forecourse.com/2010/03/hthud-part-1-building-the-base-class-displaying-ammo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.forecourse.com/unreal/UDKBuildingHTWeaponPart1720/UDKBuildingHTWeaponPart1720.mp4" length="109607532" type="video/mpeg" />
<enclosure url="http://www.forecourse.com/unreal/UDKHTHUDPart1/UDKHTHUDPart1.mp4" length="337266496" type="video/mpeg" />
		<feedburner:origLink>http://forecourse.com/2010/03/hthud-part-1-building-the-base-class-displaying-ammo/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</feedburner:origLink></item>
		<item>
		<title>HTWeapon: Part 1 – Adding Ammo</title>
		<link>http://feedproxy.google.com/~r/AllarsAwesomeBlog/~3/sNWDLqJy4TM/</link>
		<comments>http://forecourse.com/2010/03/htweapon-part-1-adding-ammo/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 12:14:26 +0000</pubDate>
		<dc:creator>Allar</dc:creator>
				<category><![CDATA[Unreal]]></category>
		<category><![CDATA[ammo]]></category>
		<category><![CDATA[HTWeapon]]></category>
		<category><![CDATA[m16]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[udk]]></category>
		<category><![CDATA[weapons]]></category>

		<guid isPermaLink="false">http://forecourse.com/?p=298</guid>
		<description><![CDATA[
Video Version
Subject: HTWeapon: Part 1 &#8211; Adding Ammo
Skill Level: Beginner
Run-Time: 30 minutes
Author: Michael Allar
Notes: How to implement a very basic ammo system in our custom weapon class, taking code from UTWeapon.
Streaming:     720×480 1920×1080
Download:     Low-Res  (66MB) Hi-Res (200MB)
Written Version
Subject: HTWeapon: Part 1 &#8211; Adding Ammo
Skill Level: Beginner
Author: Michael Allar
Notes: How to implement a very basic [...]]]></description>
			<content:encoded><![CDATA[<p><!--CusAds1--><br />
<h2>Video Version</h2>
<p>Subject: HTWeapon: Part 1 &#8211; Adding Ammo<br />
Skill Level: Beginner<br />
Run-Time: 30 minutes<br />
Author: Michael Allar<br />
Notes: How to implement a very basic ammo system in our custom weapon class, taking code from UTWeapon.</p>
<p>Streaming:     <a href="http://www.forecourse.com/unreal/UDKBuildingHTWeaponPart1720/UDKBuildingHTWeaponPart1720.html">720×480</a> <a href="http://www.forecourse.com/unreal/UDKBuildingHTWeaponPart1/UDKBuildingHTWeaponPart1.html" target="_blank">1920×1080</a></p>
<p>Download:     <a href="http://www.forecourse.com/unreal/UDKBuildingHTWeaponPart1720/UDKBuildingHTWeaponPart1720.mp4">Low-Res  (66MB)</a> <a href="http://www.forecourse.com/unreal/UDKBuildingHTWeaponPart1/UDKBuildingHTWeaponPart1.mp4" target="_blank">Hi-Res (200MB)</a></p>
<h2>Written Version</h2>
<p>Subject: HTWeapon: Part 1 &#8211; Adding Ammo<br />
Skill Level: Beginner<br />
Author: Michael Allar<br />
Notes: How to implement a very basic ammo system in our custom weapon  class, taking code from UTWeapon.</p>
<p>See video for an in-depth explanation. Sorry about the indentation, it seems like my indentation will not survive copy paste&#8230; D:</p>
<p><span id="more-298"></span></p>
<h3>HTWeapon</h3>
<pre class="brush: csharp;">/*******************************************************************************
 HTWeapon

 Creation date: 08/03/2010 06:21
 Copyright (c) 2010, Allar

*******************************************************************************/

class HTWeapon extends UDKWeapon;

/** Current ammo count */
var repnotify int AmmoCount;

/** Max ammo count */
var int MaxAmmoCount;

/** Holds the amount of ammo used for a given shot */
var array&lt;int&gt; ShotCost;

/** Offset from view center */
var(FirstPerson) vector    PlayerViewOffset;

replication
{
 // Server-&gt;Client properties
 if ( bNetOwner )
 AmmoCount;
}

simulated event ReplicatedEvent(name VarName)
{
 if ( VarName == 'AmmoCount' )
 {
 if ( !HasAnyAmmo() )
 {
 WeaponEmpty();
 }
 }
 else
 {
 Super.ReplicatedEvent(VarName);
 }
}

simulated function int GetAmmoCount()
{
 return AmmoCount;
}
 /*
 * Consumes some of the ammo
 */
function ConsumeAmmo( byte FireModeNum )
{
 // Subtract the Ammo
 AddAmmo(-ShotCost[FireModeNum]);
}

/**
 * This function is used to add ammo back to a weapon.  It's called from the Inventory Manager
 */
function int AddAmmo( int Amount )
{
 AmmoCount = Clamp(AmmoCount + Amount,0,MaxAmmoCount);
 return AmmoCount;
}

/**
 * Returns true if the ammo is maxed out
 */
simulated function bool AmmoMaxed(int mode)
{
 return (AmmoCount &gt;= MaxAmmoCount);
}

/**
 * This function checks to see if the weapon has any ammo available for a given fire mode.
 *
 * @param    FireModeNum        - The Fire Mode to Test For
 * @param    Amount            - [Optional] Check to see if this amount is available.  If 0 it will default to checking
 *                              for the ShotCost
 */
simulated function bool HasAmmo( byte FireModeNum, optional int Amount )
{
 if (Amount==0)
 return (AmmoCount &gt;= ShotCost[FireModeNum]);
 else
 return ( AmmoCount &gt;= Amount );
}

/**
 * returns true if this weapon has any ammo
 */
simulated function bool HasAnyAmmo()
{
 return ( ( AmmoCount &gt; 0 ) || (ShotCost[0]==0 &amp;&amp; ShotCost[1]==0) );
}

/**
 * This function retuns how much of the clip is empty.
 */
simulated function float DesireAmmo(bool bDetour)
{
 return (1.f - float(AmmoCount)/MaxAmmoCount);
}

/**
 * Returns true if the current ammo count is less than the default ammo count
 */
simulated function bool NeedAmmo()
{
 return ( AmmoCount &lt; Default.AmmoCount );
}

/**
 * Cheat Help function the loads out the weapon
 *
 * @param     bUseWeaponMax     - [Optional] If true, this function will load out the weapon
 *                              with the actual maximum, not 999
 */
simulated function Loaded(optional bool bUseWeaponMax)
{
 if (bUseWeaponMax)
 AmmoCount = MaxAmmoCount;
 else
 AmmoCount = 999;
}

/**
 * Called when the weapon runs out of ammo during firing
 */
simulated function WeaponEmpty()
{
 // If we were firing, stop
 if ( IsFiring() )
 {
 GotoState('Active');
 }

 if ( Instigator != none &amp;&amp; Instigator.IsLocallyControlled() )
 {
 Instigator.InvManager.SwitchToBestWeapon( true );
 }
}

/*********************************************************************************************
 * Ammunition / Inventory
 *********************************************************************************************/

function PrintScreenDebug(string debugText)
{
 local PlayerController PC;
 PC = PlayerController(Pawn(Owner).Controller);
 if (PC != None)
 PC.ClientMessage(&quot;HTWeapon: &quot; $ debugText);
}

simulated function AttachWeaponTo( SkeletalMeshComponent MeshCpnt, optional Name SocketName )
{
 local HTPawn HTP;

 HTP = HTPawn(Instigator);
 PrintScreenDebug(&quot;Attaching Weapon&quot;);
 // Attach 1st Person Muzzle Flashes, etc,
 if ( Instigator.IsFirstPerson() )
 {
 AttachComponent(Mesh);
 EnsureWeaponOverlayComponentLast();
 SetHidden(False);
 Mesh.SetLightEnvironment(HTP.LightEnvironment);
 PrintScreenDebug(&quot;First Person Weapon Attached&quot;);
 }
 else
 {
 SetHidden(True);
 if (HTP != None)
 {
 Mesh.SetLightEnvironment(HTP.LightEnvironment);
 }
 }
 //SetSkin(HTPawn(Instigator).ReplicatedBodyMaterial);
}

simulated event SetPosition(UDKPawn Holder)
{
 local vector DrawOffset, ViewOffset, FinalLocation;
 local rotator NewRotation, FinalRotation, SpecRotation;
 local PlayerController PC;
 local vector2D ViewportSize;
 local bool bIsWideScreen;
 local vector SpecViewLoc;

 if ( !Holder.IsFirstPerson() )
 return;

 Mesh.SetHidden(False);

 foreach LocalPlayerControllers(class'PlayerController', PC)
 {
 LocalPlayer(PC.Player).ViewportClient.GetViewportSize(ViewportSize);
 break;
 }
 bIsWideScreen = (ViewportSize.Y &gt; 0.f) &amp;&amp; (ViewportSize.X/ViewportSize.Y &gt; 1.7);

 Mesh.SetScale3D(default.Mesh.Scale3D);
 Mesh.SetRotation(default.Mesh.Rotation);

 ViewOffset = PlayerViewOffset;

 // Calculate the draw offset
 if ( Holder.Controller == None )
 {

 if ( DemoRecSpectator(PC) != None )
 {
 PC.GetPlayerViewPoint(SpecViewLoc, SpecRotation);
 DrawOffset = ViewOffset &gt;&gt; SpecRotation;
 //DrawOffset += UTPawn(Holder).WeaponBob(BobDamping, JumpDamping);
 FinalLocation = SpecViewLoc + DrawOffset;
 SetLocation(FinalLocation);
 SetBase(Holder);

 // Add some rotation leading
 //SpecRotation.Yaw = LagRot(SpecRotation.Yaw &amp; 65535, LastRotation.Yaw &amp; 65535, MaxYawLag, 0);
 //SpecRotation.Pitch = LagRot(SpecRotation.Pitch &amp; 65535, LastRotation.Pitch &amp; 65535, MaxPitchLag, 1);
 //LastRotUpdate = WorldInfo.TimeSeconds;
 //LastRotation = SpecRotation;

 if ( bIsWideScreen )
 {
 //SpecRotation += WidescreenRotationOffset;
 }
 SetRotation(SpecRotation);
 return;
 }
 else
 {
 DrawOffset = (ViewOffset &gt;&gt; Holder.GetBaseAimRotation()) + HTPawn(Holder).GetEyeHeight() * vect(0,0,1);
 PrintScreenDebug(&quot;Setting DrawOffset to Holder Info&quot;);
 }
 }
 else
 {

 DrawOffset.Z = HTPawn(Holder).GetEyeHeight();
 //DrawOffset += HTPawn(Holder).WeaponBob(BobDamping, JumpDamping);

 if ( HTPlayerController(Holder.Controller) != None )
 {
 DrawOffset += HTPlayerController(Holder.Controller).ShakeOffset &gt;&gt; Holder.Controller.Rotation;
 }

 DrawOffset = DrawOffset + ( ViewOffset &gt;&gt; Holder.Controller.Rotation );
 }

 // Adjust it in the world
 FinalLocation = Holder.Location + DrawOffset;
 SetLocation(FinalLocation);
 SetBase(Holder);

 NewRotation = (Holder.Controller == None) ? Holder.GetBaseAimRotation() : Holder.Controller.Rotation;

 // Add some rotation leading
 //if (Holder.Controller != None)
 //{
 //    FinalRotation.Yaw = LagRot(NewRotation.Yaw &amp; 65535, LastRotation.Yaw &amp; 65535, MaxYawLag, 0);
 //    FinalRotation.Pitch = LagRot(NewRotation.Pitch &amp; 65535, LastRotation.Pitch &amp; 65535, MaxPitchLag, 1);
 //    FinalRotation.Roll = NewRotation.Roll;
 //}
 //else
 //{
 FinalRotation = NewRotation;
 //}
 //LastRotUpdate = WorldInfo.TimeSeconds;
 //LastRotation = NewRotation;

 if ( bIsWideScreen )
 {
 //FinalRotation += WidescreenRotationOffset;
 }
 SetRotation(FinalRotation);
}

simulated state WeaponEquipping
{
 simulated event BeginState(Name PreviousStateName)
 {
 PrintScreenDebug(&quot;Weapon Equipping&quot;);
 AttachWeaponTo(Instigator.Mesh);
 Super.BeginState(PreviousStateName);
 }
}

simulated state Active
{
 simulated event BeginState(Name PreviousStateName)
 {
 PrintScreenDebug(&quot;Active&quot;);
 Super.BeginState(PreviousStateName);
 }
}

simulated state WeaponFiring
{
 simulated event BeginState(Name PreviousStateName)
 {
 PrintScreenDebug(&quot;Firing&quot;);
 Super.BeginState(PreviousStateName);
 }

 /**
 * We override BeginFire() so that we can check for zooming and/or empty weapons
 */

 simulated function BeginFire( Byte FireModeNum )
 {
 // No Ammo, then do a quick exit.
 if( !HasAmmo(FireModeNum) )
 {
 WeaponEmpty();
 return;
 }
 Global.BeginFire(FireModeNum);
 }
}

defaultproperties
{
 Begin Object Name=FirstPersonMesh
 DepthPriorityGroup=SDPG_Foreground
 bOnlyOwnerSee=true
 bOverrideAttachmentOwnerVisibility=true
 CastShadow=false
 bAllowAmbientOcclusion=false
 End Object
 Mesh=FirstPersonMesh

 Begin Object Name=PickupMesh
 bOnlyOwnerSee=false
 CastShadow=false
 bForceDirectLightMap=true
 bCastDynamicShadow=false
 CollideActors=false
 BlockRigidBody=false
 bUseAsOccluder=false
 MaxDrawDistance=6000
 bForceRefPose=1
 bUpdateSkelWhenNotRendered=false
 bIgnoreControllersWhenNotRendered=true
 bAcceptsStaticDecals=FALSE
 bAcceptsDynamicDecals=FALSE
 bAllowAmbientOcclusion=false
 End Object
 DroppedPickupMesh=PickupMesh
 PickupFactoryMesh=PickupMesh

 MessageClass=class'UTPickupMessage'
 DroppedPickupClass=class'UTDroppedPickup'

 FiringStatesArray(0)=WeaponFiring
 FiringStatesArray(1)=WeaponFiring

 WeaponFireTypes(0)=EWFT_InstantHit
 WeaponFireTypes(1)=EWFT_InstantHit

 WeaponProjectiles(0)=none
 WeaponProjectiles(1)=none

 FireInterval(0)=+0.3
 FireInterval(1)=+0.3

 Spread(0)=0.0
 Spread(1)=0.0

 ShotCost(0)=1
 ShotCost(1)=1

 AmmoCount=5
 MaxAmmoCount=5

 InstantHitDamage(0)=0.0
 InstantHitDamage(1)=0.0
 InstantHitMomentum(0)=0.0
 InstantHitMomentum(1)=0.0
 InstantHitDamageTypes(0)=class'DamageType'
 InstantHitDamageTypes(1)=class'DamageType'
 WeaponRange=22000

 ShouldFireOnRelease(0)=0
 ShouldFireOnRelease(1)=0

 DefaultAnimSpeed=0.9

 EquipTime=+0.45
 PutDownTime=+0.33
}</pre>
<h3>HTWP_M16</h3>
<pre class="brush: csharp;">/*******************************************************************************
 HTWP_M16

 Creation date: 08/03/2010 06:48
 Copyright (c) 2010, Allar

*******************************************************************************/

class HTWP_M16 extends HTWeapon;

defaultproperties
{
 // Weapon SkeletalMesh
 Begin Object Name=FirstPersonMesh
 SkeletalMesh=SkeletalMesh'ALWP_M16.Mesh.SK_WP_M16_1P'
 AnimSets(0)=AnimSet'ALWP_M16.Anims.K_WP_M16_1P'
 Scale=1.0
 FOV=60.0
 End Object

 // Pickup staticmesh
 Begin Object Name=PickupMesh
 SkeletalMesh=SkeletalMesh'ALWP_M16.Mesh.SK_WP_M16_3P'
 End Object

 PlayerViewOffset=(X=17,Y=10.0,Z=-8.0)
}</pre>
<div style="font-size:0px;height:0px;line-height:0px;margin:0;padding:0;clear:both"></div>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fforecourse.com%2F2010%2F03%2Fhtweapon-part-1-adding-ammo%2F&amp;linkname=HTWeapon%3A%20Part%201%20%26%238211%3B%20Adding%20Ammo">Share/Save</a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/qm-YK2RStAxK9KesYAPwLbTrILU/0/da"><img src="http://feedads.g.doubleclick.net/~a/qm-YK2RStAxK9KesYAPwLbTrILU/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/qm-YK2RStAxK9KesYAPwLbTrILU/1/da"><img src="http://feedads.g.doubleclick.net/~a/qm-YK2RStAxK9KesYAPwLbTrILU/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/AllarsAwesomeBlog/~4/sNWDLqJy4TM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://forecourse.com/2010/03/htweapon-part-1-adding-ammo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.forecourse.com/unreal/UDKBuildingHTWeaponPart1720/UDKBuildingHTWeaponPart1720.mp4" length="109607532" type="video/mpeg" />
<enclosure url="http://www.forecourse.com/unreal/UDKBuildingHTWeaponPart1/UDKBuildingHTWeaponPart1.mp4" length="138843416" type="video/mpeg" />
		<feedburner:origLink>http://forecourse.com/2010/03/htweapon-part-1-adding-ammo/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</feedburner:origLink></item>
		<item>
		<title>Beginning Your Game Part 4</title>
		<link>http://feedproxy.google.com/~r/AllarsAwesomeBlog/~3/9ZMmDcSWspU/</link>
		<comments>http://forecourse.com/2010/03/beginning-your-game-part-4/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 08:53:50 +0000</pubDate>
		<dc:creator>Allar</dc:creator>
				<category><![CDATA[Unreal]]></category>
		<category><![CDATA[beginner]]></category>
		<category><![CDATA[beginning]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[empty]]></category>
		<category><![CDATA[fresh]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[GameInfo]]></category>
		<category><![CDATA[scratch]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[udk]]></category>
		<category><![CDATA[UDKGame]]></category>

		<guid isPermaLink="false">http://forecourse.com/?p=291</guid>
		<description><![CDATA[
Video Version
Subject: Beginning Your Game Part 4
Skill Level: Beginner
Run-Time: 54 Minutes
Author: Michael Allar
Notes: Setting up HTInventoryManager, HTInventory, HTWeapon
Streaming:     720×480 1920×1080
Download:     Low-Res (32MB) Hi-Res (200MB)
Written Version
Subject: Beginning Your Game Part 4
Skill Level: Beginner
Author: Michael Allar
Notes: Setting up HTInventoryManager, HTInventory, HTWeapon
See the video for an in-depth explanation.

HTInventoryManager
/*******************************************************************************

 HTInventoryManager

 Creation date: 08/03/2010 07:03

 Lots of code stolen from Epic
*******************************************************************************/

class HTInventoryManager [...]]]></description>
			<content:encoded><![CDATA[<p><!--CusAds1--><br />
<h2>Video Version</h2>
<p>Subject: Beginning Your Game Part 4<br />
Skill Level: Beginner<br />
Run-Time: 54 Minutes<br />
Author: Michael Allar<br />
Notes: Setting up HTInventoryManager, HTInventory, HTWeapon</p>
<p>Streaming:     <a href="http://www.forecourse.com/unreal/UDKBeginningYourGamePart4720/UDKBeginningYourGamePart4720.html">720×480</a> <a href="http://www.forecourse.com/unreal/UDKBeginningYourGamePart4/UDKBeginningYourGamePart4.html" target="_blank">1920×1080</a></p>
<p>Download:     <a href="http://www.forecourse.com/unreal/UDKBeginningYourGamePart4720/UDKBeginningYourGamePart4720.mp4">Low-Res (32MB)</a> <a href="http://www.forecourse.com/unreal/UDKBeginningYourGamePart4/UDKBeginningYourGamePart4.mp4" target="_blank">Hi-Res (200MB)</a></p>
<h2>Written Version</h2>
<p>Subject: Beginning Your Game Part 4<br />
Skill Level: Beginner<br />
Author: Michael Allar<br />
Notes: Setting up HTInventoryManager, HTInventory, HTWeapon</p>
<p>See the video for an in-depth explanation.</p>
<p><span id="more-291"></span></p>
<h3>HTInventoryManager</h3>
<pre class="brush: csharp;">/*******************************************************************************

 HTInventoryManager

 Creation date: 08/03/2010 07:03

 Lots of code stolen from Epic
*******************************************************************************/

class HTInventoryManager extends InventoryManager
 config(Game);

/** Holds the last weapon used */
var Weapon PreviousWeapon;

simulated function GetWeaponList(out array&lt;HTWeapon&gt; WeaponList, optional bool bNoEmpty)
{
 local HTWeapon Weap;

 ForEach InventoryActors( class'HTWeapon', Weap )
 {
 if ( !bNoEmpty || Weap.HasAnyAmmo())
 {
 WeaponList.Insert(0,1);
 WeaponList[0] = Weap;
 }
 }
}
/**
 * Accessor for the server to begin a weapon switch on the client.
 *
 * @param    DesiredWeapon        The Weapon to switch to
 */

reliable client function ClientSetCurrentWeapon(Weapon DesiredWeapon)
{
 SetPendingWeapon(DesiredWeapon);
}

simulated function Inventory CreateInventory(class&lt;Inventory&gt; NewInventoryItemClass, optional bool bDoNotActivate)
{
 if (Role==ROLE_Authority)
 {
 return Super.CreateInventory(NewInventoryItemClass, bDoNotActivate);
 }
 return none;
}
/**
 * Handle AutoSwitching to a weapon
 */
simulated function bool AddInventory( Inventory NewItem, optional bool bDoNotActivate )
{
 local bool bResult;

 if (Role == ROLE_Authority)
 {
 bResult = super.AddInventory(NewItem, bDoNotActivate);
 }
 return bResult;
}

simulated function DiscardInventory()
{
 local Vehicle V;

 if (Role == ROLE_Authority)
 {
 Super.DiscardInventory();

 V = Vehicle(Owner);
 if (V != None &amp;&amp; V.Driver != None &amp;&amp; V.Driver.InvManager != None)
 {
 V.Driver.InvManager.DiscardInventory();
 }
 }
}

simulated function RemoveFromInventory(Inventory ItemToRemove)
{
 if (Role==ROLE_Authority)
 {
 Super.RemoveFromInventory(ItemToRemove);
 }
}
/**
 * Scans the inventory looking for any of type InvClass.  If it finds it it returns it, other
 * it returns none.
 */
function Inventory HasInventoryOfClass(class&lt;Inventory&gt; InvClass)
{
 local inventory inv;

 inv = InventoryChain;
 while(inv!=none)
 {
 if (Inv.Class==InvClass)
 return Inv;

 Inv = Inv.Inventory;
 }
 return none;
}

/**
 * Store the last used weapon for later
 */
simulated function ChangedWeapon()
{
 PreviousWeapon = Instigator.Weapon;
 Super.ChangedWeapon();
}

simulated function SwitchToPreviousWeapon()
{
 if ( PreviousWeapon!=none &amp;&amp; PreviousWeapon != Pawn(Owner).Weapon )
 {
 PreviousWeapon.ClientWeaponSet(false);
 }
}

defaultproperties
{
 bMustHoldWeapon=true
 PendingFire(0)=0
 PendingFire(1)=0
}
</pre>
<h3>HTInventory</h3>
<pre class="brush: csharp;">/*******************************************************************************
 HTInventory

 Creation date: 08/03/2010 07:06
 Copyright (c) 2010, Allar

*******************************************************************************/

class HTInventory extends Inventory;</pre>
<h3>HTWeapon</h3>
<pre class="brush: csharp;">/*******************************************************************************
 HTWeapon

 Creation date: 08/03/2010 06:21
 Copyright (c) 2010, Allar

*******************************************************************************/

class HTWeapon extends UDKWeapon;

/** Current ammo count */
var repnotify int AmmoCount;

/** Max ammo count */
var int MaxAmmoCount;

/** Holds the amount of ammo used for a given shot */
var array&lt;int&gt; ShotCost;

/** Offset from view center */
var(FirstPerson) vector    PlayerViewOffset;

replication
{
 // Server-&gt;Client properties
 if ( bNetOwner )
 AmmoCount;
}

simulated event ReplicatedEvent(name VarName)
{
 if ( VarName == 'AmmoCount' )
 {
 if ( !HasAnyAmmo() )
 {
 WeaponEmpty();
 }
 }
 else
 {
 Super.ReplicatedEvent(VarName);
 }
}

simulated function int GetAmmoCount()
{
 return AmmoCount;
}
 /*
 * Consumes some of the ammo
 */
function ConsumeAmmo( byte FireModeNum )
{
 // Subtract the Ammo
 AddAmmo(-ShotCost[FireModeNum]);
}

/**
 * This function is used to add ammo back to a weapon.  It's called from the Inventory Manager
 */
function int AddAmmo( int Amount )
{
 AmmoCount = Clamp(AmmoCount + Amount,0,MaxAmmoCount);
 return AmmoCount;
}

/**
 * Returns true if the ammo is maxed out
 */
simulated function bool AmmoMaxed(int mode)
{
 return (AmmoCount &gt;= MaxAmmoCount);
}

/**
 * This function checks to see if the weapon has any ammo available for a given fire mode.
 *
 * @param    FireModeNum        - The Fire Mode to Test For
 * @param    Amount            - [Optional] Check to see if this amount is available.  If 0 it will default to checking
 *                              for the ShotCost
 */
simulated function bool HasAmmo( byte FireModeNum, optional int Amount )
{
 if (Amount==0)
 return (AmmoCount &gt;= ShotCost[FireModeNum]);
 else
 return ( AmmoCount &gt;= Amount );
}

/**
 * returns true if this weapon has any ammo
 */
simulated function bool HasAnyAmmo()
{
 return ( ( AmmoCount &gt; 0 ) || (ShotCost[0]==0 &amp;&amp; ShotCost[1]==0) );
}

/**
 * This function retuns how much of the clip is empty.
 */
simulated function float DesireAmmo(bool bDetour)
{
 return (1.f - float(AmmoCount)/MaxAmmoCount);
}

/**
 * Returns true if the current ammo count is less than the default ammo count
 */
simulated function bool NeedAmmo()
{
 return ( AmmoCount &lt; Default.AmmoCount );
}

/**
 * Cheat Help function the loads out the weapon
 *
 * @param     bUseWeaponMax     - [Optional] If true, this function will load out the weapon
 *                              with the actual maximum, not 999
 */
simulated function Loaded(optional bool bUseWeaponMax)
{
 if (bUseWeaponMax)
 AmmoCount = MaxAmmoCount;
 else
 AmmoCount = 999;
}

/**
 * Called when the weapon runs out of ammo during firing
 */
simulated function WeaponEmpty()
{
 // If we were firing, stop
 if ( IsFiring() )
 {
 GotoState('Active');
 }

 if ( Instigator != none &amp;&amp; Instigator.IsLocallyControlled() )
 {
 Instigator.InvManager.SwitchToBestWeapon( true );
 }
}

/*********************************************************************************************
 * Ammunition / Inventory
 *********************************************************************************************/

function PrintScreenDebug(string debugText)
{
 local PlayerController PC;
 PC = PlayerController(Pawn(Owner).Controller);
 if (PC != None)
 PC.ClientMessage(&quot;HTWeapon: &quot; $ debugText);
}

simulated function AttachWeaponTo( SkeletalMeshComponent MeshCpnt, optional Name SocketName )
{
 local HTPawn HTP;

 HTP = HTPawn(Instigator);
 PrintScreenDebug(&quot;Attaching Weapon&quot;);
 // Attach 1st Person Muzzle Flashes, etc,
 if ( Instigator.IsFirstPerson() )
 {
 AttachComponent(Mesh);
 EnsureWeaponOverlayComponentLast();
 SetHidden(False);
 Mesh.SetLightEnvironment(HTP.LightEnvironment);
 PrintScreenDebug(&quot;First Person Weapon Attached&quot;);
 }
 else
 {
 SetHidden(True);
 if (HTP != None)
 {
 Mesh.SetLightEnvironment(HTP.LightEnvironment);
 }
 }
 //SetSkin(HTPawn(Instigator).ReplicatedBodyMaterial);
}

simulated event SetPosition(UDKPawn Holder)
{
 local vector DrawOffset, ViewOffset, FinalLocation;
 local rotator NewRotation, FinalRotation, SpecRotation;
 local PlayerController PC;
 local vector2D ViewportSize;
 local bool bIsWideScreen;
 local vector SpecViewLoc;

 if ( !Holder.IsFirstPerson() )
 return;

 Mesh.SetHidden(False);

 foreach LocalPlayerControllers(class'PlayerController', PC)
 {
 LocalPlayer(PC.Player).ViewportClient.GetViewportSize(ViewportSize);
 break;
 }
 bIsWideScreen = (ViewportSize.Y &gt; 0.f) &amp;&amp; (ViewportSize.X/ViewportSize.Y &gt; 1.7);

 Mesh.SetScale3D(default.Mesh.Scale3D);
 Mesh.SetRotation(default.Mesh.Rotation);

 ViewOffset = PlayerViewOffset;

 // Calculate the draw offset
 if ( Holder.Controller == None )
 {

 if ( DemoRecSpectator(PC) != None )
 {
 PC.GetPlayerViewPoint(SpecViewLoc, SpecRotation);
 DrawOffset = ViewOffset &gt;&gt; SpecRotation;
 //DrawOffset += UTPawn(Holder).WeaponBob(BobDamping, JumpDamping);
 FinalLocation = SpecViewLoc + DrawOffset;
 SetLocation(FinalLocation);
 SetBase(Holder);

 // Add some rotation leading
 //SpecRotation.Yaw = LagRot(SpecRotation.Yaw &amp; 65535, LastRotation.Yaw &amp; 65535, MaxYawLag, 0);
 //SpecRotation.Pitch = LagRot(SpecRotation.Pitch &amp; 65535, LastRotation.Pitch &amp; 65535, MaxPitchLag, 1);
 //LastRotUpdate = WorldInfo.TimeSeconds;
 //LastRotation = SpecRotation;

 if ( bIsWideScreen )
 {
 //SpecRotation += WidescreenRotationOffset;
 }
 SetRotation(SpecRotation);
 return;
 }
 else
 {
 DrawOffset = (ViewOffset &gt;&gt; Holder.GetBaseAimRotation()) + HTPawn(Holder).GetEyeHeight() * vect(0,0,1);
 PrintScreenDebug(&quot;Setting DrawOffset to Holder Info&quot;);
 }
 }
 else
 {

 DrawOffset.Z = HTPawn(Holder).GetEyeHeight();
 //DrawOffset += HTPawn(Holder).WeaponBob(BobDamping, JumpDamping);

 if ( HTPlayerController(Holder.Controller) != None )
 {
 DrawOffset += HTPlayerController(Holder.Controller).ShakeOffset &gt;&gt; Holder.Controller.Rotation;
 }

 DrawOffset = DrawOffset + ( ViewOffset &gt;&gt; Holder.Controller.Rotation );
 }

 // Adjust it in the world
 FinalLocation = Holder.Location + DrawOffset;
 SetLocation(FinalLocation);
 SetBase(Holder);

 NewRotation = (Holder.Controller == None) ? Holder.GetBaseAimRotation() : Holder.Controller.Rotation;

 // Add some rotation leading
 //if (Holder.Controller != None)
 //{
 //    FinalRotation.Yaw = LagRot(NewRotation.Yaw &amp; 65535, LastRotation.Yaw &amp; 65535, MaxYawLag, 0);
 //    FinalRotation.Pitch = LagRot(NewRotation.Pitch &amp; 65535, LastRotation.Pitch &amp; 65535, MaxPitchLag, 1);
 //    FinalRotation.Roll = NewRotation.Roll;
 //}
 //else
 //{
 FinalRotation = NewRotation;
 //}
 //LastRotUpdate = WorldInfo.TimeSeconds;
 //LastRotation = NewRotation;

 if ( bIsWideScreen )
 {
 //FinalRotation += WidescreenRotationOffset;
 }
 SetRotation(FinalRotation);
}

simulated state WeaponEquipping
{
 simulated event BeginState(Name PreviousStateName)
 {
 PrintScreenDebug(&quot;Weapon Equipping&quot;);
 AttachWeaponTo(Instigator.Mesh);
 Super.BeginState(PreviousStateName);
 }
}

simulated state Active
{
 simulated event BeginState(Name PreviousStateName)
 {
 PrintScreenDebug(&quot;Active&quot;);
 Super.BeginState(PreviousStateName);
 }
}

simulated state WeaponFiring
{
 simulated event BeginState(Name PreviousStateName)
 {
 PrintScreenDebug(&quot;Firing&quot;);
 Super.BeginState(PreviousStateName);
 }

 /**
 * We override BeginFire() so that we can check for zooming and/or empty weapons
 */

 simulated function BeginFire( Byte FireModeNum )
 {
 // No Ammo, then do a quick exit.
 if( !HasAmmo(FireModeNum) )
 {
 WeaponEmpty();
 return;
 }
 Global.BeginFire(FireModeNum);
 }
}

defaultproperties
{
 Begin Object Name=FirstPersonMesh
 DepthPriorityGroup=SDPG_Foreground
 bOnlyOwnerSee=true
 bOverrideAttachmentOwnerVisibility=true
 CastShadow=false
 bAllowAmbientOcclusion=false
 End Object
 Mesh=FirstPersonMesh

 Begin Object Name=PickupMesh
 bOnlyOwnerSee=false
 CastShadow=false
 bForceDirectLightMap=true
 bCastDynamicShadow=false
 CollideActors=false
 BlockRigidBody=false
 bUseAsOccluder=false
 MaxDrawDistance=6000
 bForceRefPose=1
 bUpdateSkelWhenNotRendered=false
 bIgnoreControllersWhenNotRendered=true
 bAcceptsStaticDecals=FALSE
 bAcceptsDynamicDecals=FALSE
 bAllowAmbientOcclusion=false
 End Object
 DroppedPickupMesh=PickupMesh
 PickupFactoryMesh=PickupMesh

 MessageClass=class'UTPickupMessage'
 DroppedPickupClass=class'UTDroppedPickup'

 FiringStatesArray(0)=WeaponFiring
 FiringStatesArray(1)=WeaponFiring

 WeaponFireTypes(0)=EWFT_InstantHit
 WeaponFireTypes(1)=EWFT_InstantHit

 WeaponProjectiles(0)=none
 WeaponProjectiles(1)=none

 FireInterval(0)=+0.3
 FireInterval(1)=+0.3

 Spread(0)=0.0
 Spread(1)=0.0

 ShotCost(0)=1
 ShotCost(1)=1

 AmmoCount=5
 MaxAmmoCount=5

 InstantHitDamage(0)=0.0
 InstantHitDamage(1)=0.0
 InstantHitMomentum(0)=0.0
 InstantHitMomentum(1)=0.0
 InstantHitDamageTypes(0)=class'DamageType'
 InstantHitDamageTypes(1)=class'DamageType'
 WeaponRange=22000

 ShouldFireOnRelease(0)=0
 ShouldFireOnRelease(1)=0

 DefaultAnimSpeed=0.9

 EquipTime=+0.45
 PutDownTime=+0.33
}</pre>
<div style="font-size:0px;height:0px;line-height:0px;margin:0;padding:0;clear:both"></div>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fforecourse.com%2F2010%2F03%2Fbeginning-your-game-part-4%2F&amp;linkname=Beginning%20Your%20Game%20Part%204">Share/Save</a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/I2ESLpabiicXYwmflijj99prjDQ/0/da"><img src="http://feedads.g.doubleclick.net/~a/I2ESLpabiicXYwmflijj99prjDQ/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/I2ESLpabiicXYwmflijj99prjDQ/1/da"><img src="http://feedads.g.doubleclick.net/~a/I2ESLpabiicXYwmflijj99prjDQ/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/AllarsAwesomeBlog/~4/9ZMmDcSWspU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://forecourse.com/2010/03/beginning-your-game-part-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.forecourse.com/unreal/UDKBeginningYourGamePart4720/UDKBeginningYourGamePart4720.mp4" length="148162923" type="video/mpeg" />
<enclosure url="http://www.forecourse.com/unreal/UDKBeginningYourGamePart4/UDKBeginningYourGamePart4.mp4" length="198995753" type="video/mpeg" />
		<feedburner:origLink>http://forecourse.com/2010/03/beginning-your-game-part-4/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</feedburner:origLink></item>
		<item>
		<title>Beginning Your Game Part 3</title>
		<link>http://feedproxy.google.com/~r/AllarsAwesomeBlog/~3/5ynv4xqauco/</link>
		<comments>http://forecourse.com/2010/03/beginning-your-game-part-3/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 18:37:00 +0000</pubDate>
		<dc:creator>Allar</dc:creator>
				<category><![CDATA[Unreal]]></category>
		<category><![CDATA[beginner]]></category>
		<category><![CDATA[beginning]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[empty]]></category>
		<category><![CDATA[fresh]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[GameInfo]]></category>
		<category><![CDATA[scratch]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[udk]]></category>
		<category><![CDATA[UDKGame]]></category>

		<guid isPermaLink="false">http://forecourse.com/?p=279</guid>
		<description><![CDATA[
Video Version
Subject: Beginning Your Game Part 3
Skill Level: Beginner
Run-Time: 16 Minutes
Author: Michael Allar
Notes: The project I&#8217;m working on as I&#8217;m creating this documentation requires the classes we&#8217;ve made to be based off higher level classes. These were the changes made.
Streaming:     720×480 1920×1080
Download:     Low-Res (32MB) Hi-Res (72MB)
Written Version
Subject: Beginning Your Game Part 3
Skill Level: Beginner
Author: Michael Allar
Notes: The [...]]]></description>
			<content:encoded><![CDATA[<p><!--CusAds1--><br />
<h2>Video Version</h2>
<p>Subject: Beginning Your Game Part 3<br />
Skill Level: Beginner<br />
Run-Time: 16 Minutes<br />
Author: Michael Allar<br />
Notes: The project I&#8217;m working on as I&#8217;m creating this documentation requires the classes we&#8217;ve made to be based off higher level classes. These were the changes made.</p>
<p>Streaming:     <a href="http://www.forecourse.com/unreal/UDKBeginningYourGamePart3720/UDKBeginningYourGamePart3720.html">720×480</a> <a href="http://www.forecourse.com/unreal/UDKBeginningYourGamePart3a/UDKBeginningYourGamePart3.html" target="_blank">1920×1080</a></p>
<p>Download:     <a href="http://www.forecourse.com/unreal/UDKBeginningYourGamePart3720/UDKBeginningYourGamePart3720.mp4">Low-Res (32MB)</a> <a href="http://www.forecourse.com/unreal/UDKBeginningYourGamePart3a/UDKBeginningYourGamePart3.mp4" target="_blank">Hi-Res (72MB)</a></p>
<h2>Written Version</h2>
<p>Subject: Beginning Your Game Part 3<br />
Skill Level: Beginner<br />
Author: Michael Allar<br />
Notes: The project I&#8217;m working on as I&#8217;m creating this documentation requires the classes we&#8217;ve made to be based off higher level classes. These were the changes made.</p>
<p>In order to make these changes, you must be using the February build or later of UDK.</p>
<p><span id="more-279"></span></p>
<h4>Why Is There A Part 3?</h4>
<p>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&#8217;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.</p>
<h3>UDKGame now extends GameInfo</h3>
<pre class="brush: csharp;">/*******************************************************************************
	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&lt;GameTypePrefix&gt; DefaultMapPrefixes;

static event class&lt;GameInfo&gt; SetGameType(string MapName, string Options, string Portal)
{
	local string ThisMapPrefix;
	local int i,pos;
	local class&lt;GameInfo&gt; NewGameType;

	if (Left(MapName, 10) ~= &quot;HTFrontEnd&quot;)
	{
		return class'UDKGame';
	}

	// strip the UEDPIE_ from the filename, if it exists (meaning this is a Play in Editor game)
	if (Left(MapName, 6) ~= &quot;UEDPIE&quot;)
	{
		MapName = Right(MapName, Len(MapName) - 6);
	}
	else if ( Left(MapName, 5) ~= &quot;UEDPC&quot; )
	{
		MapName = Right(MapName, Len(MapName) - 5);
	}
	else if (Left(MapName, 6) ~= &quot;UEDPS3&quot;)
	{
		MapName = Right(MapName, Len(MapName) - 6);
	}
	else if (Left(MapName, 6) ~= &quot;UED360&quot;)
	{
		MapName = Right(MapName, Len(MapName) - 6);
	}

	// replace self with appropriate gametype if no game specified
	pos = InStr(MapName,&quot;-&quot;);
	ThisMapPrefix = left(MapName,pos);

	// change game type
	for ( i=0; i&lt;Default.DefaultMapPrefixes.Length; i++ )
	{
		if ( Default.DefaultMapPrefixes[i].Prefix ~= ThisMapPrefix )
		{
			NewGameType = class&lt;GameInfo&gt;(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=&quot;HT&quot;,GameType=&quot;UDKGame.TheHuntGame&quot;)
}
</pre>
<div>You will see that the main change here is the struct GameTypePrefix, var array&lt;GameTypePrefix&gt; DefaultMapPrefixes;, and the event  SetGameType. Because we are now basing UDKGame of of GameInfo instead of UTGame, we have to restore the map prefix functionality that is present in UTGame but is missing in GameInfo.</div>
<div>
<pre class="brush: csharp;">struct GameTypePrefix
{
     var string Prefix;
     var string GameType;
};
</pre>
</div>
<div>This declares a struct for a class that holds two strings, Prefix and GameType. A struct is essentially a set of variables in a variable or &#8220;structure&#8221;. Every instance of GameTypePrefix has a Prefix of GameType, which allows us to make an organized array of this data. This may make more sense when we see how it is used.</div>
<div>
<pre class="brush: csharp;">var array&lt;GameTypePrefix&gt; DefaultMapPrefixes;</pre>
</div>
<div>This declares an array of our struct called DefaultMapPrefixes. An array can be thought of as a collection of objects that you can add, remove, or edit the objects within. DefaultMapPrefixes will hold all of our default map prefixes for our different map names and game types. We will assign these in the default properties block at the end of the class.</div>
<div>
<pre class="brush: csharp;">static event class&lt;GameInfo&gt; SetGameType(string MapName, string Options, string Portal)
{
	local string ThisMapPrefix;
	local int i,pos;
	local class&lt;GameInfo&gt; NewGameType;

	if (Left(MapName, 10) ~= &quot;HTFrontEnd&quot;)
	{
		return class'UDKGame';
	}</pre>
</div>
<div>This is an event. Events are usually called automatically from other code when an event triggers. In this case, when the engine loads the UDKGame class it calls this event to see if we should set the game type to a different GameInfo class. It is given three strings, MapName, Options, and Portal. The only one we will use in our logic is MapName. We then have three lines of code declaring local variables. local variables are the same as variables we have been using before (var) except they only exist in the function they are declared in (also known as scope). The string ThisMapPrefix will be used to store the map prefix of the currently loaded map or MapName. &#8220;i&#8221; is used as an iterator for a for loop we will be running later, while pos is an integer that stores the location of a &#8220;-&#8221; in the map name if one exists (which we will calculate later). NewGameType is a variable of class GameInfo that we will be using to return the new GameInfo class we will switch to.</div>
<div>Our first if statement is checking to see if the first 10 characters from the left of MapName are a case-insensitive match (~=) to &#8220;HTFrontEnd&#8221;, and if so, it will return the class &#8216;UDKGame&#8217; causing the GameInfo class we are loading into to be UDKGame. Because we are already in UDKGame, no game type will be switched.</div>
<div>
<pre class="brush: csharp;">	// strip the UEDPIE_ from the filename, if it exists (meaning this is a Play in Editor game)
	if (Left(MapName, 6) ~= &quot;UEDPIE&quot;)
	{
		MapName = Right(MapName, Len(MapName) - 6);
	}
	else if ( Left(MapName, 5) ~= &quot;UEDPC&quot; )
	{
		MapName = Right(MapName, Len(MapName) - 5);
	}
	else if (Left(MapName, 6) ~= &quot;UEDPS3&quot;)
	{
		MapName = Right(MapName, Len(MapName) - 6);
	}
	else if (Left(MapName, 6) ~= &quot;UED360&quot;)
	{
		MapName = Right(MapName, Len(MapName) - 6);
	}</pre>
</div>
<div>Just as Epic&#8217;s comment states, these if statements check to see if our MapName contains a prefix that is added on automatically by the UDK Editor when we use the &#8220;Play in Editor&#8221; feature. If an editor prefix exists, we reassign MapName to be the the right most characters of the original mapname, ignoring the left-hand editor prefix.</div>
<div>
<pre class="brush: csharp;">	// replace self with appropriate gametype if no game specified
	pos = InStr(MapName,&quot;-&quot;);
	ThisMapPrefix = left(MapName,pos);</pre>
</div>
<div>This code searches our MapName for a &#8220;-&#8221; and stores the position of the first &#8220;-&#8221; character it finds into our variable &#8220;pos&#8221;. We then assign ThisMapPrefix to the left side of our MapName ending at the &#8220;-&#8221; character, causing the prefix of our map to only be stored. Example: If the MapName is HT-Hole1, it will first find the &#8220;-&#8221; character and then store 2 in pos as the &#8220;-&#8221; is character 2. (The first character of a string is always character zero). We then grab the left of the MapName from the beginning of the string up to the 2nd character (being the &#8220;-&#8221;), causing ThisMapPrefix to have &#8220;HT&#8221; assigned to it.</div>
<div>
<pre class="brush: csharp;">	// change game type
	for ( i=0; i&lt;Default.DefaultMapPrefixes.Length; i++ )
	{
		if ( Default.DefaultMapPrefixes[i].Prefix ~= ThisMapPrefix )
		{
			NewGameType = class&lt;GameInfo&gt;(DynamicLoadObject(Default.DefaultMapPrefixes[i].GameType,class'Class'));
			if ( NewGameType != None )
			{
				return NewGameType;
			}
		}
	}</pre>
</div>
<div>This is a for loop. A for loop essentially loops a code block while changing a variable every loop until a condition is no longer true. This is where our i variable comes into play (i being short for iterator). We start the loop by making i = 0, and we give the loop a condition of  i&lt;Default.DefaultMapPrefixes.Length. Default.DefaultMapPrefixes refers to our default value of DefaultMapPrefixes which we assign to in the DefaultProperties code block later on in this class. It contains all the map prefixes for our game. Default.DefaultMapPrefixes.Length is the length of the array, or how many prefixes are in DefaultMapPrefixes. Every time this for loop loops, it will continue to loop as long as our iterator is less than the number of prefixes in our array. The &#8220;i++&#8221; in our for loop tells the loop to increment i by 1 every time it loops.</div>
<div>Our if statement is checking to see if the &#8220;ith&#8221; object of DefaultMapPrefixes is a case-insensitive (~=) match to our map prefix of our map. Arrays are kind of like strings in that the first object in an array has an &#8216;index&#8217; of 0, just like the first character of a string is character 0. To access an object in an array, you suffix the array with square brackets [ ] with the index of the object inside the brackets. In this case it is i, our loop iterator. Every time we loop this code block, i is increased by one, thus moving to the next object in the array. If our array has 1 object in it, that first object has an index of 0, so our loop will loop once. After it loops once, i will be 1 which is not less than the number of objects in our array, which is 1; thus the loop will stop. If we had two objects in our array, the loop will run the code block twice with i being 0 and 1, stopping at 2; which works because the second object of an array has an index of 1 because our first object has an index of 0.</div>
<div>If it is a match, the next line of code is a bit tricky. What we are doing here is loading an object by its asset name which is stored as a string &#8220;GameType&#8221;. Our DefaultMapPrefixes is an array of the GameTypePrefix struct, so every object in the array has two strings, Prefix and GameType. We can access that string by referencing DefaultMapPrefixes[i].GameType where i is the index of the object we are comparing to in our loop. This string is the fully qualified name of a GameInfo class, such as UDKGame.UDKGame or later UDKGame.TheHuntGame. UTGame.UTDeathmatch would also work here. We load it in as a &#8220;class&#8221; instead of an instance because we are looking for the actual class of the GameInfo we want to switch to, not an instance of it. Because DynamicLoadObject returns a generic Object, we have to do whats called type-casting in order to turn it into a GameInfo class. Type-casting allows us to store an object in a variable thats designed to hold another object if the two objects are compatible. We can store a UDKGame.UDKGame in a GameInfo class because UDKGame derives from GameInfo. We can not however type-cast an Actor into GameInfo because Actor is not a sub-class of GameInfo, but instead is a parent of it. Finally, this newly loaded and type-casted object is stored in NewGameType. Even though if we load a UDKGame.UDKGame class and type cast it as a GameInfo class, it will still remain a UDKGame class with all its unique properties, but it will just be stored as a GameInfo class.</div>
<div>The second if statement checks to see if NewGameType does not equal None, which means that we successfully converted our newly loaded object into a GameInfo class. If for some reason we could not load the object or type-casting failed, NewGameType would not be assigned to anything (None) and therefore would not be a valid thing to return, as we can&#8217;t change the game mode to &#8220;None&#8221;. If NewGameType was assigned a value, we then return it, which causes the engine to set our new game type to whatever game type matched our prefix that we assigned in DefaultMapPrefixes.</div>
<div>
<pre class="brush: csharp;">	return class'UDKGame';
}</pre>
</div>
<div>This last bit of code will return &#8220;UDKGame&#8221; if our loop fails to return a new game type, causing us not to switch game modes because we are already in UDKGame. The last bracket closes the SetGameType event.</div>
<div>
<pre class="brush: csharp;">defaultproperties
{
	DefaultPawnClass=class'UDKGame.HTPawn'
	PlayerControllerClass=class'UDKGame.HTPlayerController'
	DefaultMapPrefixes(0)=(Prefix=&quot;HT&quot;,GameType=&quot;UDKGame.TheHuntGame&quot;)
}</pre>
</div>
<div>This is our defaultproperties box, which is pretty much the same as before. We assign our HT prefix with the GameType UDKGame.TheHuntGame to the first object of DefaultMapPrefixes, so that if our map has a prefix of HT it will load UDKGame.TheHuntGame instead.</div>
<p>{var string Prefix;var string GameType;};</p>
<h3>HTPawn now extends UDKPawn</h3>
<p>HTPawn now has a defaultproperties block identical to UTPawn, with the UTPawn specific properties removed. <a href="http://www.forecourse.com/unreal/HTPawn.zip" target="_blank">It is really long so here is a link to the script instead.</a></p>
<h3>HTPlayerController now extends UDKPlayerController</h3>
<pre class="brush: csharp;">/*******************************************************************************
HTPlayerController
Creation date: 14/01/2010 14:31
Copyright (c) 2010, Michael Allar
*******************************************************************************/
class HTPlayerController extends UDKPlayerController
     config(UDKGame);</pre>
<div>No added functionality here, just inherits from UDKPlayerController instead.</div>
<h3>TheHuntGame is a second GameInfo class that extends UDKGame</h3>
<p>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.</p>
<pre class="brush: csharp;">/*******************************************************************************
	TheHuntGame

	Creation date: 19/01/2010 22:24
	Copyright (c) 2010, Michael Allar

*******************************************************************************/

class TheHuntGame extends UDKGame;

var array&lt; class&lt;Inventory&gt; &gt; 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, &quot;New Player&quot;, true);
    return PC;
}

function AddDefaultInventory( pawn PlayerPawn )
{
	local int i;

	for (i=0; i&lt;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 &gt; 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

}
</pre>
<h3>Thats all the changes made.</h3>
<p>Now you are ready to continue to set up your game!</p>
<div style="font-size:0px;height:0px;line-height:0px;margin:0;padding:0;clear:both"></div>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fforecourse.com%2F2010%2F03%2Fbeginning-your-game-part-3%2F&amp;linkname=Beginning%20Your%20Game%20Part%203">Share/Save</a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/60WhQRwVCyuatdEmPTK_vRm1Dcc/0/da"><img src="http://feedads.g.doubleclick.net/~a/60WhQRwVCyuatdEmPTK_vRm1Dcc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/60WhQRwVCyuatdEmPTK_vRm1Dcc/1/da"><img src="http://feedads.g.doubleclick.net/~a/60WhQRwVCyuatdEmPTK_vRm1Dcc/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/AllarsAwesomeBlog/~4/5ynv4xqauco" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://forecourse.com/2010/03/beginning-your-game-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.forecourse.com/unreal/UDKGameInfoSmall/UDKGameInfoSmall.mp4" length="66954108" type="video/mpeg" />
<enclosure url="http://www.forecourse.com/unreal/UDKGameInfo/UDKGameInfo.mp4" length="214678112" type="video/mpeg" />
<enclosure url="http://www.forecourse.com/unreal/UDKBeginningYourGamePart3720/UDKBeginningYourGamePart3720.mp4" length="32936900" type="video/mpeg" />
<enclosure url="http://www.forecourse.com/unreal/UDKBeginningYourGamePart3a/UDKBeginningYourGamePart3.mp4" length="72166173" type="video/mpeg" />
		<feedburner:origLink>http://forecourse.com/2010/03/beginning-your-game-part-3/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</feedburner:origLink></item>
		<item>
		<title>Adding an M16: Part 2.5 – Dummy Rigging</title>
		<link>http://feedproxy.google.com/~r/AllarsAwesomeBlog/~3/TQUjTVpRPVM/</link>
		<comments>http://forecourse.com/2010/03/adding-an-m16-part-3-dummy-rigging/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 08:44:17 +0000</pubDate>
		<dc:creator>Allar</dc:creator>
				<category><![CDATA[Unreal]]></category>
		<category><![CDATA[3ds max]]></category>
		<category><![CDATA[allar]]></category>
		<category><![CDATA[m16]]></category>
		<category><![CDATA[rigging]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[udk]]></category>
		<category><![CDATA[weapons]]></category>

		<guid isPermaLink="false">http://forecourse.com/?p=270</guid>
		<description><![CDATA[
Video Version
Subject: Adding an M16: Part 2.5 – Dummy Rigging
Skill Level: Beginner
Run-Time: 10 minutes
Author: Michael Allar
Notes: Rigging a temporary M16 slug model to use for testing purposes using dummy objects.
Streaming:     720×480 1920×1080
Download:     Low-Res (17MB) Hi-Res (35MB)
Click here to continue to Part 3:  Preparing Model For Implementaton

Share/Save
]]></description>
			<content:encoded><![CDATA[<p><!--CusAds1--><br />
<h2>Video Version</h2>
<p>Subject: Adding an M16: Part 2.5 – Dummy Rigging<br />
Skill Level: Beginner<br />
Run-Time: 10 minutes<br />
Author: Michael Allar<br />
Notes: Rigging a temporary M16 slug model to use for testing purposes using dummy objects.</p>
<p>Streaming:     <a title="Dummy Rigging" href="http://www.forecourse.com/unreal/UDKM16DummyRigging720/UDKM16DummyRigging720.html" target="_blank">720×480</a> <a title="Geometry Rigging" href="http://www.forecourse.com/unreal/UDKM16DummyRigging/UDKM16DummyRigging.html" target="_blank">1920×1080</a></p>
<p>Download:     <a href="http://www.forecourse.com/unreal/UDKM16DummyRigging720/UDKM16DummyRigging720.mp4">Low-Res (17MB)</a> <a href="http://www.forecourse.com/unreal/UDKM16DummyRigging/UDKM16DummyRigging.mp4" target="_blank">Hi-Res (35MB)</a></p>
<p>Click here to continue to Part 3:  Preparing Model For Implementaton</p>
<div style="font-size:0px;height:0px;line-height:0px;margin:0;padding:0;clear:both"></div>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fforecourse.com%2F2010%2F03%2Fadding-an-m16-part-3-dummy-rigging%2F&amp;linkname=Adding%20an%20M16%3A%20Part%202.5%20%E2%80%93%20Dummy%20Rigging">Share/Save</a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/dqBDklSURsRMVoOH1n5W58uctcY/0/da"><img src="http://feedads.g.doubleclick.net/~a/dqBDklSURsRMVoOH1n5W58uctcY/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/dqBDklSURsRMVoOH1n5W58uctcY/1/da"><img src="http://feedads.g.doubleclick.net/~a/dqBDklSURsRMVoOH1n5W58uctcY/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/AllarsAwesomeBlog/~4/TQUjTVpRPVM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://forecourse.com/2010/03/adding-an-m16-part-3-dummy-rigging/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
<enclosure url="http://www.forecourse.com/unreal/UDKM16DummyRigging720/UDKM16DummyRigging720.mp4" length="17895790" type="video/mpeg" />
<enclosure url="http://www.forecourse.com/unreal/UDKM16DummyRigging/UDKM16DummyRigging.mp4" length="35885836" type="video/mpeg" />
		<feedburner:origLink>http://forecourse.com/2010/03/adding-an-m16-part-3-dummy-rigging/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</feedburner:origLink></item>
		<item>
		<title>Adding an M16: Part 2 – Geometry Rigging</title>
		<link>http://feedproxy.google.com/~r/AllarsAwesomeBlog/~3/KYlu0w2_GBs/</link>
		<comments>http://forecourse.com/2010/03/adding-an-m16-part-2-geometry-rigging/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 08:20:51 +0000</pubDate>
		<dc:creator>Allar</dc:creator>
				<category><![CDATA[Unreal]]></category>
		<category><![CDATA[3ds max]]></category>
		<category><![CDATA[allar]]></category>
		<category><![CDATA[m16]]></category>
		<category><![CDATA[rigging]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[udk]]></category>
		<category><![CDATA[weapons]]></category>

		<guid isPermaLink="false">http://forecourse.com/?p=258</guid>
		<description><![CDATA[
Important Note:
During the video, I mention that all weapons point down the Y axis. I was basing this knowledge off of the Shock Rifle, which turns out is coded to be rotated to be facing down the X axis like the Rocket Launcher. Your model can face down any axis in 3DS Max, but make [...]]]></description>
			<content:encoded><![CDATA[<p><!--CusAds1--><br />
<h2>Important Note:</h2>
<p><strong>During the video, I mention that all weapons point down the Y axis. I was basing this knowledge off of the Shock Rifle, which turns out is coded to be rotated to be facing down the X axis like the Rocket Launcher. Your model can face down any axis in 3DS Max, but make sure that after you import it that it faces down the X axis using the Rot Origin properties. You can leave it facing in the Y axis if you want, as adjusting the rotation in the weapon&#8217;s code is also really easy to do too and I will go over how to do so in the code part of this tutorial series.</strong></p>
<h2>Video Version</h2>
<p>Subject: Adding an M16: Part 2 – Geometry Rigging<br />
Skill Level: Beginner<br />
Run-Time: 21 minutes<br />
Author: Michael Allar<br />
Notes: Rigging a temporary M16 slug model to use for testing purposes.</p>
<p>Streaming:     <a title="Geometry Rigging" href="http://www.forecourse.com/unreal/UDKM16GeomRigging720/UDKM16GeomRigging720.html" target="_blank">720×480</a> <a title="Geometry Rigging" href="http://www.forecourse.com/unreal/UDKM16GeomRigging/UDKM16GeomRigging.html" target="_blank">1920×1080</a></p>
<p>Download:     <a href="http://www.forecourse.com/unreal/UDKM16GeomRigging720/UDKM16GeomRigging720.mp4">Low-Res (47MB)</a> <a href="http://www.forecourse.com/unreal/UDKM16GeomRigging/UDKM16GeomRigging.mp4" target="_blank">Hi-Res (84MB)</a></p>
<p><a href="http://forecourse.com/2010/03/adding-an-m16-part-3-dummy-rigging/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed" target="_self">Click here to continue to Part 2.5:  Dummy Rigging (Optional)</a></p>
<p>Click here to continue to Part 3:  Preparing Model For Implementation</p>
<h2>Written Version</h2>
<p>Subject: Adding an M16: Part 2 – Geometry Rigging<br />
Skill Level: Beginner<br />
Author: Michael Allar<br />
Notes: Rigging a temporary M16 slug model to use for testing purposes.<br />
Prerequisites: UDK, 3DS Max, ActorX</p>
<p><span id="more-258"></span></p>
<h3>Making Your Model To Scale (In 3DS Max)</h3>
<ol>
<li>Orientate the weapon so that it it points down the negative Y axis, with top facing positive Z. Y will be flipped when importing into UDK.</li>
<li>Place the M16 at origin so that origin is at the weapons vertical center, horizontal center, and that its shifted forward or backward so the stock on the weapon is on origin or a bit behind it. This just makes first person view positioning a bit easier.</li>
<li>Export your model as a .ASE (ASCII Scene Export)</li>
<li>Import into Unreal and drop it into a level and see how the scaling works out.</li>
<li>Go back into Max, scale, reposition, and re-export until the scaling is as desired.</li>
</ol>
<h3>Rigging Your Model Using Its Own Geometry (In 3DS Max)</h3>
<p>Skeletal meshes can be imported from 3DS Max using geometry as their bones or by using actual bones, dummy objects, etc. The advantages of using geometry to rig are it is faster to do so, and all you have to worry about is the pivot points for each piece of geometry. The downside is that each piece of geometry can only be manipulated by one bone, being itself. This part goes over how to use geometry as rigging, however there is an optional tutorial on how to rig using dummy objects in 3DS Max as well.</p>
<ol>
<li>You should have one piece of geometry that will serve as the root node of the model. In this case, I used the main body of the M16.</li>
<li>Use &#8220;Select and Link&#8221; to link objects to their parents. In this case, I only had to link my trigger to the main body.</li>
</ol>
<h3>Installing ActorX</h3>
<p>ActorX is a plugin by Epic for 3DS Max, Maya, and XSI to export skeletal meshes for use with the Unreal Engine. There is a copy of the plugin to install inside your UDK installation under Binaries\ActorX. Install the plugin for your 3d package.</p>
<ol>
<li>For 3DS Max, grab the plugin from the Max folder that corresponds to the version of 3DS Max you are using and place the .DLU file into your Max installation directory in the &#8220;stdplugins&#8221; folder.</li>
<li>Customize -&gt; Plug-in Manager&#8230;</li>
<li>Right-click anywhere in the Plug-in Manager and choose Load New Plugin&#8230;</li>
<li>Open ActorX.dlu</li>
<li>Open the ActorX UI by clicking the Utilities tab on the right (hammer) and then by clicking More&#8230; Select ActorX and then click OK.</li>
</ol>
<div id="attachment_259" class="wp-caption aligncenter" style="width: 306px"><a href="http://forecourse.com/wp-content/uploads/2010/03/MaxMoreActorX.jpg#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img class="size-medium wp-image-259" title="MaxMoreActorX" src="http://forecourse.com/wp-content/uploads/2010/03/MaxMoreActorX-296x300.jpg" alt="" width="296" height="300" /></a>
<p class="wp-caption-text">Bringing up the ActorX UI</p>
</div>
<h3>Exporting as a Skeletal Mesh (.PSK)</h3>
<ol>
<li>Choose a path and filename for your mesh.</li>
<li>Make your settings the same in the next picture:
<p style="text-align: center;">
<p><a href="http://forecourse.com/wp-content/uploads/2010/03/ActorXSettings.jpg#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img class="aligncenter size-full wp-image-260" title="ActorXSettings" src="http://forecourse.com/wp-content/uploads/2010/03/ActorXSettings.jpg" alt="" width="161" height="783" /></a></li>
<li>If you do not have your mesh textured, uncheck &#8220;all textured&#8221;.</li>
<li>Click Save mesh/refpose.</li>
</ol>
<h3>Importing Your Skeletal Mesh</h3>
<ol>
<li>Open your Content Browser</li>
<li>Import your file into a package of your choice.</li>
<li>Make sure your model is pointing down the X axis.
<ol>
<li>Open up the Skeletal Mesh Viewer by double clicking on your asset</li>
</ol>
</li>
</ol>
<p>Under the Mesh tab, adjust the Rot Origin properties until it does.</p>
<div id="attachment_261" class="wp-caption aligncenter" style="width: 310px"><a href="http://forecourse.com/wp-content/uploads/2010/03/M16Orientation.jpg#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img class="size-medium wp-image-261" title="M16Orientation" src="http://forecourse.com/wp-content/uploads/2010/03/M16Orientation-300x222.jpg" alt="" width="300" height="222" /></a>
<p class="wp-caption-text">Where to set the orientation for your model.</p>
</div>
<p><a href="http://forecourse.com/2010/03/adding-an-m16-part-3-dummy-rigging/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed" target="_self">Click here to continue to Part 2.5:  Dummy Rigging (Optional)</a></p>
<p>Click here to continue to Part 3:  Preparing Model For Implementation</p>
<div style="font-size:0px;height:0px;line-height:0px;margin:0;padding:0;clear:both"></div>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fforecourse.com%2F2010%2F03%2Fadding-an-m16-part-2-geometry-rigging%2F&amp;linkname=Adding%20an%20M16%3A%20Part%202%20%E2%80%93%20Geometry%20Rigging">Share/Save</a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/uj5J3g3K2p60JW9h3anvtLsF4IE/0/da"><img src="http://feedads.g.doubleclick.net/~a/uj5J3g3K2p60JW9h3anvtLsF4IE/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/uj5J3g3K2p60JW9h3anvtLsF4IE/1/da"><img src="http://feedads.g.doubleclick.net/~a/uj5J3g3K2p60JW9h3anvtLsF4IE/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/AllarsAwesomeBlog/~4/KYlu0w2_GBs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://forecourse.com/2010/03/adding-an-m16-part-2-geometry-rigging/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
<enclosure url="http://www.forecourse.com/unreal/UDKM16GeomRigging720/UDKM16GeomRigging720.mp4" length="47859062" type="video/mpeg" />
<enclosure url="http://www.forecourse.com/unreal/UDKM16GeomRigging/UDKM16GeomRigging.mp4" length="84682288" type="video/mpeg" />
		<feedburner:origLink>http://forecourse.com/2010/03/adding-an-m16-part-2-geometry-rigging/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</feedburner:origLink></item>
		<item>
		<title>Adding an M16: Part 1 – Modeling</title>
		<link>http://feedproxy.google.com/~r/AllarsAwesomeBlog/~3/QLvD7Q306yU/</link>
		<comments>http://forecourse.com/2010/03/adding-an-m16-part-1-modeling/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 07:21:26 +0000</pubDate>
		<dc:creator>Allar</dc:creator>
				<category><![CDATA[Unreal]]></category>
		<category><![CDATA[3ds max]]></category>
		<category><![CDATA[allar]]></category>
		<category><![CDATA[m16]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[udk]]></category>
		<category><![CDATA[weapons]]></category>

		<guid isPermaLink="false">http://forecourse.com/?p=256</guid>
		<description><![CDATA[
Video Version
Subject: Adding an M16: Part 1 &#8211; Modeling
Skill Level: Beginner
Run-Time: 21 minutes
Author: Michael Allar
Notes: A temporary M16 slug model to use for testing purposes.
Streaming:     720×480 1920×1080
Download:     Low-Res (54MB) Hi-Res (94MB)
Click here to continue to Part 2: Rigging

Share/Save
]]></description>
			<content:encoded><![CDATA[<p><!--CusAds1--><br />
<h2>Video Version</h2>
<p>Subject: Adding an M16: Part 1 &#8211; Modeling<br />
Skill Level: Beginner<br />
Run-Time: 21 minutes<br />
Author: Michael Allar<br />
Notes: A temporary M16 slug model to use for testing purposes.</p>
<p>Streaming:     <a title="Modeling an M16" href="http://www.forecourse.com/unreal/ModelingM16720/ModelingM16720.html" target="_blank">720×480</a> <a href="http://www.forecourse.com/unreal/M16Modeling/M16Modeling.html" target="_blank">1920×1080</a></p>
<p>Download:     <a href="http://www.forecourse.com/unreal/ModelingM16720/ModelingM16720.mp4">Low-Res (54MB)</a> <a href="http://www.forecourse.com/unreal/M16Modeling/M16Modeling.mp4" target="_blank">Hi-Res (94MB)</a></p>
<p><a href="http://forecourse.com/2010/03/adding-an-m16-part-2-geometry-rigging/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed" target="_self">Click here to continue to Part 2: Rigging</a></p>
<div style="font-size:0px;height:0px;line-height:0px;margin:0;padding:0;clear:both"></div>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fforecourse.com%2F2010%2F03%2Fadding-an-m16-part-1-modeling%2F&amp;linkname=Adding%20an%20M16%3A%20Part%201%20%26%238211%3B%20Modeling">Share/Save</a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/HHt_excGiwbrs_23k-bNbX6nRs0/0/da"><img src="http://feedads.g.doubleclick.net/~a/HHt_excGiwbrs_23k-bNbX6nRs0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/HHt_excGiwbrs_23k-bNbX6nRs0/1/da"><img src="http://feedads.g.doubleclick.net/~a/HHt_excGiwbrs_23k-bNbX6nRs0/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/AllarsAwesomeBlog/~4/QLvD7Q306yU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://forecourse.com/2010/03/adding-an-m16-part-1-modeling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.forecourse.com/unreal/ModelingM16720/ModelingM16720.mp4" length="54132759" type="video/mpeg" />
<enclosure url="http://www.forecourse.com/unreal/M16Modeling/M16Modeling.mp4" length="94497367" type="video/mpeg" />
		<feedburner:origLink>http://forecourse.com/2010/03/adding-an-m16-part-1-modeling/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</feedburner:origLink></item>
		<item>
		<title>Beginning Your Game Part 2</title>
		<link>http://feedproxy.google.com/~r/AllarsAwesomeBlog/~3/bPfYdwBwpog/</link>
		<comments>http://forecourse.com/2010/01/beginning-your-game-part-2/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 22:28:02 +0000</pubDate>
		<dc:creator>Allar</dc:creator>
				<category><![CDATA[Unreal]]></category>
		<category><![CDATA[beginner]]></category>
		<category><![CDATA[beginning]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[empty]]></category>
		<category><![CDATA[fresh]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[GameInfo]]></category>
		<category><![CDATA[scratch]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[udk]]></category>
		<category><![CDATA[UDKGame]]></category>

		<guid isPermaLink="false">http://forecourse.com/?p=243</guid>
		<description><![CDATA[
Video Version
Subject: Beginning Your Game Parts 1 and 2
Skill Level: Beginner
Run-Time: 1 Hour
Author: Michael Allar
Notes: This is really incredibly long but goes over how to create a blank slate for your game. Also goes somewhat in-depth on a line-by-line basis.
Streaming:     720×480 1920×1080
Download:     Low-Res (66MB) Hi-Res (200MB)
Written Version
Subject: Beginning Your Game Part 1
Skill Level: Beginner
Author: Michael [...]]]></description>
			<content:encoded><![CDATA[<p><!--CusAds1--><br />
<h2>Video Version</h2>
<p>Subject: Beginning Your Game Parts 1 and 2<br />
Skill Level: Beginner<br />
Run-Time: 1 Hour<br />
Author: Michael Allar<br />
Notes: This is really incredibly long but goes over how to create a blank slate for your game. Also goes somewhat in-depth on a line-by-line basis.</p>
<p>Streaming:     <a href="http://www.forecourse.com/unreal/UDKGameInfoSmall/UDKGameInfoSmall.html">720×480</a> <a href="http://www.forecourse.com/unreal/UDKGameInfo/UDKGameInfo.html" target="_blank">1920×1080</a></p>
<p>Download:     <a href="http://www.forecourse.com/unreal/UDKGameInfoSmall/UDKGameInfoSmall.mp4">Low-Res (66MB)</a> <a href="http://www.forecourse.com/unreal/UDKGameInfo/UDKGameInfo.mp4" target="_blank">Hi-Res (200MB)</a></p>
<h2>Written Version</h2>
<p>Subject: Beginning Your Game Part 1<br />
Skill Level: Beginner<br />
Author: Michael Allar<br />
Notes: Gets your UDK set up so that you can start coding into your own game class!</p>
<p>You will have needed to have done Beginning Your Game Part 1 if you are sticking to the written series of these tutorials. The video tutorial on both tutorials covers both parts.</p>
<h4>Why Is There A Part 2?</h4>
<p>So, we now have an empty game mode that we can now start coding into. Great! Why don&#8217;t we start going over UnrealScript and start adding our own things?</p>
<p>Well simply put, we aren&#8217;t done yet. While we have our own game mode set up now, we still are using Epic&#8217;s player logic instead of a blank slate for us to use. The way the Unreal Engine handles player interaction is pretty important to understand:</p>
<p><span id="more-243"></span></p>
<ul>
<li>All physical representations of players, creatures, NPCs, and etc are coded in subclasses of the Pawn class. The term Pawn relates to how these &#8216;actors&#8217; are essentially pushed around and have no mind of their own. The term Actor corresponds to anything the player may interact with in-world  including things they don&#8217;t know they are interacting with.</li>
<li>All controlling logic that effects the physical representations of these actors are coded in subclasses of the PlayerController class. PlayerControllers possess and control Pawns. Example: The players input is sent to the PlayerController, which is then sent to the corresponding Pawn.</li>
</ul>
<p>Right now we are using Epic&#8217;s Pawns and PlayerControllers, when we should be using our own. You can continue to use Epic&#8217;s code, but then you will only be able to create a game mode that only involves Epic&#8217;s default player designed for UTDeathmatch. The point of Part 2 of this tutorial is to create our own PlayerController and Pawn classes, along with giving our game mode a little bit more functionality. There is more explanation of this in the video version of this tutorial.</p>
<div id="attachment_244" class="wp-caption aligncenter" style="width: 218px"><a href="http://forecourse.com/wp-content/uploads/2010/01/pawn.jpg#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img class="size-full wp-image-244" title="Pawn Class" src="http://forecourse.com/wp-content/uploads/2010/01/pawn.jpg" alt="" width="208" height="82" /></a>
<p class="wp-caption-text">The Pawn class listed in the class tree of UnCodeX. Ignore the crossed out class.</p>
</div>
<div id="attachment_245" class="wp-caption aligncenter" style="width: 276px"><a href="http://forecourse.com/wp-content/uploads/2010/01/PlayerController.jpg#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img class="size-full wp-image-245" title="PlayerController Class" src="http://forecourse.com/wp-content/uploads/2010/01/PlayerController.jpg" alt="" width="266" height="240" /></a>
<p class="wp-caption-text">The PlayerController class listed in the class view of UnCodeX. Ignore the crossed out class.</p>
</div>
<p>As mentioned in Part 1, derived from these classes are GamePawn and GamePlayerController. You never want to derive from anything above a Game* class if one exists, as that will cause you to have to rewrite some engine functionality in your class. The Game* classes allow you to start with a clean slate but still giving your new subclasses the ability to be used in the engine correctly. This is where you have to make a choice similar to earlier however, whether or not you want to derive from the Game* classes or the UT* classes; deriving from the Game* classes will give you full control but deriving the UT* classes will speed up development for any type of game remotely near UT3 (read as: first person shooter). In this series, I will be deriving from the UT* classes and I -strongly- recommend you do too as well. If you chose to derive from GameInfo for your game mode you may do either here, but if you derived from UTGame then you should derive from the UT* classes here so code comparability is ensured and you know that you won&#8217;t be missing code in your subclass that the UTGame class expects it to have.</p>
<h4>Subclassing UTPlayerController</h4>
<p>We can extend this class the same way we extended GameInfo in Part 1 of this tutorial. <strong>Be sure to use your script package.</strong></p>
<div id="attachment_246" class="wp-caption aligncenter" style="width: 310px"><a href="http://forecourse.com/wp-content/uploads/2010/01/YourPlayerController.jpg#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img class="size-medium wp-image-246" title="YourPlayerController" src="http://forecourse.com/wp-content/uploads/2010/01/YourPlayerController-300x251.jpg" alt="" width="300" height="251" /></a>
<p class="wp-caption-text">Extending UTPlayerController in UnCodeX</p>
</div>
<p>In this tutorial series, I will be using HTPlayerController as HT is a suitable prefix for a project that I am working on. Please name this something that suits your project, but remember that in this series I prefix all classes I create with HT (UDKGame being an exception). If you want to do this manually without UnCodeX, the video tutorial covers how to do this.</p>
<p>This results in the code asset UDKGame.HTPlayerController, or Development\Src\UDKGame\Classes\HTPlayerController.uc. The directory structure of code packages should be clear now and I will only be referencing code classes from their packaged names here on out. The code generated should be as follows:</p>
<pre class="brush: csharp;">class HTPlayerController extends UTPlayerController;</pre>
<p>This line of code should make sense to you know, as it was covered in Part 1 and in the video version of this tutorial in-depth. Please review those sections if you do not understand this line of code.</p>
<p>Now we are going to introduce another keyword to our code, &#8220;config&#8221;. In UnrealScript, if we give a class declaration the &#8220;config&#8221; keyword, we can have the engine create a config file for us that will allow us to change some of the settings of our class in a config file rather than having to open up our code and making changes that way. During development however, you should always make changes to your script files as the config settings are generally for allowing the end user to tweak the game to their settings. To use this config keyword, manipulate the code above to become:</p>
<pre class="brush: csharp;">class HTPlayerController extends UTPlayerController
 config(UDKGame);</pre>
<p>This will allow us to make changes to our defaultproperties block of code through a config file, but we will cover this concept later. Also notice the placement of the semi-colon, it is now on the next line. The reason behind this is this code is actually one line of code, or one code instruction. Like in most languages, white-space does not matter too much so putting config on the 2nd line instead of the first is read the same way into the compiler, as long as UTPlayerController and config are seperated. Because the config keyword operates in the class declaration, the only reasoning for putting it on the next line is pure style and readability. Sometimes class declarations can have lots of keywords in it and its easier to read them line by line instead of reading them all in one line.</p>
<p>We need to create a defaultproperties code block for future use, so lets do that:</p>
<pre class="brush: csharp;">class HTPlayerController extends UTPlayerController
 config(UDKGame);

defaultproperties
{
}</pre>
<p>I will go into the power of defaultproperties when we revisit our game mode class. For now, this will serve as a blank slate for us to add code to in the future.</p>
<h4>Subclassing UTPawn</h4>
<p>This is the third class we will be extending and we will just be creating a blank slate like before, so I won&#8217;t go into too much info here.</p>
<div id="attachment_247" class="wp-caption aligncenter" style="width: 310px"><a href="http://forecourse.com/wp-content/uploads/2010/01/YourPawn.jpg#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img class="size-medium wp-image-247" title="YourPawn" src="http://forecourse.com/wp-content/uploads/2010/01/YourPawn-300x251.jpg" alt="" width="300" height="251" /></a>
<p class="wp-caption-text">Extending UTPawn in UnCodeX</p>
</div>
<p>I will be naming my Pawn class HTPawn. Here is the blank slate code HTPawn will consist of:</p>
<pre class="brush: csharp;">class HTPawn extends UTPawn
notplaceable;

defaultproperties
{
}</pre>
<p>If you look at this code closely, you will see that I am not going to allow the HTPawn to be manipulated through a config file just yet, but also I have introduced a new keyword: notplaceable. The notplaceable keyword tells the Unreal Editor that this class can not be placed in-world, because we don&#8217;t want it to be. Pawns are reserved for being only physical representations of players, AI, and etc. If you were to place a Pawn in a level, it will not have a PlayerController, any settings correctly configured, and will simply just not work. Pawns should be created either through code or through a factory class of some kind, which we will get into later. Currently Pawns are created by the UTGame class when the game mode decides it is time for a player to spawn.</p>
<h4>Getting our GameInfo Class To Use Our PlayerController and Pawn</h4>
<p>Now that we have empty slates for our PlayerController and Pawn, we need to get our game mode to use them! This is where we finally work with the defaultproperties class.</p>
<p>Every class in UnrealScript allows the use of a defaultproperties code block, which assigns variables values, inherits and overrides values of previous classes, and allows for manipulation of a class programatically through a certain extent. One example we have already encountered with this is the bGivePhysicsGun=true line in UTGame, which is overridden in UTDeathmatch by bGivePhysicsGun=false. The defaultproperties block is essentially a config file, which is why the defaultproperties block also does not have semi-colons to terminate each variable assignment. When you use the config keyword in a class declaration, you are giving access to this code block through a config file outside of the code. We will go over how config files work more in a later tutorial. The brilliance of the defaultproperties code block is that it allows easy changes to the behavior of inherited classes. I often recommend reading through the defaultproperties code block of a class you are reading for the first time first as it can give you an idea of what it does and what you can change just by the variables it exposes.</p>
<p>When you want to modify the default properties of a class, you can either change it in the class itself (only for classes you create yourself) or if you need to change an Epic class, you should extend it within your package and then modify the variables you need to there. This is what we are doing with our custom game info class. Right now our game info class looks like this:</p>
<pre class="brush: csharp;">class UDKGame extends UTGame;</pre>
<p>I am however going to add a little functionality to this so that it now reads:</p>
<pre class="brush: csharp;">class UDKGame extends UTGame
 config(UDKGame);

defaultproperties
{
}</pre>
<p>You should already understand the changes I have made here.</p>
<p>Now to tell our game info class to use our PlayerController and Pawn, if you examine the defaultproperties block of what we derived from (UTGame.UTGame) you will see the following:</p>
<pre class="brush: csharp; first-line: 3591;">defaultproperties
{
 HUDType=class'UTGame.UTHUD'
 PlayerControllerClass=class'UTGame.UTPlayerController'
 ConsolePlayerControllerClass=class'UTGame.UTConsolePlayerController'
 DefaultPawnClass=class'UTPawn'
 PlayerReplicationInfoClass=class'UTGame.UTPlayerReplicationInfo'
 GameReplicationInfoClass=class'UTGame.UTGameReplicationInfo'
 DeathMessageClass=class'UTDeathMessage'
 BotClass=class'UTBot'

//And a lot more stuff in here....

}</pre>
<p>Looking at the defaultproperties box of UTGame, you will see that there are some things that interest us. Those are lines are 3594 and 3596. 3954 reads PlayerControllerClass=class&#8217;UTGame.UTPlayerController&#8217;. The variable PlayerControllerClass holds a reference to a class that tells the game mode what PlayerController to use as the game modes PlayerController. It is then followed by the &#8220;class&#8221; operator. This allows us to say &#8220;Use this class&#8221; instead of &#8220;Use an instance of this class&#8221;. This will make sense later when we deal with code assets vs. content assets in later tutorials, but we want all the PlayerControllers to be of HTPlayerController (or what you named your controller), not to all be the same instance of one HTPlayerController. Now within the quotes of the class operator, we feed it what class to use by giving it our code asset&#8217;s fully qualified name. The fully qualified name of my PlayerController is UDKGame.HTPlayerController. This goes for DefaultPawnClass as well. DefaultPawnClass here does not use the fully qualified name here but just the class name; and while it will work in Epic&#8217;s case it will not work in our case due to our code asset not being of the same scope. We will also talk more about scope later in a future tutorial. It is best to always use the fully qualified name anyways so that no one will be confused as to where your class lies if they were to read your code.</p>
<p>Now that we know what variables we want to change, lets change them! You can do that by making your game info class read:</p>
<pre class="brush: csharp;">class UDKGame extends UTGame
 config(UDKGame);

defaultproperties
{
 DefaultPawnClass=class'UDKGame.HTPawn'
 PlayerControllerClass=class'UDKGame.HTPlayerController'
}</pre>
<p>Our game info class will now use our new Pawn and PlayerController classes! Whoooo!</p>
<p>You should be able to save your code, compile, and run your game. It will still load your game mode, but because our Pawn and PlayerController classes add no functionality, it will appear to function exactly the same because it technically is exactly the same! We just have some where to put our future code now.</p>
<h4>Associating Our Game Mode With A Map Prefix</h4>
<p>You may recall from earlier that if you load a DM- map it loads a Deathmatch game, a CTF- loads a Capture The Flag and a VCTF- prefixed map loads a Vehicle Capture The Flag game. How was this accomplished?</p>
<p>Once again, this magic is done in the defaultproperties code block of our game info class. If we dig back into the original defaultproperties box of UTGame:</p>
<pre class="brush: csharp; first-line: 3621;">DefaultMapPrefixes(0)=(Prefix=&quot;DM&quot;,GameType=&quot;UTGame.UTDeathmatch&quot;)
 DefaultMapPrefixes(1)=(Prefix=&quot;CTF&quot;,GameType=&quot;UTGameContent.UTCTFGame_Content&quot;)
 DefaultMapPrefixes(3)=(Prefix=&quot;VCTF&quot;,GameType=&quot;UTGameContent.UTVehicleCTFGame_Content&quot;)</pre>
<p>Lines 3621 through 3623 fill in an array of variables that the GameInfo class uses to load a new game mode depending on the prefix of the map that was loaded. This lays it out pretty clear, DM loads UTGame.UTDeathmatch, CTF loads UTGameContent.UTCTFGame_Content, etc. In order for our map prefixes to load the correct game modes, we just have to override this in our game info class! While you may not understand everything going on in these lines, it is pretty obvious what we can change to get what we want.</p>
<pre class="brush: csharp;">DefaultMapPrefixes(0)=(Prefix=&quot;HT&quot;,GameType=&quot;UDKGame.UDKGame&quot;)</pre>
<p>In our game info class, we can add that line above to our default properties box to associate any map with the prefix with the HT prefix to use the GameInfo class UDKGame.UDKGame. Your names may be different but should match what you have done previously. If you have multiple game modes, you can set up the map prefixing logic here by adding a new map prefix data set by changing the 0 in DefaultMapPrefixes(0) to (1) just like in UTGame, and continue to 2, 3, 4, etc. We will go over arrays in a later UnrealScript tutorial.</p>
<p>Our code should now look like this:</p>
<pre class="brush: csharp;">class UDKGame extends UTGame
 config(UDKGame);

defaultproperties
{
 DefaultMapPrefixes(0)=(Prefix=&quot;HT&quot;,GameType=&quot;UDKGame.UDKGame&quot;)
 DefaultPawnClass=class'UDKGame.HTPawn'
 PlayerControllerClass=class'UDKGame.HTPlayerController'
}</pre>
<p>The UDKGame GameInfo class is the topmost GameInfo class in my project, and should be in yours too; therefore it has to be aware of all other GameInfo classes. This is why UTGame has prefix logic for DM, CTF, and VCTF. If we look in UTDeathmatch however, you&#8217;ll see this is handled a little differently:</p>
<pre class="brush: csharp; first-line: 107;">Acronym=&quot;DM&quot;
 MapPrefixes[0]=&quot;DM&quot;</pre>
<p>The UTDeathmatch class is not going to transition into any other game modes, it will only transition back to the topmost UTGame class. There is no point in Unreal Tournament where you go directly from a UTDeathmatch to another game mode without some sort of middleman menu in between. Because of this, UTDeathmatch only needs to be aware of the prefix logic for itself. The Acronym variable tells the game mode what the game mode&#8217;s prefix is. UTDeathmatch&#8217;s prefix is DM, and is thus assigned to Acronym. Also, it adds DM to the map prefix logic as a game mode can have multiple prefixes which may or may not swap out game modes. Adding DM to the set of MapPrefixes allows UTDeathmatch to immediately switch to another DM map without having to worry what game mode it is. We already defined a map prefix for our game mode above, but we should at least let UDKGame know that its acronym is HT as well.</p>
<pre class="brush: csharp;">class UDKGame extends UTGame
 config(UDKGame);

defaultproperties
{
 Acronym=&quot;HT&quot;
 DefaultMapPrefixes(0)=(Prefix=&quot;HT&quot;,GameType=&quot;UDKGame.UDKGame&quot;)
 DefaultPawnClass=class'UDKGame.HTPawn'
 PlayerControllerClass=class'UDKGame.HTPlayerController'
}</pre>
<p>This will do for now. When we require a need to have a seperate game mode for menu front-ends, in-game madness, and other game modes we may create in the future, we may need to come back and rework or add to this code block. For now though, any map with the HT prefix (or the prefix you created) will always load our game info class, and thats all we need to make sure our levels run our game code!</p>
<p>After you save your code, it should compile with 0 errors and 0 warnings. Congratulations your game is now set up and ready for future code! Stay tuned for more tutorials on how to extend you game!</p>
<div style="font-size:0px;height:0px;line-height:0px;margin:0;padding:0;clear:both"></div>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fforecourse.com%2F2010%2F01%2Fbeginning-your-game-part-2%2F&amp;linkname=Beginning%20Your%20Game%20Part%202">Share/Save</a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/y6bC2zoxDHTT5YlDGTLy_6v4E7Q/0/da"><img src="http://feedads.g.doubleclick.net/~a/y6bC2zoxDHTT5YlDGTLy_6v4E7Q/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/y6bC2zoxDHTT5YlDGTLy_6v4E7Q/1/da"><img src="http://feedads.g.doubleclick.net/~a/y6bC2zoxDHTT5YlDGTLy_6v4E7Q/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/AllarsAwesomeBlog/~4/bPfYdwBwpog" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://forecourse.com/2010/01/beginning-your-game-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
<enclosure url="http://www.forecourse.com/unreal/UDKGameInfoSmall/UDKGameInfoSmall.mp4" length="66954108" type="video/mpeg" />
<enclosure url="http://www.forecourse.com/unreal/UDKGameInfo/UDKGameInfo.mp4" length="214678112" type="video/mpeg" />
		<feedburner:origLink>http://forecourse.com/2010/01/beginning-your-game-part-2/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</feedburner:origLink></item>
		<item>
		<title>Beginning Your Game Part 1</title>
		<link>http://feedproxy.google.com/~r/AllarsAwesomeBlog/~3/_RmGFk97FzU/</link>
		<comments>http://forecourse.com/2010/01/beginning-your-game-part-1/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 18:44:19 +0000</pubDate>
		<dc:creator>Allar</dc:creator>
				<category><![CDATA[Unreal]]></category>
		<category><![CDATA[beginner]]></category>
		<category><![CDATA[beginning]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[empty]]></category>
		<category><![CDATA[fresh]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[GameInfo]]></category>
		<category><![CDATA[scratch]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[udk]]></category>
		<category><![CDATA[UDKGame]]></category>

		<guid isPermaLink="false">http://forecourse.com/?p=219</guid>
		<description><![CDATA[
Video Version
Subject: Beginning Your Game Parts 1 and 2
Skill Level: Beginner
Run-Time: 1 Hour
Author: Michael Allar
Notes: This is really incredibly long but goes over how to create a blank slate for your game. Also goes somewhat in-depth on a line-by-line basis.
Streaming:     720×480 1920×1080
Download:     Low-Res (66MB) Hi-Res (200MB)
Written Version
Subject: Beginning Your Game Part 1
Skill Level: Beginner
Author: Michael [...]]]></description>
			<content:encoded><![CDATA[<p><!--CusAds1--><br />
<h2>Video Version</h2>
<p>Subject: Beginning Your Game Parts 1 and 2<br />
Skill Level: Beginner<br />
Run-Time: 1 Hour<br />
Author: Michael Allar<br />
Notes: This is really incredibly long but goes over how to create a blank slate for your game. Also goes somewhat in-depth on a line-by-line basis.</p>
<p>Streaming:     <a href="http://www.forecourse.com/unreal/UDKGameInfoSmall/UDKGameInfoSmall.html">720×480</a> <a href="http://www.forecourse.com/unreal/UDKGameInfo/UDKGameInfo.html" target="_blank">1920×1080</a></p>
<p>Download:     <a href="http://www.forecourse.com/unreal/UDKGameInfoSmall/UDKGameInfoSmall.mp4">Low-Res (66MB)</a> <a href="http://www.forecourse.com/unreal/UDKGameInfo/UDKGameInfo.mp4" target="_blank">Hi-Res (200MB)</a></p>
<h2>Written Version</h2>
<p>Subject: Beginning Your Game Part 1<br />
Skill Level: Beginner<br />
Author: Michael Allar<br />
Notes: Gets your UDK set up so that you can start coding into your own game class!</p>
<p>If you haven’t already, you need to install a fresh copy of <a href="http://www.udk.com/" target="_blank">Epic’s Unreal Development Kit (UDK)</a>. Without it, you can’t really build anything. <img src="../wp-includes/images/smilies/icon_biggrin.gif" alt=":D" /></p>
<p>You also need a way to edit .ini and .uc files. Notepad will work, but I strongly recommend setting up <a href="http://forecourse.com/2009/11/setting-up-an-nfringe-environment-for-epics-udk/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed">nFringe </a>or <a href="http://forecourse.com/2009/11/setting-up-a-notepad-environment/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed">Notepad++</a>.</p>
<p>It is highly recommended that you also set up <a href="http://forecourse.com/?p=209#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed">UnCodeX</a>.</p>
<p>At the time of this writing, the UDK version used is UDK-2009-12.</p>
<h4>Setting Up Your Code Package</h4>
<p>In order to begin coding your new game, you first have to put your code somewhere where the Unreal Engine can find it. This is where the Development\Src folder comes into play. All the code for your game belongs in the Development\Src folder, and <strong>your</strong> code that <strong>you </strong>will create will be in a folder with a meaningful name that represents your game. Each folder in Development\Src is a script package, so we call GameFramework, UTGame, UTGameContent, etc &#8220;script packages&#8221;. In each script package there is a folder within labeled &#8220;Classes&#8221; where all your UnrealScript classes will go. UnrealScript Classes are how you extend functionality to your game, making it your own. There lies a folder upon installation in Src named MyMod, you may use this folder to place your code in but I highly recommend naming it similar to your game name but keep in mind that you shouldn&#8217;t use spaces or weird characters in your package name as it will have to be referenced in code many times. You will see that for this tutorial, I have used &#8220;UDKGame&#8221; as my script package name. Inside this MyMod\Classes folder you will find a DO_NOT_DELETE.txt, but feel free to delete this. It seems that this file was only needed for Epic to package the installer correctly. Right now this script package is empty, so lets get ready to add to it!</p>
<p><span id="more-219"></span></p>
<h4>Currently Your Game is UTDeathmatch</h4>
<p>After installing the UDK, if you launch your game through your Unreal Frontend (located in Binaries, I highly recommend keeping this open at all times for convenience) you will load a level with a UI interface that allows you to begin a game. If you load any other map (the default is UTFrontend), you will see that your game will load Epic&#8217;s UTDeathmatch game mode. (unless the map you load has a CTF- or VCTF- prefix, but we will go into how that works later) We don&#8217;t want to play UTDeathmatch, we want to play our own game mode! In order to do this, we have to first create our own game mode and then make the engine use our game mode.</p>
<h4>What Makes A Game Mode?</h4>
<p>A game mode in the Unreal Engine is a set of rules in code that define game play. Game modes are implemented through GameInfo classes. (Actor.Info.GameInfo) For a more in-depth explanation of this and how one was supposed to figure this out, watch the video version of this tutorial. Derived from this GameInfo class is UTGameInfo, the superclass of all game modes that you have seen in Unreal Tournament including Deathmatch, Capture The Flag, etc. Here is where you must make an important decision regarding the development of your game: You can either derive your game mode from either GameInfo or UTGameInfo. Deriving from GameInfo will give you the from-scratch code base for you start developing your game, however deriving from UTGameInfo will give you a great stepping stone into creating your own game and it is what I will be using for this tutorial.</p>
<h4>Deriving From GameInfo? What Do You Mean, Derive?</h4>
<p>UnrealScript is a language that relies heavily on Object-Oriented Programming. Infact, every single .uc file contains one and only UnrealScript Class, which all derive from Object and a good lot deriving from Actor. When one class derives from another, it is said to inherit all of the traits, properties, methods, etc of the class before it. Lets take a look at the GameInfo hierarchy.</p>
<div id="attachment_221" class="wp-caption aligncenter" style="width: 310px"><a href="http://forecourse.com/wp-content/uploads/2010/01/GameInfi1.JPG#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img class="size-medium wp-image-221" title="GameInfo" src="http://forecourse.com/wp-content/uploads/2010/01/GameInfi1-300x139.jpg" alt="The GameInfo hierarchy as shown in UnCodeX. To learn more about UnCodeX, please watch this video tutorial." width="300" height="139" /></a>
<p class="wp-caption-text">The GameInfo hierarchy as shown in UnCodeX. To learn more about UnCodeX, please watch this video tutorial.</p>
</div>
<p>The way the GameInfo hierarchy is laid out, one can make sense of this class deriving nonsense. If each class is a file of code, and each file of code inherits properties of the class above it, it is easy to figure out where code you need to create needs to reside. GameInfo is the super-class (the top-most class for its role) for all things game mode related. Below that is UTGame which derives from (also called extending) GameInfo to add more functionality to GameInfo for all of Epic&#8217;s Unreal Tournament game modes. I will be extending from UTGame as it contains lots of code that you will have to rewrite if you were to extend GameInfo directly such as player HUD, input, deaths, etc. The next class in the hierarchy is UTDeathmatch, and this game mode is pretty simple. In fact its only 121 lines of code long as most of the game mode logic is done in UTGame as there are hardly any rules to Deathmatch as the goal is just to kill everyone else. Extending from Deathmatch is UTTeamGame which serves as the super-class for all game modes that have teams. In fact this super-class also functions as Team Deathmatch, as all UTTeamGame does is introduce team functionality. When you add team functionality to a Deathmatch mode, you get Team Deathmatch! The next class in the hierarchy is UTCTFGame, which adds Capture The Flag functionality. Capture The Flag is a team-based game, so it derives from UTTeamGame and contains code that stacks on top of just killing people, by adding flags to capture. There are two classes that extend from this however: UTCTFGame_Content and UTVehicleCTFGame. You will find that Epic sometimes splits their classes into two classes, one being for the class logic and the other being for setting up the &#8220;defaultproperties&#8221; block that handles a lot of content assignment. We will be getting more into more about the &#8220;defaultproperties&#8221; block later when we actually begin coding. UTVehicleCTFGame however does add something to the table, vehicles! There is no need to write a game mode from scratch just to include vehicles so once again we extend an existing class that just so happens to have CTF logic for us. Understanding how concepts like these are broken up and then implemented in class hierarchies is key to understanding UnrealScript and getting it to do what you want.</p>
<h4>Okay, So How Do We Actually Derive/Extend?</h4>
<p>To make one class derive from another, we have to script it to do so! If you watch the video tutorial it will go over the many ways to first set this up, but for the written version of this tutorial I will be using UnCodeX&#8217;s Create Subclass feature. You can do this manually yourself really easily, and that is also discussed in the video. To Create a Subclass (or extend a class/derive from a class):</p>
<ol>
<li>Know which class you need to extend. In this case, it is UTGame</li>
<li>Navigate to the UTGame class in the Class Tree of UnCodeX</li>
<li>Right-Click it and choose Create Subclass.</li>
<li>If you already have a script package, choose it from the Package drop-down box. Otherwise, type in the name of your new script package. As previously mentioned, I will be using UDKGame.</li>
<li>Make sure Parent Class reads UTGame, as that is the class we want to extend.</li>
<li>Type the new name for your new GameInfo class. For this tutorial, I will be using UDKGame again, but if your game has a prefix (like UT for UnrealTournament) it would be wise to prefix your class name. You will see that I use HT in the future.</li>
<li>If you are just now creating your script package, make sure &#8220;Create New Package&#8221; is checked.
<ol>
<li>After you click OK, it will ask where you want your base folder to be. Make absolutely sure to select your Src folder.</li>
</ol>
</li>
<li>Click OK if you haven&#8217;t already.</li>
<li>UnCodeX will attempt to open your new .uc file in a text editor, however if you have not set up an UnrealScript environment (as covered in my previous tutorial) Windows may ask you what program you would like to open it with. In which case, just use notepad.</li>
<li>If UnCodeX did not open your new class file, navigate to Development\Src\YourScriptPackage\Classes\YourGameInfo.uc and open it there.</li>
</ol>
<div id="attachment_223" class="wp-caption aligncenter" style="width: 310px"><a href="http://forecourse.com/wp-content/uploads/2010/01/createnewclass.JPG#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img class="size-medium wp-image-223" title="Create New Sub-class" src="http://forecourse.com/wp-content/uploads/2010/01/createnewclass-300x252.jpg" alt="The Create New Class dialog in UnCodeX. User-Friendly way to extend a class if you are completely new to UnrealScript. See the video tutorial for more info about the power of UnCodeX." width="300" height="252" /></a>
<p class="wp-caption-text">The Create New Class dialog in UnCodeX. User-Friendly way to extend a class if you are completely new to UnrealScript. See the video tutorial for more info about the power of UnCodeX.</p>
</div>
<h4>Woah, My First UnrealScript Code, What Is This?</h4>
<p>If you created your code with UnCodeX, the top portion of your code will consist of a comment block which you can feel free to keep/edit/delete/etc. Its a nice way to add a description of your class so that others reading your code can understand what it does/how to use it. Otherwise, if you followed the video tutorial or skipped ahead to this part directly, this is what you will have:</p>
<pre class="brush: csharp;">class UDKGame extends UTGame;</pre>
<p>Not too intimidating I hope, however UDKGame and UTGame may be different for you. You will always see a line of code similar to this at the very top of every UnrealScript code file. This line of code tells the engine and the compiler that this file<strong> (which has to be named identical to the class you are declaring)</strong> contains all the code for this specific class that you are now creating. The keyword &#8220;class&#8221; handles all that, but it has to be followed by the name of this new class itself. Remember, my new GameInfo class is named UDKGame, yours may be named different. The next keyword &#8220;extends&#8221; allows this class to extend or derive from another class, this one extending UTGame. Because of the fact that UDKGame extends UTGame, and UTGame extends GameInfo, UDKGame can be said to now be a GameInfo class. The last character on the line is very important: the semi-colon. Semi-colons are UnrealScript&#8217;s (and most other languages) way to tell the compiler that this is the end of this line of code. Every instruction you do in code must be proceeded by a semi-colon. UDKGame is now ready to be used within the engine as your new game mode! Because this is the only line of code and adds no functionality, it will function identical to the UTGame class. As UTGame contains lots of logic already and that UTDeathmatch is hardly any improvement, Your game class is currently a UTDeathmatch-Lite! Save your file.</p>
<h4>Getting the Engine To Use Your Game Mode</h4>
<p>To have UDK use your game mode, there are two things you need to do:</p>
<ol>
<li>Tell the engine to load your package.</li>
<li>Tell the engine to use your game mode.</li>
</ol>
<h5>Having the engine load your package</h5>
<p>To have the engine load your package you will need to edit your config files that house all the settings and fun things the engine needs to load and to figure out what it is doing. The video goes more in-depth about the config folder, but here are some things to always keep in mind when editing a config file.</p>
<ul>
<li>All your changes should only be done in the Default*.ini files, as those are the config files that will be set in stone when your game gets distributed.</li>
<li>Always delete all your UT*.ini config files unless you know you need them because you created them every time you make a change to your corresponding Default*.ini file.</li>
<li>If your changes did not seem to do anything, did you delete your UT*.ini files?</li>
<li>Also, you may want to delete your UT*.ini files and then reload it.</li>
<li>Lastly, if something is wrong, delete your UT*.ini files.</li>
</ul>
<p>While that may be redundant, its pretty important if you change something and don&#8217;t understand this concept. The Unreal Engine grabs configuration settings from the UTGame\Config folder. When developing your game, you have two sets of files: Default*.ini files and UT*.ini files. Also in the Engine folder you have Base*.ini files. The way the config system works is that first it loads the Base*.ini files, and then it loads the Default*.ini files and overrides any Base*.ini setting, lastly loading the UT*.ini files overriding any Default*.ini files.</p>
<ul>
<li>Base*.ini files: These are Epic&#8217;s config settings for the engine. Don&#8217;t touch them.</li>
<li>Default*.ini files: These are <strong>your</strong> config settings. These are the settings that will be standard when you distribute your game, and will override the Base*.ini settings when different. If these files are missing, they will be regenerated with the same settings in the Base*.ini files.</li>
<li>UT*.ini files: These are the <strong>end-user&#8217;s</strong> config settings. These are settings that the players of your game will tweak and change to their liking. The end-user may even accidentally delete these files, in which case they will be regenerated with the Default*.ini files which they will have a tougher time corrupting. The reason why your changes are in the Default*.ini files is so that if a end-user screws up their settings, it will load your standard settings again. If you do all your editing in the UT*.ini files and the end-user screws up their config, they will need to re-install their game just to have proper config files!</li>
</ul>
<p>Now with that said, lets delete those UT*.ini files.</p>
<p>After that is done, your UTGame\Config folder should have nothing but Default*.ini files. The one you need to open now is DefaultEngine.ini. This config file contains important settings that tell the engine what to do upon loading, some critical settings, and also which packages should always be loaded. Our game should always have our script package loaded as our game IS our script package. Epic made this really easy to add our new package in, as they just commented out the line that allows us to do so. Look for the following code block near the top of the config file:</p>
<pre class="brush: csharp; first-line: 31;">[UnrealEd.EditorEngine]
EditPackagesOutPath=..\..\UTGame\Script
FRScriptOutputPath=..\..\UTGame\ScriptFinalRelease
+EditPackages=UTGame
+EditPackages=UTEditor
+EditPackages=UTGameContent
;ModEditPackages=MyMod
AutoSaveDir=..\..\UTGame\Autosaves
InEditorGameURLOptions=?quickstart=1?numplay=1</pre>
<p>Line 37 reads <em>;ModEditPackages=MyMod </em>and this is the line that will allow us to have the engine load our script package.</p>
<p>In config files, the semi-colon actually tells the engine to ignore everything past it, or to comment the line out instead of telling the engine that its at the end of the line of code. Right now that semi-colon is making the engine skip over ModEditPackages=MyMod. The ModEditPackages property tells the engine that our game (&#8216;mod&#8217;) that we are developing is MyMod, which was the default name of the empty code folder the UDK made after install. You may or may not have changed this, in my case I changed it to UDKGame. By uncommenting this line out by deleting the semi-colon, and changing MyMod to our package name, the engine will now load our package and allow us to use our code.</p>
<p>My edited line:</p>
<pre class="brush: csharp; first-line: 37;">ModEditPackages=UDKGame</pre>
<p>Save the file!</p>
<h5>Seeing if the engine will now compile your package</h5>
<p>If the engine now is correctly loading your script package, it will be able to compile it through the Unreal Frontend. As I have written way above, it is convienent to have your Unreal Frontend running (located in your Binaries folder). The Unreal Frontend has a button on the top labeled &#8220;Make&#8221; along with a drop down arrow aside it that allows you to do a &#8220;Full Recompile&#8221;. A Full Recompile will recompile all of your packages regardless if they have been modified or not since their last compile, while simply clicking the Make button itself will only compile packages that have changed. I recommend doing a Full Recompile right now to see if all of your other Epic packages are untouched and running just fine. In your compile log to the right, you will see a list of package names being outputted. If you see MyMod, UDKGame, or whatever you named your script package in the compile log then you have successfully made the engine load your package! Yay! If not, review the last section. Also, your compile should succeed with 0 errors and 0 warnings, otherwise you may have to review the 1 line of code we created earlier.</p>
<div id="attachment_232" class="wp-caption aligncenter" style="width: 310px"><a href="http://forecourse.com/wp-content/uploads/2010/01/FullRecompile.jpg#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img class="size-medium wp-image-232" title="Full Recompile" src="http://forecourse.com/wp-content/uploads/2010/01/FullRecompile-300x189.jpg" alt="" width="300" height="189" /></a>
<p class="wp-caption-text">Seeing if our script package is now being compiled! Yay!</p>
</div>
<h5>Telling the engine to use your game mode</h5>
<p>Now that the engine is now compiling your script package, your script package is now usable! Yaaay! This means we can tell the engine to use our new game mode as our default game mode! This couldn&#8217;t be any easier. This is also done by editing a config file named DefaultGame.ini. Fitting, no?</p>
<pre class="brush: csharp; first-line: 4;">[Engine.GameInfo]
DefaultGame=UTGame.UTDeathmatch
DefaultServerGame=UTGame.UTDeathmatch
PlayerControllerClassName=UTGame.UTPlayerController
GameDifficulty=+1.0
MaxPlayers=32</pre>
<p>You will find this config block on line 4 of DefaultGame.ini. This here is pretty simple, we need to change the DefaultGame property and we are good to go. When we reference things in packages, be it static meshes, materials, particle systems, code classes, etc, we have to supply its fully qualified name. An assets&#8217; fully qualified name is in the form of PackageName.Group.Asset; but not assets have Group names. I will go into this more at a later time, but code classes are an example of an asset that does not have a group name in its fully qualified name. The name of the asset you will reference depends on how you named your script package and your GameInfo class. I used UDKGame for my package name and I also used UDKGame for my GameInfo, but they do not have to be the same and it is probably best if they aren&#8217;t the same name. For me, my game&#8217;s qualified name is UDKGame.UDKGame. Remember PackageName.AssetName, it is how everything is referenced.</p>
<p>My edited DefaultGame.ini line:</p>
<pre class="brush: csharp; first-line: 5;">DefaultGame=UDKGame.UDKGame</pre>
<p>Save your file. Delete UT*.ini files before you test.</p>
<h4>How To Test Our Game Mode</h4>
<p>To test our game mode, we can&#8217;t just load up our game with the Launch button in the Unreal Frontend. If we do this, our current config loads UTFrontend as our first level and this level has some special things going on behind the scenes that create the UI that allow the player to start a game of their choosing or join one. This level then loads another level that will be loaded with the appropriate game mode as we have not coded how our game mode handles itself on different maps. Loading a DM- map will load a UTDeathmatch game, a CTF- a UTCTFGame game, etc. We will fix this later on, but there is one map that we can load that does not have a prefix and also does not have any special game changing UI in our way: ExampleMap.udk. This ExampleMap is just that, an example map built with the UDK. We can load this map up by going to the Game tab in the top left and next to the Map To Play box, click Browse and select ExampleMap. Now when we click Launch, it will launch our game directly into that map! You may see a start up video along with a loading screen, but eventually you will be put right into ExampleMap!</p>
<p>Now how do we know its our game mode?</p>
<p>Well if you derived GameInfo, you won&#8217;t have any weapons or HUD! That is a pretty significant change&#8230; but what if you derived from UTGame? If you examine the UTDeathmatch code, you will see that it doesn&#8217;t add much at all to the UTGame class so UTGame and UTDeathmatch are near identical. Because our game mode derived UTGame and added zero code, our mode is identical to UTGame which is near-identical to UTDeathmatch. There is one easy difference to spot however, and that is UTGame gives players a Physics Gun whereas UTDeathmatch does not. If you examine the defaultproperties block in both UTGame and UTDeathmatch, you will see this difference at the end. We will go into this code block later however. Because UTGame gives us a Physics Gun and UTDeathmatch does not, and our mode is identical to UTGame, we should have a Physics Gun! To select it, scroll your mouse wheel! Then stand back, aim at the lone Scorpion, hold down right-click, and fling your mouse into the air! Yay Physics! If you find you do not have a Physics Gun, try deleting your UT*.ini files. If that doesn&#8217;t work, review this tutorial.</p>
<div id="attachment_235" class="wp-caption aligncenter" style="width: 310px"><a href="http://forecourse.com/wp-content/uploads/2010/01/PhysicsGun.jpg#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img class="size-medium wp-image-235" title="Your Empty Game Mode" src="http://forecourse.com/wp-content/uploads/2010/01/PhysicsGun-300x207.jpg" alt="" width="300" height="207" /></a>
<p class="wp-caption-text">Testing to see if your empty game mode is now being called and working by taking out the Physics Gun not available in UTDeathmatch. Yaay!</p>
</div>
<p><a href="http://forecourse.com/2010/01/beginning-your-game-part-2/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed">Click here to continue to Part 2</a></p>
<div style="font-size:0px;height:0px;line-height:0px;margin:0;padding:0;clear:both"></div>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fforecourse.com%2F2010%2F01%2Fbeginning-your-game-part-1%2F&amp;linkname=Beginning%20Your%20Game%20Part%201">Share/Save</a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/q97U7pHDXHEkArmKAjf-lN-4wkM/0/da"><img src="http://feedads.g.doubleclick.net/~a/q97U7pHDXHEkArmKAjf-lN-4wkM/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/q97U7pHDXHEkArmKAjf-lN-4wkM/1/da"><img src="http://feedads.g.doubleclick.net/~a/q97U7pHDXHEkArmKAjf-lN-4wkM/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/AllarsAwesomeBlog/~4/_RmGFk97FzU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://forecourse.com/2010/01/beginning-your-game-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.forecourse.com/unreal/UDKGameInfoSmall/UDKGameInfoSmall.mp4" length="66954108" type="video/mpeg" />
<enclosure url="http://www.forecourse.com/unreal/UDKGameInfo/UDKGameInfo.mp4" length="214678112" type="video/mpeg" />
		<feedburner:origLink>http://forecourse.com/2010/01/beginning-your-game-part-1/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</feedburner:origLink></item>
		<item>
		<title>Long time no activity</title>
		<link>http://feedproxy.google.com/~r/AllarsAwesomeBlog/~3/oXNlOfZpfT0/</link>
		<comments>http://forecourse.com/2009/12/long-time-no-activity/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 01:38:14 +0000</pubDate>
		<dc:creator>Allar</dc:creator>
				<category><![CDATA[Site]]></category>

		<guid isPermaLink="false">http://forecourse.com/?p=217</guid>
		<description><![CDATA[Yeah, I know, sorry, I had lots of things to do.
The content train will be rolling soon.

Share/Save
]]></description>
			<content:encoded><![CDATA[<p><!--CusAds1-->Yeah, I know, sorry, I had lots of things to do.</p>
<p>The content train will be rolling soon.</p>
<div style="font-size:0px;height:0px;line-height:0px;margin:0;padding:0;clear:both"></div>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fforecourse.com%2F2009%2F12%2Flong-time-no-activity%2F&amp;linkname=Long%20time%20no%20activity">Share/Save</a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/gGn-XLGoqTzc4X2GWkFVdSXb3mE/0/da"><img src="http://feedads.g.doubleclick.net/~a/gGn-XLGoqTzc4X2GWkFVdSXb3mE/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/gGn-XLGoqTzc4X2GWkFVdSXb3mE/1/da"><img src="http://feedads.g.doubleclick.net/~a/gGn-XLGoqTzc4X2GWkFVdSXb3mE/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/AllarsAwesomeBlog/~4/oXNlOfZpfT0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://forecourse.com/2009/12/long-time-no-activity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://forecourse.com/2009/12/long-time-no-activity/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</feedburner:origLink></item>
	</channel>
</rss>
