diff --git a/9781430240358.jpg b/9781430240358.jpg new file mode 100644 index 0000000..5ee9d1a Binary files /dev/null and b/9781430240358.jpg differ diff --git a/Beginning iOS 3D Unreal Games Dev/Ch02/Classes/ExampleCh2Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch02/Classes/ExampleCh2Game.uc new file mode 100644 index 0000000..2c9b543 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch02/Classes/ExampleCh2Game.uc @@ -0,0 +1,31 @@ +class ExampleCh2Game extends FrameworkGame; + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh2Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh2.ExampleCh2PC' + + DefaultPawnClass=class'UDKBase.SimplePawn' + HUDType=class'UDKBase.UDKHUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false +} + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch02/Classes/ExampleCh2PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch02/Classes/ExampleCh2PC.uc new file mode 100644 index 0000000..6c869a8 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch02/Classes/ExampleCh2PC.uc @@ -0,0 +1,114 @@ +class ExampleCh2PC extends SimplePC; + + +var float PickDistance; + + +function Actor PickActor(Vector2D PickLocation, out Vector HitLocation, out TraceHitInfo HitInfo) +{ + local Vector TouchOrigin, TouchDir; + local Vector HitNormal; + local Actor PickedActor; + local vector Extent; + + //Transform absolute screen coordinates to relative coordinates + PickLocation.X = PickLocation.X / ViewportSize.X; + PickLocation.Y = PickLocation.Y / ViewportSize.Y; + + //Transform to world coordinates to get pick ray + LocalPlayer(Player).Deproject(PickLocation, TouchOrigin, TouchDir); + + //Perform trace to find touched actor + Extent = vect(0,0,0); + PickedActor = Trace(HitLocation, + HitNormal, + TouchOrigin + (TouchDir * PickDistance), + TouchOrigin, + True, + Extent, + HitInfo); + + + //Return the touched actor for good measure + return PickedActor; +} + + +// OnProcessInputDelegate [Zone] [DeltaTime] [Handle] [EventType] [TouchLocation] - +// Called when any input event occurs within the zone allowing completely custom input handling for any +// zone or for input in a zone to be handled by other classes. Return TRUE to acknowledge the input as +// being handled. Returning FALSE will pass the input on, processing it in the ProcessTouch() function +// according to the type of zone. +// +// Zone - A reference to the Zone the delegate belongs to. +// DeltaTime - The amount of time since the last input event for the zone. +// Handle - The unique identifier of the touch responsible for the input event. +// EventType - The EZoneTouchEvent type of the input event. +// TouchLocation - The Vector2D specifying the horizontal and vertical location of the touch event in pixel screen coordinates. + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + local Actor PickedActor; + local Vector HitLocation; + local TraceHitInfo HitInfo; + + + retval = true; + + + if (EventType == ZoneEvent_Touch) + { + // If screen touched then pick actor + PickedActor = PickActor(TouchLocation,HitLocation,HitInfo); + + WorldInfo.Game.Broadcast(self,"PICKED ACTOR = " @ + PickedActor @ + ", HitLocation = " @ HitLocation @ + ", Zone Touched = " @ Zone); + } + else + if(EventType == ZoneEvent_Update) + { + + } + else + if (EventType == ZoneEvent_UnTouch) + { + + } + + + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + } + } + +} + +defaultproperties +{ + PickDistance = 10000; +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/ExampleCh31Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/ExampleCh31Game.uc new file mode 100644 index 0000000..abffa4a --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/ExampleCh31Game.uc @@ -0,0 +1,30 @@ +class ExampleCh31Game extends FrameworkGame; + + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh31Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh31.ExampleCh31PC' + + DefaultPawnClass=class'Jazz1Pawn' + HUDType=class'UDKBase.UDKHUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/ExampleCh31PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/ExampleCh31PC.uc new file mode 100644 index 0000000..9651aec --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/ExampleCh31PC.uc @@ -0,0 +1,67 @@ +class ExampleCh31PC extends SimplePC; + + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + + retval = true; + + + if (EventType == ZoneEvent_Touch) + { + WorldInfo.Game.Broadcast(self,"You touched the screen at = " @ + TouchLocation.x @ " , " @ TouchLocation.y @ + ", Zone Touched = " @ Zone); + + + // Start Firing pawn's weapon + StartFire(0); + } + else + if(EventType == ZoneEvent_Update) + { + + } + else + if (EventType == ZoneEvent_UnTouch) + { + // Stop Firing Pawn's weapon + StopFire(0); + } + + + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + + } + } +} + + +defaultproperties +{ + +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/Jazz1Pawn.uc b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/Jazz1Pawn.uc new file mode 100644 index 0000000..2bada75 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/Jazz1Pawn.uc @@ -0,0 +1,131 @@ +class Jazz1Pawn extends SimplePawn; + + +var float CamOffsetDistance; +var int CamAngle; + +var Inventory MainGun; + + +simulated singular event Rotator GetBaseAimRotation() +{ + local rotator TempRot; + + TempRot = Rotation; + TempRot.Pitch = 0; + + SetRotation(TempRot); + + + return TempRot; +} + +function AddGunToSocket(Name SocketName) +{ + local Vector SocketLocation; + local Rotator SocketRotation; + + if (Mesh != None) + { + if (Mesh.GetSocketByName(SocketName) != None) + { + Mesh.GetSocketWorldLocationAndRotation(SocketName, SocketLocation, SocketRotation); + + MainGun.SetRotation(SocketRotation); + MainGun.SetBase(Self,, Mesh, SocketName); + + } + else + { + WorldInfo.Game.Broadcast(self,"!!!!!!SOCKET NAME NOT FOUND!!!!!"); + } + } + else + { + WorldInfo.Game.Broadcast(self,"!!!!!!MESH NOT FOUND!!!!!"); + } + +} + + +function AddDefaultInventory() +{ + MainGun = InvManager.CreateInventory(class'JazzWeapon1'); + MainGun.SetHidden(false); + + AddGunToSocket('Weapon_R'); + + Weapon(MainGun).FireOffset = vect(0,0,-70); +} + +// Iso Cam +/* +simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) +{ + out_CamLoc = Location; + out_CamLoc.X += Cos(CamAngle * UnrRotToRad) * CamOffsetDistance; + out_CamLoc.Z += Sin(CamAngle * UnrRotToRad) * CamOffsetDistance; + + out_CamRot.Pitch = -1 * CamAngle; + out_CamRot.Yaw = 32000; + out_CamRot.Roll = 0; + + return true; +} +*/ + +/////////////////////////////////////////////// Third Person View ///////////////////////////////////////////////////// + +simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) +{ + local vector BackVector; + local vector UpVector; + + local float CamDistanceHorizontal; + local float CamDistanceVertical; + + + + // Set Camera Location + CamDistanceHorizontal = CamOffsetDistance * cos(CamAngle * UnrRotToRad); + CamDistanceVertical = CamOffsetDistance * sin(CamAngle * UnrRotToRad); + + BackVector = -Normal(Vector(Rotation)) * CamDistanceHorizontal; + UpVector = vect(0,0,1) * CamDistanceVertical; + + out_CamLoc = Location + BackVector + UpVector; + + // Set Camera Rotation + out_CamRot.pitch = -CamAngle; + out_CamRot.yaw = Rotation.yaw; + out_CamRot.roll = Rotation.roll; + + return true; +} + + +defaultproperties +{ + + Begin Object Class=SkeletalMeshComponent Name=JazzMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_Jazz' + AnimSets(0)=AnimSet'KismetGame_Assets.Anims.SK_Jazz_Anims' + AnimTreeTemplate=AnimTree'KismetGame_Assets.Anims.Jazz_AnimTree' + BlockRigidBody=true + CollideActors=true + End Object + + Mesh = JazzMesh; // Set The mesh for this object + Components.Add(JazzMesh); // Attach this mesh to this Actor + + + CamAngle=3000; + CamOffsetDistance= 484.0 + + + InventoryManagerClass=class'WeaponsIM1' +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/JazzBullet1.uc b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/JazzBullet1.uc new file mode 100644 index 0000000..f6b438b --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/JazzBullet1.uc @@ -0,0 +1,33 @@ +class JazzBullet1 extends Projectile; + + +simulated function Explode(vector HitLocation, vector HitNormal) +{ + +} + + +function Init( Vector Direction ) +{ + local vector NewDir; + + NewDir = Normal(Vector(InstigatorController.Pawn.Rotation)); + Velocity = Speed * NewDir; +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=Bullet + StaticMesh=StaticMesh'EngineMeshes.Sphere' + Scale3D=(X=0.050000,Y=0.050000,Z=0.05000) + End Object + Components.Add(Bullet) + + Begin Object Class=ParticleSystemComponent Name=BulletTrail + Template=ParticleSystem'Castle_Assets.FX.P_FX_Fire_SubUV_01' + End Object + Components.Add(BulletTrail) + + MaxSpeed=+05000.000000 + Speed=+05000.000000 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/JazzWeapon1.uc b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/JazzWeapon1.uc new file mode 100644 index 0000000..87d4526 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/JazzWeapon1.uc @@ -0,0 +1,26 @@ +class JazzWeapon1 extends Weapon; + +defaultproperties +{ + Begin Object Class=SkeletalMeshComponent Name=FirstPersonMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + Mesh=FirstPersonMesh + Components.Add(FirstPersonMesh); + + Begin Object Class=SkeletalMeshComponent Name=PickupMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + DroppedPickupMesh=PickupMesh + PickupFactoryMesh=PickupMesh + + WeaponFireTypes(0)=EWFT_Projectile + WeaponFireTypes(1)=EWFT_NONE + + WeaponProjectiles(0)=class'JazzBullet1' + WeaponProjectiles(1)=class'JazzBullet1' + + FiringStatesArray(0)=WeaponFiring + FireInterval(0)=0.25 + Spread(0)=0 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/WeaponsIM1.uc b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/WeaponsIM1.uc new file mode 100644 index 0000000..c221dcc --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.1/Classes/WeaponsIM1.uc @@ -0,0 +1,7 @@ +class WeaponsIM1 extends InventoryManager; + +defaultproperties +{ + PendingFire(0)=0 + PendingFire(1)=0 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/ExampleCh32Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/ExampleCh32Game.uc new file mode 100644 index 0000000..3138889 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/ExampleCh32Game.uc @@ -0,0 +1,32 @@ +class ExampleCh32Game extends FrameworkGame; + + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh32Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh32.ExampleCh32PC' + + DefaultPawnClass=class'Jazz2Pawn' + HUDType=class'UDKBase.UDKHUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false +} + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/ExampleCh32PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/ExampleCh32PC.uc new file mode 100644 index 0000000..d87bf5e --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/ExampleCh32PC.uc @@ -0,0 +1,103 @@ +class ExampleCh32PC extends SimplePC; + + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + + retval = true; + + + if (EventType == ZoneEvent_Touch) + { + //WorldInfo.Game.Broadcast(self,"You touched the screen at = " @ + // TouchLocation.x @ " , " @ TouchLocation.y @ + // ", Zone Touched = " @ Zone); + // Start Firing pawn's weapon + StartFire(0); + } + else + if(EventType == ZoneEvent_Update) + { + } + else + if (EventType == ZoneEvent_UnTouch) + { + // Stop Firing Pawn's weapon + StopFire(0); + } + + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + + } + } +} + +function PlaceWeapon() +{ + // First Person + local vector WeaponLocation; + local Rotator WeaponRotation,TempRot; + local Weapon TestW; + local vector WeaponAimVect; + + + WeaponRotation.yaw = -16000; // 90 Degrees turn = OFFSET + + + TempRot = Pawn.GetBaseAimRotation(); + WeaponRotation.pitch = TempRot.roll; + WeaponRotation.yaw += TempRot.yaw; + WeaponRotation.roll -= TempRot.pitch; // Swith due to weapon local axes orientation + + WeaponAimVect = Normal(Vector(TempRot)); + WeaponLocation = Pawn.Location + (40 * WeaponAimVect) + vect(0,0,30); + + TestW = Pawn.Weapon; //Pawn.InvManager.GetBestWeapon(); + + if (TestW != None) + { + TestW.SetLocation(WeaponLocation); + TestW.SetRotation(WeaponRotation); + } + else + { + WorldInfo.Game.Broadcast(self,"Player has no weapon!!!!!"); + } + +} + +function PlayerTick(float DeltaTime) +{ + Super.PlayerTick(DeltaTime); + + PlaceWeapon(); +} + +defaultproperties +{ + +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/Jazz2Pawn.uc b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/Jazz2Pawn.uc new file mode 100644 index 0000000..69a0c59 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/Jazz2Pawn.uc @@ -0,0 +1,19 @@ +class Jazz2Pawn extends SimplePawn; + + +var Inventory MainGun; + +function AddDefaultInventory() +{ + MainGun = InvManager.CreateInventory(class'JazzWeapon2'); + MainGun.SetHidden(false); + + Weapon(MainGun).FireOffset = vect(0,0,-70); +} + +defaultproperties +{ + InventoryManagerClass=class'WeaponsIM1' +} + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/JazzBullet2.uc b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/JazzBullet2.uc new file mode 100644 index 0000000..fd7cce6 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/JazzBullet2.uc @@ -0,0 +1,32 @@ +class JazzBullet2 extends Projectile; + + +simulated function Explode(vector HitLocation, vector HitNormal) +{ + SetPhysics(Phys_Falling); + +} + +function Init( Vector Direction ) +{ + super.Init(Direction); + + RandSpin(90000); +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=Bullet + StaticMesh=StaticMesh'Castle_Assets.Meshes.SM_RiverRock_01' + Scale3D=(X=0.300000,Y=0.30000,Z=0.3000) + End Object + Components.Add(Bullet) + + Begin Object Class=ParticleSystemComponent Name=BulletTrail + Template=ParticleSystem'Castle_Assets.FX.P_FX_Fire_SubUV_01' + End Object + Components.Add(BulletTrail) + + MaxSpeed=+05000.000000 + Speed=+05000.000000 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/JazzWeapon2.uc b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/JazzWeapon2.uc new file mode 100644 index 0000000..1bd0e2f --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch03/Example 3.2/Classes/JazzWeapon2.uc @@ -0,0 +1,26 @@ +class JazzWeapon2 extends Weapon; + +defaultproperties +{ + Begin Object Class=SkeletalMeshComponent Name=FirstPersonMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + Mesh=FirstPersonMesh + Components.Add(FirstPersonMesh); + + Begin Object Class=SkeletalMeshComponent Name=PickupMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + DroppedPickupMesh=PickupMesh + PickupFactoryMesh=PickupMesh + + WeaponFireTypes(0)=EWFT_Projectile + WeaponFireTypes(1)=EWFT_NONE + + WeaponProjectiles(0)=class'JazzBullet2' + WeaponProjectiles(1)=class'JazzBullet2' + + FiringStatesArray(0)=WeaponFiring + FireInterval(0)=0.25 + Spread(0)=0 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.1/Classes/ExampleCh41Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.1/Classes/ExampleCh41Game.uc new file mode 100644 index 0000000..895b6ca --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.1/Classes/ExampleCh41Game.uc @@ -0,0 +1,43 @@ +class ExampleCh41Game extends FrameworkGame; + + +// UDKEngine.ini +//[UnrealEd.EditorEngine] +//ModEditPackages=Example2 + + +// Mobile-UDKGame.ini +//[Example2.Example2Game] +//RequiredMobileInputConfigs=(GroupName="UberGroup",RequireZoneNames=("UberStickMoveZone","UberStickLookZone","UberLookZone")) + + + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh41Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh41.ExampleCh41PC' + + DefaultPawnClass=class'UDKBase.SimplePawn' + HUDType=class'UDKBase.UDKHUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false +} + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.1/Classes/ExampleCh41PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.1/Classes/ExampleCh41PC.uc new file mode 100644 index 0000000..29cb376 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.1/Classes/ExampleCh41PC.uc @@ -0,0 +1,126 @@ +class ExampleCh41PC extends SimplePC; + + +var float PickDistance; + + +function ApplyForceRigidBody(Actor SelectedActor, Vector ImpulseDir,float ImpulseMag, Vector HitLocation) +{ + if (SelectedActor.IsA('KActor')) + { + WorldInfo.Game.Broadcast(self,"*** Thrown object " @ SelectedActor @ + ", ImpulseDir = " @ ImpulseDir @ + ", ImpulseMag = " @ ImpulseMag @ + ", HitLocation = " @ HitLocation); + KActor(SelectedActor).ApplyImpulse(ImpulseDir,ImpulseMag, HitLocation); + } + else + { + WorldInfo.Game.Broadcast(self,"!!!ERROR Selected Actor " @ SelectedActor @ + " is not a KActor, you can not apply an impulse to this object!!!"); + } +} + +function Actor PickActor(Vector2D PickLocation, out Vector HitLocation, out TraceHitInfo HitInfo) +{ + local Vector TouchOrigin, TouchDir; + local Vector HitNormal; + local Actor PickedActor; + local vector Extent; + + + //Transform absolute screen coordinates to relative coordinates + PickLocation.X = PickLocation.X / ViewportSize.X; + PickLocation.Y = PickLocation.Y / ViewportSize.Y; + + //Transform to world coordinates to get pick ray + LocalPlayer(Player).Deproject(PickLocation, TouchOrigin, TouchDir); + + //Perform trace to find touched actor + Extent = vect(0,0,0); + PickedActor = Trace(HitLocation, + HitNormal, + TouchOrigin + (TouchDir * PickDistance), + TouchOrigin, + True, + Extent, + HitInfo); + + + //Return the touched actor for good measure + return PickedActor; +} + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + local Actor PickedActor; + local Vector HitLocation; + local TraceHitInfo HitInfo; + + + // Variables for physics + local Vector ImpulseDir; + local float ImpulseMag; + + + retval = true; + + + if (EventType == ZoneEvent_Touch) + { + // If screen touched then pick actor + PickedActor = PickActor(TouchLocation,HitLocation,HitInfo); + + WorldInfo.Game.Broadcast(self,"PICKED ACTOR = " @ + PickedActor @ + ", HitLocation = " @ HitLocation @ + ", Zone Touched = " @ Zone); + + // Set to roughly 45 degree angle + ImpulseDir = Normal(Vector(Pawn.Rotation)) + vect(0,0,1); + ImpulseMag = 100; + + ApplyForceRigidBody(PickedActor,ImpulseDir,ImpulseMag,HitLocation); + + } + else + if(EventType == ZoneEvent_Update) + { + + } + else + if (EventType == ZoneEvent_UnTouch) + { + + } + + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + } + } +} + +defaultproperties +{ + PickDistance = 10000; +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.2/Classes/ExampleCh42Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.2/Classes/ExampleCh42Game.uc new file mode 100644 index 0000000..e1df7e5 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.2/Classes/ExampleCh42Game.uc @@ -0,0 +1,32 @@ +class ExampleCh42Game extends FrameworkGame; + + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh42Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh42.ExampleCh42PC' + + DefaultPawnClass=class'UDKBase.SimplePawn' + HUDType=class'UDKBase.UDKHUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false +} + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.2/Classes/ExampleCh42PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.2/Classes/ExampleCh42PC.uc new file mode 100644 index 0000000..42aad3e --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.2/Classes/ExampleCh42PC.uc @@ -0,0 +1,132 @@ +class ExampleCh42PC extends SimplePC; + + +var float PickDistance; + + +function ApplyForceRigidBody(Actor SelectedActor, Vector ImpulseDir,float ImpulseMag, Vector HitLocation) +{ + if (SelectedActor.IsA('KActor')) + { + WorldInfo.Game.Broadcast(self,"*** Thrown object " @ SelectedActor @ + ", ImpulseDir = " @ ImpulseDir @ + ", ImpulseMag = " @ ImpulseMag @ + ", HitLocation = " @ HitLocation); + KActor(SelectedActor).ApplyImpulse(ImpulseDir,ImpulseMag, HitLocation); + } + else + if (SelectedActor.IsA('KAsset')) + { + WorldInfo.Game.Broadcast(self,"*** Thrown object " @ SelectedActor @ + ", ImpulseDir = " @ ImpulseDir @ + ", ImpulseMag = " @ ImpulseMag @ + ", HitLocation = " @ HitLocation); + KAsset(SelectedActor).SkeletalMeshComponent.AddImpulse(ImpulseDir* ImpulseMag, ,'Bone06'); + } + else + { + WorldInfo.Game.Broadcast(self,"!!!ERROR Selected Actor " @ SelectedActor @ + " is not a KActor or KAsset, you can not apply an impulse to this object!!!"); + } +} + +function Actor PickActor(Vector2D PickLocation, out Vector HitLocation, out TraceHitInfo HitInfo) +{ + local Vector TouchOrigin, TouchDir; + local Vector HitNormal; + local Actor PickedActor; + local vector Extent; + + //Transform absolute screen coordinates to relative coordinates + PickLocation.X = PickLocation.X / ViewportSize.X; + PickLocation.Y = PickLocation.Y / ViewportSize.Y; + + //Transform to world coordinates to get pick ray + LocalPlayer(Player).Deproject(PickLocation, TouchOrigin, TouchDir); + + //Perform trace to find touched actor + Extent = vect(0,0,0); + PickedActor = Trace(HitLocation, + HitNormal, + TouchOrigin + (TouchDir * PickDistance), + TouchOrigin, + True, + Extent, + HitInfo); + + //Return the touched actor for good measure + return PickedActor; +} + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + local Actor PickedActor; + local Vector HitLocation; + local TraceHitInfo HitInfo; + + // Variables for physics + local Vector ImpulseDir; + local float ImpulseMag; + + retval = true; + + if (EventType == ZoneEvent_Touch) + { + // If screen touched then pick actor + PickedActor = PickActor(TouchLocation,HitLocation,HitInfo); + + WorldInfo.Game.Broadcast(self,"PICKED ACTOR = " @ + PickedActor @ + ", HitLocation = " @ HitLocation @ + ", Zone Touched = " @ Zone); + + // Set to roughly 45 degree angle + ImpulseDir = Normal(Vector(Pawn.Rotation)) + vect(0,0,1); + ImpulseMag = 500; + + ApplyForceRigidBody(PickedActor,ImpulseDir,ImpulseMag,HitLocation); + + } + else + if(EventType == ZoneEvent_Update) + { + + } + else + if (EventType == ZoneEvent_UnTouch) + { + + } + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + } + } +} + +defaultproperties +{ + PickDistance = 10000; +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.3/Classes/ExampleCh43Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.3/Classes/ExampleCh43Game.uc new file mode 100644 index 0000000..aa7b462 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.3/Classes/ExampleCh43Game.uc @@ -0,0 +1,32 @@ +class ExampleCh43Game extends FrameworkGame; + + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh43Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh43.ExampleCh43PC' + + DefaultPawnClass=class'UDKBase.SimplePawn' + HUDType=class'UDKBase.UDKHUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false +} + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.3/Classes/ExampleCh43PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.3/Classes/ExampleCh43PC.uc new file mode 100644 index 0000000..36351c6 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.3/Classes/ExampleCh43PC.uc @@ -0,0 +1,154 @@ +class ExampleCh43PC extends SimplePC; + +var float PickDistance; + + +function ApplyForceRigidBody(Actor SelectedActor, Vector ImpulseDir,float ImpulseMag, Vector HitLocation) +{ + if (SelectedActor.IsA('KActor')) + { + WorldInfo.Game.Broadcast(self,"*** Thrown object " @ SelectedActor @ + ", ImpulseDir = " @ ImpulseDir @ + ", ImpulseMag = " @ ImpulseMag @ + ", HitLocation = " @ HitLocation); + KActor(SelectedActor).ApplyImpulse(ImpulseDir,ImpulseMag, HitLocation); + } + else + if (SelectedActor.IsA('KAsset')) + { + WorldInfo.Game.Broadcast(self,"*** Thrown object " @ SelectedActor @ + ", ImpulseDir = " @ ImpulseDir @ + ", ImpulseMag = " @ ImpulseMag @ + ", HitLocation = " @ HitLocation); + KAsset(SelectedActor).SkeletalMeshComponent.AddImpulse(ImpulseDir* ImpulseMag, ,'Bone06'); + } + else + { + WorldInfo.Game.Broadcast(self,"!!!ERROR Selected Actor " @ SelectedActor @ + " is not a KActor or KAsset, you can not apply an impulse to this object!!!"); + } +} + +function Actor PickActor(Vector2D PickLocation, out Vector HitLocation, out TraceHitInfo HitInfo) +{ + local Vector TouchOrigin, TouchDir; + local Vector HitNormal; + local Actor PickedActor; + local vector Extent; + + + //Transform absolute screen coordinates to relative coordinates + PickLocation.X = PickLocation.X / ViewportSize.X; + PickLocation.Y = PickLocation.Y / ViewportSize.Y; + + //Transform to world coordinates to get pick ray + LocalPlayer(Player).Deproject(PickLocation, TouchOrigin, TouchDir); + + //Perform trace to find touched actor + Extent = vect(0,0,0); + PickedActor = Trace(HitLocation, + HitNormal, + TouchOrigin + (TouchDir * PickDistance), + TouchOrigin, + True, + Extent, + HitInfo); + + + //Return the touched actor for good measure + return PickedActor; +} + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + local Actor PickedActor; + local Vector HitLocation; + local TraceHitInfo HitInfo; + + + // Variables for physics + local Vector ImpulseDir; + local float ImpulseMag; + + local float KickAngle; + + // Constants define din Object.uc + // const Pi = 3.1415926535897932; + // const RadToDeg = 57.295779513082321600; // 180 / Pi + // const DegToRad = 0.017453292519943296; // Pi / 180 + // const UnrRotToRad = 0.00009587379924285; // Pi / 32768 + // const RadToUnrRot = 10430.3783504704527; // 32768 / Pi + // const DegToUnrRot = 182.0444; + // const UnrRotToDeg = 0.00549316540360483; + + + retval = true; + + + if (EventType == ZoneEvent_Touch) + { + // If screen touched then pick actor + PickedActor = PickActor(TouchLocation,HitLocation,HitInfo); + + WorldInfo.Game.Broadcast(self,"PICKED ACTOR = " @ + PickedActor @ + ", HitLocation = " @ HitLocation @ + ", Zone Touched = " @ Zone); + + KickAngle = 15 * DegToRad; + ImpulseDir = (Normal(Vector(Pawn.Rotation)) * cos(KickAngle)) + (vect(0,0,1) * sin(KickAngle)); + ImpulseMag = 500; + + ApplyForceRigidBody(PickedActor,ImpulseDir,ImpulseMag,HitLocation); + + + WorldInfo.Game.Broadcast(self,"Pawn.Rotation = " @ + Normal(Vector(Pawn.Rotation)) ); + + } + else + if(EventType == ZoneEvent_Update) + { + + } + else + if (EventType == ZoneEvent_UnTouch) + { + + } + + + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + + } + } +} + +defaultproperties +{ + PickDistance = 10000; +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.3/Classes/RigidBodyCube.uc b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.3/Classes/RigidBodyCube.uc new file mode 100644 index 0000000..578601f --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch04/Example 4.3/Classes/RigidBodyCube.uc @@ -0,0 +1,89 @@ +class RigidBodyCube extends KActor +placeable; + +var ParticleSystem ExplosionTemplate; +var ParticleSystemComponent Explosion; + +var vector OutOfViewLocation; +var float MinimumForceToExplode; +var bool bDestroyed; + +/** Called when a PrimitiveComponent this Actor owns has: + * -bNotifyRigidBodyCollision set to true + * -ScriptRigidBodyCollisionThreshold > 0 + * -it is involved in a physics collision where the relative velocity exceeds ScriptRigidBodyCollisionThreshold + * + * @param HitComponent the component of this Actor that collided + * @param OtherComponent the other component that collided + * @param RigidCollisionData information on the collision itslef, including contact points + * @param ContactIndex the element in each ContactInfos' ContactVelocity and PhysMaterial arrays that corresponds + * to this Actor/HitComponent + */ +event RigidBodyCollision(PrimitiveComponent HitComponent, + PrimitiveComponent OtherComponent, + const out CollisionImpactData RigidCollisionData, + int ContactIndex) +{ + local vector ExplosionLocation; + local float CollisionForce; + + + + WorldInfo.Game.Broadcast(self,"RigidBodyCube COLLISION!!!! - " @ self @ + ", HitComponent = " @ Hitcomponent @ + " Has Collided with " @ OtherComponent @ + " With FOrce " @ VSize(RigidCollisionData.TotalNormalForceVector)); + + + CollisionForce = VSize(RigidCollisionData.TotalNormalForceVector); + + + if (CollisionForce >= MinimumForceToExplode) + { + // Spawn Explosion Emitter + ExplosionLocation = HitComponent.Bounds.Origin; + Explosion = WorldInfo.MyEmitterPool.SpawnEmitter(ExplosionTemplate, ExplosionLocation); + + // Object has been Destroyed + bDestroyed = true; + + // Move Rigid Body out of view + HitComponent.SetRBPosition(OutOfViewLocation); + SetPhysics(Phys_None); + } + +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=RigidBodyCubeMesh + StaticMesh=StaticMesh'EngineMeshes.Cube' + CollideActors=true + BlockActors=true + BlockRigidBody=true + bNotifyRigidBodyCollision=true + ScriptRigidBodyCollisionThreshold=0.001 + RBChannel=RBCC_GameplayPhysics + RBCollideWithChannels=(Default=TRUE,BlockingVolume=TRUE,GameplayPhysics=TRUE,EffectPhysics=TRUE) + End Object + StaticMeshComponent=RigidBodyCubeMesh + Components.Add(RigidBodyCubeMesh) + + CollisionComponent = RigidBodyCubeMesh + + + bWakeOnLevelStart = true + bEdShouldSnap = false + + Physics = PHYS_RigidBody + BlockRigidBody = true + bBlockActors = true + bCollideActors = true + + MinimumForceToExplode = 370; + bDestroyed = false + OutOfViewLocation = (X = 0, Y = 0, Z = -5000) + + ExplosionTemplate = ParticleSystem'Castle_Assets.FX.P_FX_Fire_SubUV_01' +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/BotController.uc b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/BotController.uc new file mode 100644 index 0000000..7d9503b --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/BotController.uc @@ -0,0 +1,142 @@ +class BotController extends UDKBot; + +var Actor CurrentGoal; +var Vector TempDest; +var float FollowDistance; +var Actor TempGoal; + + +////////////////////////////////////////// PAthnode Related Functions ////////////////////////////////////////////////// +/* +state FollowTarget +{ + Begin: + + //WorldInfo.Game.Broadcast(self,"BotController-USING PATHNODES FOR FOLLOWTARGET STATE"); + + // Move Bot to Target + if (CurrentGoal != None) + { + TempGoal = FindPathToward(CurrentGoal); + + if (ActorReachable(CurrentGoal)) + { + MoveTo(CurrentGoal.Location, ,FollowDistance); + } + else + if (TempGoal != None) + { + MoveToward(TempGoal); + } + else + { + //give up because the nav mesh failed to find a path + `warn("PATCHNODES failed to find a path!"); + WorldInfo.Game.Broadcast(self,"PATHNODES failed to find a path!, CurrentGoal = " @ CurrentGoal); + MoveTo(Pawn.Location); + } + } + LatentWhatToDoNext(); +} +*/ + +////////////////////////////////////////// Navigation Mesh Related Functions ////////////////////////////////////////////// + +event bool GeneratePathTo(Actor Goal, optional float WithinDistance, optional bool bAllowPartialPath) +{ + if( NavigationHandle == None ) + return FALSE; + + // Clear cache and constraints (ignore recycling for the moment) + NavigationHandle.PathConstraintList = none; + NavigationHandle.PathGoalList = none; + + class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle, Goal ); + class'NavMeshGoal_At'.static.AtActor( NavigationHandle, Goal, WithinDistance, bAllowPartialPath ); + + return NavigationHandle.FindPath(); +} + +state FollowTarget +{ + Begin: + + WorldInfo.Game.Broadcast(self,"BotController-USING NAVMESH FOR FOLLOWTARGET STATE"); + + // Move Bot to Target + if (CurrentGoal != None) + { + if(GeneratePathTo(CurrentGoal)) + { + NavigationHandle.SetFinalDestination(CurrentGoal.Location); + if( NavigationHandle.ActorReachable(CurrentGoal) ) + { + // then move directly to the actor + MoveTo(CurrentGoal.Location, ,FollowDistance); + } + else + { + // move to the first node on the path + if( NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()) ) + { + // suggest move preparation will return TRUE when the edge's + // logic is getting the bot to the edge point + // FALSE if we should run there ourselves + if (!NavigationHandle.SuggestMovePreparation(TempDest,self)) + { + MoveTo(TempDest); + } + } + } + } + else + { + //give up because the nav mesh failed to find a path + `warn("FindNavMeshPath failed to find a path!"); + WorldInfo.Game.Broadcast(self,"FindNavMeshPath failed to find a path!, CurrentGoal = " @ CurrentGoal); + MoveTo(Pawn.Location); + } + } + LatentWhatToDoNext(); +} + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +auto state Initial +{ + Begin: + + LatentWhatToDoNext(); +} + +/** triggers ExecuteWhatToDoNext() to occur during the next tick + * this is also where logic that is unsafe to do during the physics tick should be added + * @note: in state code, you probably want LatentWhatToDoNext() so the state is paused while waiting for ExecuteWhatToDoNext() to be called + */ +event WhatToDoNext() +{ + DecisionComponent.bTriggered = true; +} + +/** entry point for AI decision making + * this gets executed during the physics tick so actions that could change the physics state (e.g. firing weapons) are not allowed + */ +protected event ExecuteWhatToDoNext() +{ + if (IsInState('Initial')) + { + GotoState('FollowTarget', 'Begin'); + } + else + { + GotoState('FollowTarget', 'Begin'); + } +} + +defaultproperties +{ + CurrentGoal = None; + FollowDistance = 700; +} diff --git a/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/BotMarker.uc b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/BotMarker.uc new file mode 100644 index 0000000..915c565 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/BotMarker.uc @@ -0,0 +1,35 @@ +class BotMarker extends Actor; + +event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + //WorldInfo.Game.Broadcast(self,"BotMarker Has Been Touched"); +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=StaticMeshComponent0 + //StaticMesh=StaticMesh'EngineMeshes.Cube' + StaticMesh=StaticMesh'EngineMeshes.Sphere' + //Translation=(X=0.000000,Y=0.000000,Z=0.000000) + Scale3D=(X=0.250000,Y=0.250000,Z=0.25000) + //CollideActors=false + //bAllowApproximateOcclusion=True + //bForceDirectLightMap=True + //bCastDynamicShadow=False + //LightingChannels=(Dynamic=False,Static=True) + End Object + Components.Add(StaticMeshComponent0) + + Begin Object Class=CylinderComponent NAME=CollisionCylinder + CollideActors=true + CollisionRadius=+0040.000000 + CollisionHeight=+0040.000000 + End Object + CollisionComponent=CollisionCylinder + Components.Add(CollisionCylinder) + + bCollideActors=true + //bStatic=false + //bMovable=true + //bEdShouldSnap=True +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/BotPawn.uc b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/BotPawn.uc new file mode 100644 index 0000000..4b576ab --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/BotPawn.uc @@ -0,0 +1,84 @@ +class BotPawn extends SimplePawn; + +var Inventory MainGun; +var SoundCue JazzHitSound; +var vector InitialLocation; + + +event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + PlaySound(JazzHitSound); + Health = Health - Damage; + WorldInfo.Game.Broadcast(self,self @ " Has Taken Damage IN TAKEDAMAGE, HEALTH = " @ Health); + + if (Health <= 0) + { + SetLocation(InitialLocation); + SetPhysics(PHYS_Falling); + Health = 100; + } +} + +function AddGunToSocket(Name SocketName) +{ + local Vector SocketLocation; + local Rotator SocketRotation; + + if (Mesh != None) + { + if (Mesh.GetSocketByName(SocketName) != None) + { + Mesh.GetSocketWorldLocationAndRotation(SocketName, SocketLocation, SocketRotation); + MainGun.SetRotation(SocketRotation); + MainGun.SetBase(Self,, Mesh, SocketName); + } + else + { + WorldInfo.Game.Broadcast(self,"!!!!!!SOCKET NAME NOT FOUND!!!!!"); + } + } + else + { + WorldInfo.Game.Broadcast(self,"!!!!!!MESH NOT FOUND!!!!!"); + } + +} + +function AddDefaultInventory() +{ + MainGun = InvManager.CreateInventory(class'JazzWeapon2Damage'); + MainGun.SetHidden(false); + AddGunToSocket('Weapon_R'); + Weapon(MainGun).FireOffset = vect(0,13,-70); +} + +defaultproperties +{ + // Jazz Mesh Object + Begin Object Class=SkeletalMeshComponent Name=JazzMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_Jazz' + AnimSets(0)=AnimSet'KismetGame_Assets.Anims.SK_Jazz_Anims' + AnimTreeTemplate=AnimTree'KismetGame_Assets.Anims.Jazz_AnimTree' + BlockRigidBody=true + CollideActors=true + End Object + Mesh = JazzMesh; + Components.Add(JazzMesh); + + // Collision Component for This actor + Begin Object Class=CylinderComponent NAME=CollisionCylinder2 + CollideActors=true + CollisionRadius=+25.000000 + //CollisionHeight=+45.000000 // Path Nodes + CollisionHeight=+60.000000 //Nav Mesh + //CollisionHeight=+78.000000 + End Object + CollisionComponent=CollisionCylinder2 + CylinderComponent=CollisionCylinder2 + Components.Add(CollisionCylinder2) + + JazzHitSound = SoundCue'KismetGame_Assets.Sounds.Jazz_Death_Cue' + InventoryManagerClass=class'ExampleCh5.WeaponsCh5IM1' +} + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/ExampleCh5Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/ExampleCh5Game.uc new file mode 100644 index 0000000..5ce3c4b --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/ExampleCh5Game.uc @@ -0,0 +1,30 @@ +class ExampleCh5Game extends FrameworkGame; + + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh5Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh5.ExampleCh5PC' + + DefaultPawnClass=class'ExampleCh5.JazzPawnDamage' + HUDType=class'UDKBase.UDKHUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/ExampleCh5PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/ExampleCh5PC.uc new file mode 100644 index 0000000..9937632 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/ExampleCh5PC.uc @@ -0,0 +1,168 @@ +class ExampleCh5PC extends SimplePC; + +var Controller FollowBot; +Var Pawn FollowPawn; +var bool BotSpawned; +var Actor BotTarget; + +var float PickDistance; + + +function Actor PickActor(Vector2D PickLocation, out Vector HitLocation, out TraceHitInfo HitInfo) +{ + local Vector TouchOrigin, TouchDir; + local Vector HitNormal; + local Actor PickedActor; + local vector Extent; + + //Transform absolute screen coordinates to relative coordinates + PickLocation.X = PickLocation.X / ViewportSize.X; + PickLocation.Y = PickLocation.Y / ViewportSize.Y; + + //Transform to world coordinates to get pick ray + LocalPlayer(Player).Deproject(PickLocation, TouchOrigin, TouchDir); + + //Perform trace to find touched actor + Extent = vect(0,0,0); + PickedActor = Trace(HitLocation, + HitNormal, + TouchOrigin + (TouchDir * PickDistance), + TouchOrigin, + True, + Extent, + HitInfo); + + //Return the touched actor for good measure + return PickedActor; +} + +reliable server function ExecuteBotMoveCommand(Vector HitLocation) +{ + // 1. Set AttackMove Target Marker + Hitlocation.z += 50; // Add offset to help bot navigate to point + If (BotTarget == None) + { + WorldInfo.Game.Broadcast(None,"Creating New Move Marker!!!!!!!!"); + BotTarget = Spawn(class'BotMarker',,,HitLocation); + } + else + { + BotTarget.SetLocation(HitLocation); + } + + // 2. Send Move Command to bot along with target location + BotController(FollowBot).CurrentGoal = BotTarget; + BotController(FollowBot).FollowDistance = 75; +} + + + +function SpawnBot(Vector SpawnLocation) +{ + SpawnLocation.z = SpawnLocation.z + 500; + //WorldInfo.Game.Broadcast(self,"SPAWNING A BOT AT LOCATION " @ Spawnlocation); + + FollowBot = Spawn(class'BotController',,,SpawnLocation); + FollowPawn = Spawn(class'BotPawn',,,SpawnLocation); + FollowBot.Possess(FollowPawn,false); + + BotController(FollowBot).CurrentGoal = Pawn; + Botpawn(FollowPawn).AddDefaultInventory(); + BotPawn(Followpawn).InitialLocation = SpawnLocation; + + FollowPawn.SetPhysics(PHYS_Falling); + + BotSpawned = true; +} + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + local Vector HitLocation; + local TraceHitInfo HitInfo; + + retval = true; + + + if (EventType == ZoneEvent_Touch) + { + WorldInfo.Game.Broadcast(self,"You touched the screen at = " @ + TouchLocation.x @ " , " @ TouchLocation.y @ + ", Zone Touched = " @ Zone); + + + // Start Firing pawn's weapon + StartFire(0); + + // Start Firing the Bot's Weapon + FollowBot.Pawn.StartFire(0); + + // Code for Setting Bot WayPoint + PickActor(TouchLocation, HitLocation, HitInfo); + ExecuteBotMoveCommand(HitLocation); + } + else + if(EventType == ZoneEvent_Update) + { + + } + else + if (EventType == ZoneEvent_UnTouch) + { + // Stop Firing Pawn's weapon + StopFire(0); + + // Stop Firing the Bot's weapon + FollowBot.Pawn.StopFire(0); + } + + + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + + } + } +} + +function PlayerTick(float DeltaTime) +{ + Super.PlayerTick(DeltaTime); + + + if (!BotSpawned) + { + SpawnBot(Pawn.Location); + BotSpawned = true; + + JazzPawnDamage(Pawn).InitialLocation = Pawn.Location; + + } +} + +defaultproperties +{ + BotSpawned=false + PickDistance = 10000 +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzBullet2Damage.uc b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzBullet2Damage.uc new file mode 100644 index 0000000..bab6b9c --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzBullet2Damage.uc @@ -0,0 +1,35 @@ +class JazzBullet2Damage extends Projectile; + + +simulated singular event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + Other.TakeDamage(33, InstigatorController, HitLocation, -HitNormal, None); +} + +simulated function Explode(vector HitLocation, vector HitNormal) +{ + SetPhysics(Phys_Falling); +} + +function Init( Vector Direction ) +{ + super.Init(Direction); + RandSpin(90000); +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=Bullet + StaticMesh=StaticMesh'Castle_Assets.Meshes.SM_RiverRock_01' + Scale3D=(X=0.300000,Y=0.30000,Z=0.3000) + End Object + Components.Add(Bullet) + + Begin Object Class=ParticleSystemComponent Name=BulletTrail + Template=ParticleSystem'Castle_Assets.FX.P_FX_Fire_SubUV_01' + End Object + Components.Add(BulletTrail) + + MaxSpeed=+05000.000000 + Speed=+05000.000000 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzBulletDamage.uc b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzBulletDamage.uc new file mode 100644 index 0000000..bb1c0a5 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzBulletDamage.uc @@ -0,0 +1,37 @@ +class JazzBulletDamage extends Projectile; + + +simulated function Explode(vector HitLocation, vector HitNormal) +{ + +} + +simulated singular event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + Other.TakeDamage(33, InstigatorController, HitLocation, -HitNormal, None); +} + +function Init( Vector Direction ) +{ + local vector NewDir; + + NewDir = Normal(Vector(InstigatorController.Pawn.Rotation)); + Velocity = Speed * NewDir; +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=Bullet + StaticMesh=StaticMesh'EngineMeshes.Sphere' + Scale3D=(X=0.050000,Y=0.050000,Z=0.05000) + End Object + Components.Add(Bullet) + + Begin Object Class=ParticleSystemComponent Name=BulletTrail + Template=ParticleSystem'Castle_Assets.FX.P_FX_Fire_SubUV_01' + End Object + Components.Add(BulletTrail) + + MaxSpeed=+05000.000000 + Speed=+05000.000000 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzPawnDamage.uc b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzPawnDamage.uc new file mode 100644 index 0000000..4583616 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzPawnDamage.uc @@ -0,0 +1,146 @@ +class JazzPawnDamage extends SimplePawn; + + +var float CamOffsetDistance; +var int CamAngle; +var Inventory MainGun; +var vector InitialLocation; + +var SoundCue PawnHitSound; + + +event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + PlaySound(PawnHitSound); + Health = Health - Damage; + WorldInfo.Game.Broadcast(self,self @ " Has Taken Damage IN TAKEDAMAGE, HEALTH = " @ Health); + + if (Health <= 0) + { + SetLocation(InitialLocation); + SetPhysics(PHYS_Falling); + Health = 100; + } +} + +simulated singular event Rotator GetBaseAimRotation() +{ + local rotator TempRot; + + TempRot = Rotation; + TempRot.Pitch = 0; + + SetRotation(TempRot); + + + return TempRot; +} + +function AddGunToSocket(Name SocketName) +{ + local Vector SocketLocation; + local Rotator SocketRotation; + + if (Mesh != None) + { + if (Mesh.GetSocketByName(SocketName) != None) + { + Mesh.GetSocketWorldLocationAndRotation(SocketName, SocketLocation, SocketRotation); + + MainGun.SetRotation(SocketRotation); + MainGun.SetBase(Self,, Mesh, SocketName); + + } + else + { + WorldInfo.Game.Broadcast(self,"!!!!!!SOCKET NAME NOT FOUND!!!!!"); + } + } + else + { + WorldInfo.Game.Broadcast(self,"!!!!!!MESH NOT FOUND!!!!!"); + } + +} + + +function AddDefaultInventory() +{ + MainGun = InvManager.CreateInventory(class'JazzWeaponDamage'); + MainGun.SetHidden(false); + + AddGunToSocket('Weapon_R'); + + Weapon(MainGun).FireOffset = vect(0,0,-70); +} + +// Iso Cam +/* +simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) +{ + out_CamLoc = Location; + out_CamLoc.X += Cos(CamAngle * UnrRotToRad) * CamOffsetDistance; + out_CamLoc.Z += Sin(CamAngle * UnrRotToRad) * CamOffsetDistance; + + out_CamRot.Pitch = -1 * CamAngle; + out_CamRot.Yaw = 32000; + out_CamRot.Roll = 0; + + return true; +} +*/ + +/////////////////////////////////////////////// Third Person View ///////////////////////////////////////////////////// + +simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) +{ + local vector BackVector; + local vector UpVector; + + local float CamDistanceHorizontal; + local float CamDistanceVertical; + + + + // Set Camera Location + CamDistanceHorizontal = CamOffsetDistance * cos(CamAngle * UnrRotToRad); + CamDistanceVertical = CamOffsetDistance * sin(CamAngle * UnrRotToRad); + + BackVector = -Normal(Vector(Rotation)) * CamDistanceHorizontal; + UpVector = vect(0,0,1) * CamDistanceVertical; + + out_CamLoc = Location + BackVector + UpVector; + + // Set Camera Rotation + out_CamRot.pitch = -CamAngle; + out_CamRot.yaw = Rotation.yaw; + out_CamRot.roll = Rotation.roll; + + return true; +} + +defaultproperties +{ + Begin Object Class=SkeletalMeshComponent Name=JazzMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_Jazz' + AnimSets(0)=AnimSet'KismetGame_Assets.Anims.SK_Jazz_Anims' + AnimTreeTemplate=AnimTree'KismetGame_Assets.Anims.Jazz_AnimTree' + BlockRigidBody=true + CollideActors=true + End Object + + Mesh = JazzMesh; // Set The mesh for this object + Components.Add(JazzMesh); // Attach this mesh to this Actor + + + CamAngle=3000; + CamOffsetDistance= 484.0 + + InventoryManagerClass=class'ExampleCh5.WeaponsCh5IM1' + + PawnHitSound = SoundCue'A_Character_CorruptEnigma_Cue.Mean_Efforts.A_Effort_EnigmaMean_Death_Cue' +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzWeapon2Damage.uc b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzWeapon2Damage.uc new file mode 100644 index 0000000..3d929dc --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzWeapon2Damage.uc @@ -0,0 +1,26 @@ +class JazzWeapon2Damage extends Weapon; + +defaultproperties +{ + Begin Object Class=SkeletalMeshComponent Name=FirstPersonMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + Mesh=FirstPersonMesh + Components.Add(FirstPersonMesh); + + Begin Object Class=SkeletalMeshComponent Name=PickupMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + DroppedPickupMesh=PickupMesh + PickupFactoryMesh=PickupMesh + + WeaponFireTypes(0)=EWFT_Projectile + WeaponFireTypes(1)=EWFT_NONE + + WeaponProjectiles(0)=class'JazzBullet2Damage' + WeaponProjectiles(1)=class'JazzBullet2Damage' + + FiringStatesArray(0)=WeaponFiring + FireInterval(0)=0.25 + Spread(0)=0 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzWeaponDamage.uc b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzWeaponDamage.uc new file mode 100644 index 0000000..189d97a --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/JazzWeaponDamage.uc @@ -0,0 +1,26 @@ +class JazzWeaponDamage extends Weapon; + +defaultproperties +{ + Begin Object Class=SkeletalMeshComponent Name=FirstPersonMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + Mesh=FirstPersonMesh + Components.Add(FirstPersonMesh); + + Begin Object Class=SkeletalMeshComponent Name=PickupMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + DroppedPickupMesh=PickupMesh + PickupFactoryMesh=PickupMesh + + WeaponFireTypes(0)=EWFT_Projectile + WeaponFireTypes(1)=EWFT_NONE + + WeaponProjectiles(0)=class'JazzBulletDamage' + WeaponProjectiles(1)=class'JazzBulletDamage' + + FiringStatesArray(0)=WeaponFiring + FireInterval(0)=0.25 + Spread(0)=0 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/WeaponsCh5IM1.uc b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/WeaponsCh5IM1.uc new file mode 100644 index 0000000..ea20cfa --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch05/ExampleCh5/Classes/WeaponsCh5IM1.uc @@ -0,0 +1,7 @@ +class WeaponsCh5IM1 extends InventoryManager; + +defaultproperties +{ + PendingFire(0)=0 + PendingFire(1)=0 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/BotControllerAttack.uc b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/BotControllerAttack.uc new file mode 100644 index 0000000..90cd23b --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/BotControllerAttack.uc @@ -0,0 +1,164 @@ +class BotControllerAttack extends UDKBot; + +var Actor CurrentGoal; +var Vector TempDest; +var float FollowDistance; +var Actor TempGoal; + + +////////////////////////////////////////// PAthnode Related Functions ////////////////////////////////////////////////// +/* +state FollowTarget +{ + Begin: + + //WorldInfo.Game.Broadcast(self,"BotController-USING PATHNODES FOR FOLLOWTARGET STATE"); + + // Move Bot to Target + if (CurrentGoal != None) + { + TempGoal = FindPathToward(CurrentGoal); + + if (ActorReachable(CurrentGoal)) + { + MoveTo(CurrentGoal.Location, ,FollowDistance); + } + else + if (TempGoal != None) + { + MoveToward(TempGoal); + } + else + { + //give up because the nav mesh failed to find a path + `warn("PATCHNODES failed to find a path!"); + WorldInfo.Game.Broadcast(self,"PATHNODES failed to find a path!, CurrentGoal = " @ CurrentGoal); + MoveTo(Pawn.Location); + } + } + LatentWhatToDoNext(); +} +*/ + +////////////////////////////////////////// Navigation Mesh Related Functions ////////////////////////////////////////////// + +event bool GeneratePathTo(Actor Goal, optional float WithinDistance, optional bool bAllowPartialPath) +{ + if( NavigationHandle == None ) + return FALSE; + + // Clear cache and constraints (ignore recycling for the moment) + NavigationHandle.PathConstraintList = none; + NavigationHandle.PathGoalList = none; + + class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle, Goal ); + class'NavMeshGoal_At'.static.AtActor( NavigationHandle, Goal, WithinDistance, bAllowPartialPath ); + + return NavigationHandle.FindPath(); +} + +state FollowTarget +{ + Begin: + + WorldInfo.Game.Broadcast(self,"BotController-USING NAVMESH FOR FOLLOWTARGET STATE"); + + // Move Bot to Target + if (CurrentGoal != None) + { + if(GeneratePathTo(CurrentGoal)) + { + NavigationHandle.SetFinalDestination(CurrentGoal.Location); + if( NavigationHandle.ActorReachable(CurrentGoal) ) + { + // then move directly to the actor + MoveTo(CurrentGoal.Location, CurrentGoal,FollowDistance); + GotoState('Firing', 'Begin'); + } + else + { + // move to the first node on the path + if( NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()) ) + { + // suggest move preparation will return TRUE when the edge's + // logic is getting the bot to the edge point + // FALSE if we should run there ourselves + if (!NavigationHandle.SuggestMovePreparation(TempDest,self)) + { + MoveTo(TempDest); + } + } + } + } + else + { + //give up because the nav mesh failed to find a path + `warn("FindNavMeshPath failed to find a path!"); + WorldInfo.Game.Broadcast(self,"FindNavMeshPath failed to find a path!, CurrentGoal = " @ CurrentGoal); + MoveTo(Pawn.Location); + } + } + LatentWhatToDoNext(); +} + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +state Firing +{ + + Begin: + + WorldInfo.Game.Broadcast(self,"BotController-IN Firing State"); + + Sleep(3); + Pawn.StartFire(0); + Sleep(0.5); + + LatentWhatToDoNext(); +} + +auto state Initial +{ + Begin: + + LatentWhatToDoNext(); +} + +/** triggers ExecuteWhatToDoNext() to occur during the next tick + * this is also where logic that is unsafe to do during the physics tick should be added + * @note: in state code, you probably want LatentWhatToDoNext() so the state is paused while waiting for ExecuteWhatToDoNext() to be called + */ +event WhatToDoNext() +{ + DecisionComponent.bTriggered = true; +} + +/** entry point for AI decision making + * this gets executed during the physics tick so actions that could change the physics state (e.g. firing weapons) are not allowed + */ +protected event ExecuteWhatToDoNext() +{ + if (IsInState('Initial')) + { + GotoState('FollowTarget', 'Begin'); + } + else + if (IsInState('Firing')) + { + Pawn.StopFire(0); + GotoState('FollowTarget', 'Begin'); + } + else + { + GotoState('FollowTarget', 'Begin'); + } + +} + +defaultproperties +{ + CurrentGoal = None; + FollowDistance = 700; +} diff --git a/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/BotPawn2.uc b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/BotPawn2.uc new file mode 100644 index 0000000..6e4cee3 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/BotPawn2.uc @@ -0,0 +1,98 @@ +class BotPawn2 extends SimplePawn; + +var Inventory MainGun; +var SoundCue JazzHitSound; +var vector InitialLocation; + +var int KillValue; + + +event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + PlaySound(JazzHitSound); + Health = Health - Damage; + WorldInfo.Game.Broadcast(self,self @ " Has Taken Damage IN TAKEDAMAGE, HEALTH = " @ Health); + + if (Health <= 0) + { + SetLocation(InitialLocation); + SetPhysics(PHYS_Falling); + Health = 100; + + // Process Kill + if (PlayerController(InstigatedBy) != None) + { + // Add kill to Player's Score + ExampleCh7PC(InstigatedBy).Score += KillValue; + } + } + + +} + +function AddGunToSocket(Name SocketName) +{ + local Vector SocketLocation; + local Rotator SocketRotation; + + if (Mesh != None) + { + if (Mesh.GetSocketByName(SocketName) != None) + { + Mesh.GetSocketWorldLocationAndRotation(SocketName, SocketLocation, SocketRotation); + MainGun.SetRotation(SocketRotation); + MainGun.SetBase(Self,, Mesh, SocketName); + } + else + { + WorldInfo.Game.Broadcast(self,"!!!!!!SOCKET NAME NOT FOUND!!!!!"); + } + } + else + { + WorldInfo.Game.Broadcast(self,"!!!!!!MESH NOT FOUND!!!!!"); + } + +} + +function AddDefaultInventory() +{ + MainGun = InvManager.CreateInventory(class'JazzWeapon2Damage'); + MainGun.SetHidden(false); + AddGunToSocket('Weapon_R'); + Weapon(MainGun).FireOffset = vect(0,13,-70); +} + +defaultproperties +{ + // Jazz Mesh Object + Begin Object Class=SkeletalMeshComponent Name=JazzMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_Jazz' + AnimSets(0)=AnimSet'KismetGame_Assets.Anims.SK_Jazz_Anims' + AnimTreeTemplate=AnimTree'KismetGame_Assets.Anims.Jazz_AnimTree' + BlockRigidBody=true + CollideActors=true + End Object + Mesh = JazzMesh; + Components.Add(JazzMesh); + + // Collision Component for This actor + Begin Object Class=CylinderComponent NAME=CollisionCylinder2 + CollideActors=true + CollisionRadius=+25.000000 + //CollisionHeight=+45.000000 // Path Nodes + CollisionHeight=+60.000000 //Nav Mesh + End Object + CollisionComponent=CollisionCylinder2 + CylinderComponent=CollisionCylinder2 + Components.Add(CollisionCylinder2) + + JazzHitSound = SoundCue'KismetGame_Assets.Sounds.Jazz_Death_Cue' + + InventoryManagerClass=class'WeaponsIM1' + + + KillValue = 50; +} + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/ExampleCh7Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/ExampleCh7Game.uc new file mode 100644 index 0000000..efc83fe --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/ExampleCh7Game.uc @@ -0,0 +1,30 @@ +class ExampleCh7Game extends FrameworkGame; + + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh7Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh7.ExampleCh7PC' + + DefaultPawnClass=class'Jazz3Pawn' + HUDType=class'ExtendedHUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/ExampleCh7PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/ExampleCh7PC.uc new file mode 100644 index 0000000..f8e7a77 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/ExampleCh7PC.uc @@ -0,0 +1,155 @@ +class ExampleCh7PC extends SimplePC; + +var Controller FollowBot; +Var Pawn FollowPawn; +var bool BotSpawned; + + +var bool GameOver; +var int Score; + + +function vector FindSpawnPadLocation() +{ + local SpawnPad TempSpawnPad; + local vector TempLocation; + + foreach AllActors (class 'SpawnPad', TempSpawnPad ) + { + TempLocation = TempSpawnPad.Location; + } + + return TempLocation; +} + +function SpawnBot(Vector SpawnLocation) +{ + SpawnLocation.z = SpawnLocation.z + 500; + WorldInfo.Game.Broadcast(self,"SPAWNING A BOT AT LOCATION " @ Spawnlocation); + + FollowBot = Spawn(class'BotControllerAttack',,,SpawnLocation); + FollowPawn = Spawn(class'BotPawn2',,,SpawnLocation); + FollowBot.Possess(FollowPawn,false); + + BotControllerAttack(FollowBot).CurrentGoal = Pawn; + Botpawn2(FollowPawn).AddDefaultInventory(); + BotPawn2(Followpawn).InitialLocation = SpawnLocation; + + FollowPawn.SetPhysics(PHYS_Falling); + + BotSpawned = true; +} + +function ResetGame() +{ + GameoVer = false; + Jazz3Pawn(Pawn).Lives = 3; + Score = 0; + Pawn.Health = 100; + + Pawn.SetHidden(false); + Pawn.Weapon.SetHidden(false); + Pawn.SetLocation(Jazz3Pawn(Pawn).InitialLocation); +} + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + + retval = true; + + + if (EventType == ZoneEvent_Touch) + { + WorldInfo.Game.Broadcast(self,"You touched the screen at = " @ + TouchLocation.x @ " , " @ TouchLocation.y @ + ", Zone Touched = " @ Zone); + + // Reset Game + if (GameOver) + { + ResetGame(); + } + else + { + // Start Firing pawn's weapon + StartFire(0); + } + + } + else + if(EventType == ZoneEvent_Update) + { + + } + else + if (EventType == ZoneEvent_UnTouch) + { + // Stop Firing Pawn's weapon + StopFire(0); + } + + + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + + } + } +} + +function PlayerTick(float DeltaTime) +{ + Super.PlayerTick(DeltaTime); + + if (!BotSpawned) + { + SpawnBot(FindSpawnPadLocation()); + BotSpawned = true; + + Jazz3Pawn(Pawn).InitialLocation = Pawn.Location; + Jazz3Pawn(Pawn).Lives = 3; + } + + If (Jazz3Pawn(Pawn).Lives <= 0) + { + GameoVer = true; + + // Disable Player Input + //MPI.bDisableTouchInput = true; + } + + if (GameOver) + { + Pawn.SetHidden(true); + Pawn.Weapon.SetHidden(true); + Pawn.Velocity = vect(0,0,0); + } +} + +defaultproperties +{ + GameOver = false; + BotSpawned = false; +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/ExtendedHUD.uc b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/ExtendedHUD.uc new file mode 100644 index 0000000..4cf1a61 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/ExtendedHUD.uc @@ -0,0 +1,132 @@ +class ExtendedHUD extends UDKHud; + +var Texture DefaultTexture1; +var Texture DefaultTexture2; +var Texture DefaultTexture3; +var Texture DefaultTexture4; +var Texture DefaultTexture5; + +struct HUDInfo +{ + var string Label; + var Vector2D TextLocation; + var Color TextColor; + var Vector2D Scale; +}; + +// HUD +var HUDInfo HUDHealth; +var HUDInfo HUDLives; +var HUDInfo HUDGameOver; +var HUDInfo HUDScore; + + +simulated function PostBeginPlay() +{ + Super.PostBeginPlay(); + + HUDHealth.Label = "Health:"; + HUDHealth.TextLocation.x = 1100; + HUDHealth.TextLocation.y = 50; + HUDHealth.TextColor.R = 0; + HUDHealth.TextColor.G = 0; + HUDHealth.TextColor.B = 255; + HUDHealth.Scale.X = 2; + HUDHealth.Scale.Y = 4; + + HUDLives.Label = "Lives:"; + HUDLives.TextLocation.x = 600; + HUDLives.TextLocation.y = 50; + HUDLives.TextColor.R = 0; + HUDLives.TextColor.G = 255; + HUDLives.TextColor.B = 0; + HUDLives.Scale.X = 2; + HUDLives.Scale.Y = 4; + + HUDGameOver.Label = "GAME OVER"; + HUDGameOver.TextLocation.x = 400; + HUDGameOver.TextLocation.y = 300; + HUDGameOver.TextColor.R = 255; + HUDGameOver.TextColor.G = 0; + HUDGameOver.TextColor.B = 255; + HUDGameOver.Scale.X = 7; + HUDGameOver.Scale.Y = 7; + + HUDScore.Label = "Score:"; + HUDScore.TextLocation.x = 0; + HUDScore.TextLocation.y = 50; + HUDScore.TextColor.R = 255; + HUDScore.TextColor.G = 0; + HUDScore.TextColor.B = 0; + HUDScore.Scale.X = 2; + HUDScore.Scale.Y = 4; +} + +function DrawHUDItem(HUDInfo Info, coerce string Value) +{ + local Vector2D TextSize; + + Canvas.SetDrawColor(Info.TextColor.R, Info.TextColor.G, Info.TextColor.B); + Canvas.SetPos(Info.TextLocation.X, Info.TextLocation.Y); + Canvas.DrawText(Info.Label, ,Info.Scale.X,Info.Scale.Y); + Canvas.TextSize(Info.Label, TextSize.X, TextSize.Y); + Canvas.SetPos(Info.TextLocation.X + (TextSize.X * Info.Scale.X), Info.TextLocation.Y); + Canvas.DrawText(Value, , Info.Scale.X, Info.Scale.Y); +} + +function DrawHUD() +{ + local int Lives; + + super.DrawHUD(); + + /* + // Blend Modes = BLEND_Opaque, BLEND_Additive, and BLEND_Modulate modes + Canvas.SetPos(0,0); + Canvas.DrawTextureBlended(DefaultTexture1, 1, BLEND_Opaque); + + Canvas.SetPos(150,0); + Canvas.DrawTextureBlended(DefaultTexture2, 1, BLEND_Additive); + + Canvas.SetPos(300,0); + Canvas.DrawTextureBlended(DefaultTexture3, 1, BLEND_Masked); + + Canvas.SetPos(450,0); + Canvas.DrawTextureBlended(DefaultTexture4, 1,BLEND_Masked); + + Canvas.SetPos(600,0); + Canvas.DrawTextureBlended(DefaultTexture5, 1, BLEND_Masked); + + */ + + + Canvas.Font = class'Engine'.static.GetLargeFont(); + + // Score + DrawHUDItem(HUDScore,ExampleCh7PC(PlayerOwner).Score); + + // Lives + Lives = Jazz3Pawn(PlayerOwner.Pawn).Lives; + DrawHUDItem(HUDLives, Lives); + + // Health + DrawHUDItem(HUDHealth,PlayerOwner.Pawn.Health); + + // Game Over + if (ExampleCh7PC(PlayerOwner).GameOVer) + { + DrawHUDItem(HUDGameOver, ""); + } + +} + +defaultProperties +{ + DefaultTexture1= Texture2D'EditorResources.Ambientcreatures' // Yellow Chick 32 by 32 + DefaultTexture2= Texture2D'EditorResources.Ammo' // Ammo Icon 32 by 32 + DefaultTexture3= Texture2D'EditorResources.LookTarget' // Target 32 by 32 + DefaultTexture4= Texture2D'EditorMaterials.Tick' // Green Check 32 by 32 + DefaultTexture5= Texture2D'EditorMaterials.GreyCheck' // Grey Check 32 by 32 + +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/Jazz3Pawn.uc b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/Jazz3Pawn.uc new file mode 100644 index 0000000..966b66b --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/Jazz3Pawn.uc @@ -0,0 +1,157 @@ +class Jazz3Pawn extends SimplePawn; + + +var float CamOffsetDistance; +var int CamAngle; + +var Inventory MainGun; +var vector InitialLocation; + +var SoundCue PawnHitSound; +var int Lives; + + +event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + PlaySound(PawnHitSound); + Health = Health - Damage; + WorldInfo.Game.Broadcast(self,self @ " Has Taken Damage IN TAKEDAMAGE, HEALTH = " @ Health); + + // If Died + if (Health <= 0) + { + // Reduce number of lives left if above 0 + if (Lives > 0) + { + Lives--; + } + + // If player has more lives left then use them + if (Lives > 0) + { + SetLocation(InitialLocation); + SetPhysics(PHYS_Falling); + Health = 100; + } + } +} + +simulated singular event Rotator GetBaseAimRotation() +{ + local rotator TempRot; + + TempRot = Rotation; + TempRot.Pitch = 0; + + SetRotation(TempRot); + + + return TempRot; +} + +function AddGunToSocket(Name SocketName) +{ + local Vector SocketLocation; + local Rotator SocketRotation; + + if (Mesh != None) + { + if (Mesh.GetSocketByName(SocketName) != None) + { + Mesh.GetSocketWorldLocationAndRotation(SocketName, SocketLocation, SocketRotation); + + MainGun.SetRotation(SocketRotation); + MainGun.SetBase(Self,, Mesh, SocketName); + + } + else + { + WorldInfo.Game.Broadcast(self,"!!!!!!SOCKET NAME NOT FOUND!!!!!"); + } + } + else + { + WorldInfo.Game.Broadcast(self,"!!!!!!MESH NOT FOUND!!!!!"); + } + +} + + +function AddDefaultInventory() +{ + MainGun = InvManager.CreateInventory(class'JazzWeaponSound'); + MainGun.SetHidden(false); + + AddGunToSocket('Weapon_R'); + + Weapon(MainGun).FireOffset = vect(0,0,-70); +} + +// Iso Cam +/* +simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) +{ + out_CamLoc = Location; + out_CamLoc.X += Cos(CamAngle * UnrRotToRad) * CamOffsetDistance; + out_CamLoc.Z += Sin(CamAngle * UnrRotToRad) * CamOffsetDistance; + + out_CamRot.Pitch = -1 * CamAngle; + out_CamRot.Yaw = 32000; + out_CamRot.Roll = 0; + + return true; +} +*/ + +/////////////////////////////////////////////// Third Person View ///////////////////////////////////////////////////// + +simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) +{ + local vector BackVector; + local vector UpVector; + + local float CamDistanceHorizontal; + local float CamDistanceVertical; + + + + // Set Camera Location + CamDistanceHorizontal = CamOffsetDistance * cos(CamAngle * UnrRotToRad); + CamDistanceVertical = CamOffsetDistance * sin(CamAngle * UnrRotToRad); + + BackVector = -Normal(Vector(Rotation)) * CamDistanceHorizontal; + UpVector = vect(0,0,1) * CamDistanceVertical; + + out_CamLoc = Location + BackVector + UpVector; + + // Set Camera Rotation + out_CamRot.pitch = -CamAngle; + out_CamRot.yaw = Rotation.yaw; + out_CamRot.roll = Rotation.roll; + + return true; +} + +defaultproperties +{ + Begin Object Class=SkeletalMeshComponent Name=JazzMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_Jazz' + AnimSets(0)=AnimSet'KismetGame_Assets.Anims.SK_Jazz_Anims' + AnimTreeTemplate=AnimTree'KismetGame_Assets.Anims.Jazz_AnimTree' + BlockRigidBody=true + CollideActors=true + End Object + + Mesh = JazzMesh; // Set The mesh for this object + Components.Add(JazzMesh); // Attach this mesh to this Actor + + CamAngle=3000; + CamOffsetDistance= 484.0 + + InventoryManagerClass=class'WeaponsIM1' + PawnHitSound = SoundCue'A_Character_CorruptEnigma_Cue.Mean_Efforts.A_Effort_EnigmaMean_Death_Cue' +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/JazzBulletSound.uc b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/JazzBulletSound.uc new file mode 100644 index 0000000..45459d3 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/JazzBulletSound.uc @@ -0,0 +1,56 @@ +class JazzBulletSound extends Projectile; + +var SoundCue FireSound; +var bool ImpactSoundPlayed; + + +simulated singular event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + Other.TakeDamage(33, InstigatorController, HitLocation, -HitNormal, None); +} + +simulated function Explode(vector HitLocation, vector HitNormal) +{ + if (!ImpactSOundPlayed) + { + PlaySound(ImpactSound); + ImpactSoundPlayed = true; + } +} + +function Init( Vector Direction ) +{ + local vector NewDir; + + NewDir = Normal(Vector(InstigatorController.Pawn.Rotation)); + Velocity = Speed * NewDir; + + PlaySound(SpawnSound); + PlaySound(FireSound, , , true,,); +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=Bullet + StaticMesh=StaticMesh'EngineMeshes.Sphere' + Scale3D=(X=0.050000,Y=0.050000,Z=0.05000) + End Object + Components.Add(Bullet) + + Begin Object Class=ParticleSystemComponent Name=BulletTrail + Template=ParticleSystem'Castle_Assets.FX.P_FX_Fire_SubUV_01' + End Object + Components.Add(BulletTrail) + + MaxSpeed=+05000.000000 + Speed=+05000.000000 + + + FireSound = SoundCue'A_Vehicle_Generic.Vehicle.Vehicle_Damage_FireLoop_Cue' + ImpactSound = SoundCue'KismetGame_Assets.Sounds.S_BulletImpact_01_Cue' + SpawnSound = SoundCue'A_Pickups_Powerups.PowerUps.A_Powerup_UDamage_SpawnCue' + + ImpactSoundPlayed = false +} + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/JazzWeaponSound.uc b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/JazzWeaponSound.uc new file mode 100644 index 0000000..82d5366 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/JazzWeaponSound.uc @@ -0,0 +1,26 @@ +class JazzWeaponSound extends Weapon; + +defaultproperties +{ + Begin Object Class=SkeletalMeshComponent Name=FirstPersonMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + Mesh=FirstPersonMesh + Components.Add(FirstPersonMesh); + + Begin Object Class=SkeletalMeshComponent Name=PickupMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + DroppedPickupMesh=PickupMesh + PickupFactoryMesh=PickupMesh + + WeaponFireTypes(0)=EWFT_Projectile + WeaponFireTypes(1)=EWFT_NONE + + WeaponProjectiles(0)=class'JazzBulletSound' + WeaponProjectiles(1)=class'JazzBulletSound' + + FiringStatesArray(0)=WeaponFiring + FireInterval(0)=0.25 + Spread(0)=0 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/SpawnPad.uc b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/SpawnPad.uc new file mode 100644 index 0000000..a39344c --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch07/ExampleCh7/Classes/SpawnPad.uc @@ -0,0 +1,27 @@ +class SpawnPad extends Actor +placeable; + +event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + WorldInfo.Game.Broadcast(self,"SpawnPad Has Been Touched"); +} + + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=StaticMeshComponent0 + StaticMesh=StaticMesh'HU_Deco.SM.Mesh.S_HU_Deco_SM_Metalbase01' + Scale3D=(X=0.250000,Y=0.250000,Z=0.25000) + End Object + Components.Add(StaticMeshComponent0) + + Begin Object Class=CylinderComponent NAME=CollisionCylinder + CollideActors=true + CollisionRadius=+0040.000000 + CollisionHeight=+0040.000000 + End Object + CollisionComponent=CollisionCylinder + Components.Add(CollisionCylinder) + + bCollideActors=true +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/BotCoverController.uc b/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/BotCoverController.uc new file mode 100644 index 0000000..342f2e7 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/BotCoverController.uc @@ -0,0 +1,247 @@ +class BotCoverController extends UDKBot; + +// Navigation +var Actor CurrentGoal; +var Vector TempDest; +var Actor TempGoal; + +// Cover Link +var CoverLink CurrentCover; +var bool BotInCover; + +// Bot's Enemy +var Pawn BotThreat; + + + +function UnclaimAllSlots() +{ + local CoverLink CoverNodePointer; + local CoverLink TempNodePointer; + local bool done; + + CoverNodePointer = WorldInfo.Coverlist; + + done = false; + while (!done) + { + CoverNodePointer.Unclaim(Pawn, 0, true); + + if (CoverNodePointer.NextCoverLink != None) + { + TempNodePointer = CoverNodePointer.NextCoverLink; + CoverNodePointer = TempNodePointer; + } + else + { + done = true; + } + } + + Pawn.ShouldCrouch(false); + BotInCover = false; +} + +function FindEnemyLocation(out vector EnemyLocation) +{ + EnemyLocation = BotThreat.Location; +} + +function CoverLink FindClosestEmptyCoverNodeWithinRange(Vector ThreatLocation, vector Position, float Radius) +{ + local CoverLink CoverNodePointer; + local CoverLink TempNodePointer; + local bool done; + + local CoverLink ValidCoverNode; + local bool SlotValid; + local bool SlotAvailable; + local bool NodeFound; + local int DefaultSlot; + + local float Dist2Cover; + local float ClosestCoverNode; + + + CoverNodePointer = WorldInfo.Coverlist; + DefaultSlot = 0; // Assume only 1 slot per cover node. + ClosestCoverNode = 999999999; + + ValidCoverNode = None; + NodeFound = false; + + done = false; + while (!done) + { + SlotValid = CoverLinkEx(CoverNodePointer).IsCoverSlotValid(0,ThreatLocation); + SlotAvailable = CoverLinkEx(CoverNodePointer).IsCoverSlotAvailable(0); + + Dist2Cover = VSize(CoverNodePointer.GetSlotLocation(DefaultSlot) - Position); + + if (SlotValid && SlotAvailable && (Dist2Cover < ClosestCoverNode)) + { + ValidCoverNode = CoverNodePointer; + ClosestCoverNode = Dist2Cover; + NodeFound = true; + } + + // Goto Next CoverNode + if (CoverNodePointer.NextCoverLink != None) + { + TempNodePointer = CoverNodePointer.NextCoverLink; + CoverNodePointer = TempNodePointer; + } + else + { + // No more Cover Nodes + done = true; + } + } + + if (!NodeFound) + { + WorldInfo.Game.Broadcast(self,"!!! Can Not Find Valid CoverNode"); + } + + return ValidCoverNode; +} + +function bool IsCurrentCoverValid() +{ + local bool RetVal; + local vector ThreatLoc; + + + RetVal = false; + + FindEnemyLocation(ThreatLoc); + RetVal = CoverLinkEx(CurrentCover).IsCoverSlotValid(0, ThreatLoc); + + return Retval; +} + +function PrepMoveToCover() +{ + local vector ThreatLoc; + local CoverLink NextCover; + + + FindEnemyLocation(ThreatLoc); + NextCover = FindClosestEmptyCoverNodeWithinRange(ThreatLoc, Pawn.Location, 9999999); + + + if (NextCover != None) + { + WorldInfo.Game.Broadcast(self, self @ " moving to Next Cover " @ NextCover); + CurrentCover = NextCover; + CurrentGoal = CurrentCover; + BotInCover = false; + UnclaimAllSlots(); + CurrentCover.Claim(Pawn, 0); + } +} + +event bool GeneratePathTo(Actor Goal, optional float WithinDistance, optional bool bAllowPartialPath) +{ + if( NavigationHandle == None ) + return FALSE; + + // Clear cache and constraints (ignore recycling for the moment) + NavigationHandle.PathConstraintList = none; + NavigationHandle.PathGoalList = none; + + class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle, Goal ); + class'NavMeshGoal_At'.static.AtActor( NavigationHandle, Goal, WithinDistance, bAllowPartialPath ); + + return NavigationHandle.FindPath(); +} + +state TakeCover +{ + Begin: + + //WorldInfo.Game.Broadcast(self,"NAVMESH, CurrentGoal = " @ CurrentGoal @ " , BotInCover = " @ BotInCover); + + if (CurrentGoal != None) + { + if(GeneratePathTo(CurrentGoal)) + { + NavigationHandle.SetFinalDestination(CurrentGoal.Location); + if( NavigationHandle.ActorReachable(CurrentGoal) ) + { + // then move directly to the actor + MoveTo(CurrentGoal.Location, BotThreat); + BotInCover = true; + } + else + { + // move to the first node on the path + if( NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()) ) + { + // suggest move preparation will return TRUE when the edge's + // logic is getting the bot to the edge point + // FALSE if we should run there ourselves + if (!NavigationHandle.SuggestMovePreparation(TempDest,self)) + { + MoveTo(TempDest, BotThreat); + } + } + } + } + else + { + //give up because the nav mesh failed to find a path + WorldInfo.Game.Broadcast(self,"FindNavMeshPath failed to find a path!, CurrentGoal = " @ CurrentGoal); + MoveTo(Pawn.Location); + } + } + LatentWhatToDoNext(); +} + +auto state Initial +{ + Begin: + LatentWhatToDoNext(); +} + +event WhatToDoNext() +{ + DecisionComponent.bTriggered = true; +} + +protected event ExecuteWhatToDoNext() +{ + if (IsInState('Initial')) + { + PrepMoveToCover(); + GotoState('TakeCover', 'Begin'); + } + else + if (IsInState('TakeCover')) + { + if (BotInCover) + { + //Pawn.StopFire(0); + if (IsCurrentCoverValid()) + { + GotoState('TakeCover', 'Begin'); + } + else + { + PrepMoveToCover(); + GotoState('TakeCover', 'Begin'); + //Pawn.StartFire(0); + } + } + else + { + GotoState('TakeCover', 'Begin'); + } + } +} + +defaultproperties +{ + CurrentGoal = None; + BotInCover = false; +} diff --git a/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/BotCoverPawn.uc b/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/BotCoverPawn.uc new file mode 100644 index 0000000..e947d81 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/BotCoverPawn.uc @@ -0,0 +1,82 @@ +class BotCoverPawn extends SimplePawn; + +var Inventory MainGun; +var SoundCue JazzHitSound; +var vector InitialLocation; + + +event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + PlaySound(JazzHitSound); + Health = Health - Damage; + WorldInfo.Game.Broadcast(self,self @ " Has Taken Damage IN TAKEDAMAGE, HEALTH = " @ Health); + + if (Health <= 0) + { + SetLocation(InitialLocation); + SetPhysics(PHYS_Falling); + Health = 100; + } +} + +function AddGunToSocket(Name SocketName) +{ + local Vector SocketLocation; + local Rotator SocketRotation; + + if (Mesh != None) + { + if (Mesh.GetSocketByName(SocketName) != None) + { + Mesh.GetSocketWorldLocationAndRotation(SocketName, SocketLocation, SocketRotation); + MainGun.SetRotation(SocketRotation); + MainGun.SetBase(Self,, Mesh, SocketName); + } + else + { + WorldInfo.Game.Broadcast(self,"!!!!!!SOCKET NAME NOT FOUND!!!!!"); + } + } + else + { + WorldInfo.Game.Broadcast(self,"!!!!!!MESH NOT FOUND!!!!!"); + } + +} + +function AddDefaultInventory() +{ + MainGun = InvManager.CreateInventory(class'JazzWeapon2Damage'); + MainGun.SetHidden(false); + AddGunToSocket('Weapon_R'); + Weapon(MainGun).FireOffset = vect(0,13,-70); +} + +defaultproperties +{ + // Jazz Mesh Object + Begin Object Class=SkeletalMeshComponent Name=JazzMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_Jazz' + AnimSets(0)=AnimSet'KismetGame_Assets.Anims.SK_Jazz_Anims' + AnimTreeTemplate=AnimTree'KismetGame_Assets.Anims.Jazz_AnimTree' + BlockRigidBody=true + CollideActors=true + End Object + Mesh = JazzMesh; + Components.Add(JazzMesh); + + // Collision Component for This actor + Begin Object Class=CylinderComponent NAME=CollisionCylinder2 + CollideActors=true + CollisionRadius=+15.000000 + CollisionHeight=+45.000000 + End Object + CollisionComponent=CollisionCylinder2 + CylinderComponent=CollisionCylinder2 + Components.Add(CollisionCylinder2) + + JazzHitSound = SoundCue'KismetGame_Assets.Sounds.Jazz_Death_Cue' + InventoryManagerClass=class'WeaponsIM1' +} + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/CoverLinkEx.uc b/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/CoverLinkEx.uc new file mode 100644 index 0000000..854747c --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/CoverLinkEx.uc @@ -0,0 +1,53 @@ +class CoverLinkEx extends CoverLink; + +var() float CoverProtectionAngle; + + +function bool IsCoverSlotValid(int SlotIndex, vector ThreatLocation) +{ + local bool Valid; + + local vector SlotLocation; + local Rotator SlotRotation; + local vector SlotNormal; + + local vector DirectionToThreat; + local float AngleDegrees; + + + Valid = false; + + SlotLocation = GetSlotLocation(SlotIndex); + SlotRotation = GetSlotRotation(SlotIndex); + + SlotNormal = Normal(Vector(SlotRotation)); + DirectionToThreat = Normal(ThreatLocation - SlotLocation); + + AngleDegrees = acos(SlotNormal Dot DirectionToThreat) * RadToDeg; + + if (AngleDegrees < CoverProtectionAngle) + { + Valid = true; + } + + return Valid; +} + +function bool IsCoverSlotAvailable(int SlotIndex) +{ + local bool SlotAvailable; + + SlotAvailable = false; + + if (Slots[SlotIndex].SlotOwner == None) + { + SlotAvailable = true; + } + + return SlotAvailable; +} + +defaultproperties +{ + CoverProtectionAngle = 45.0 +} diff --git a/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/ExampleCh8Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/ExampleCh8Game.uc new file mode 100644 index 0000000..549d0e1 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/ExampleCh8Game.uc @@ -0,0 +1,30 @@ +class ExampleCh8Game extends FrameworkGame; + + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh8Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh8.ExampleCh8PC' + + DefaultPawnClass=class'JazzPawnDamage' + HUDType=class'UDKBase.UDKHUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/ExampleCh8PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/ExampleCh8PC.uc new file mode 100644 index 0000000..dbe61c8 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8/Classes/ExampleCh8PC.uc @@ -0,0 +1,134 @@ +class ExampleCh8PC extends SimplePC; + +var Controller FollowBot; +Var Pawn FollowPawn; +var bool BotSpawned; +var Actor BotTarget; + +var float PickDistance; + + +function Actor PickActor(Vector2D PickLocation, out Vector HitLocation, out TraceHitInfo HitInfo) +{ + local Vector TouchOrigin, TouchDir; + local Vector HitNormal; + local Actor PickedActor; + local vector Extent; + + //Transform absolute screen coordinates to relative coordinates + PickLocation.X = PickLocation.X / ViewportSize.X; + PickLocation.Y = PickLocation.Y / ViewportSize.Y; + + //Transform to world coordinates to get pick ray + LocalPlayer(Player).Deproject(PickLocation, TouchOrigin, TouchDir); + + //Perform trace to find touched actor + Extent = vect(0,0,0); + PickedActor = Trace(HitLocation, + HitNormal, + TouchOrigin + (TouchDir * PickDistance), + TouchOrigin, + True, + Extent, + HitInfo); + + //Return the touched actor for good measure + return PickedActor; +} + +function SpawnBot(Vector SpawnLocation, optional Vector Offset) +{ + SpawnLocation = SpawnLocation + Offset; + + FollowBot = Spawn(class'BotCoverController',,,SpawnLocation); + FollowPawn = Spawn(class'BotCoverPawn',,,SpawnLocation); + FollowBot.Possess(FollowPawn,false); + + BotCoverController(FollowBot).BotThreat = Pawn; + BotCoverpawn(FollowPawn).AddDefaultInventory(); + BotCoverPawn(Followpawn).InitialLocation = SpawnLocation; + + FollowPawn.SetPhysics(PHYS_Falling); +} + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + retval = true; + + + if (EventType == ZoneEvent_Touch) + { + WorldInfo.Game.Broadcast(self,"You touched the screen at = " @ + TouchLocation.x @ " , " @ TouchLocation.y @ + ", Zone Touched = " @ Zone); + + + // Start Firing pawn's weapon + StartFire(0); + } + else + if(EventType == ZoneEvent_Update) + { + + } + else + if (EventType == ZoneEvent_UnTouch) + { + // Stop Firing Pawn's weapon + StopFire(0); + } + + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + + } + } +} + +function PlayerTick(float DeltaTime) +{ + Super.PlayerTick(DeltaTime); + + + if (!BotSpawned) + { + SpawnBot(Pawn.Location,vect(0,0,500)); + SpawnBot(Pawn.Location,vect(0,0,1000)); + SpawnBot(Pawn.Location,vect(0,0,1500)); + SpawnBot(Pawn.Location,vect(0,0,2000)); + SpawnBot(Pawn.Location,vect(0,0,2500)); + + BotSpawned = true; + + JazzPawnDamage(Pawn).InitialLocation = Pawn.Location; + } +} + +defaultproperties +{ + BotSpawned=false + PickDistance = 10000 +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8Map.udk b/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8Map.udk new file mode 100644 index 0000000..221a52b Binary files /dev/null and b/Beginning iOS 3D Unreal Games Dev/Ch08/ExampleCh8Map.udk differ diff --git a/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/ExampleCh9Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/ExampleCh9Game.uc new file mode 100644 index 0000000..024889b --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/ExampleCh9Game.uc @@ -0,0 +1,34 @@ +class ExampleCh9Game extends FrameworkGame; + +var int Score; + + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh9Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh9.ExampleCh9PC' + + DefaultPawnClass=class'UDKBase.SimplePawn' + HUDType=class'KickBallHUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false +} + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/ExampleCh9PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/ExampleCh9PC.uc new file mode 100644 index 0000000..0357e52 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/ExampleCh9PC.uc @@ -0,0 +1,348 @@ +class ExampleCh9PC extends SimplePC; + +var float PickDistance; + + +var int KickAngle; +var int BallCreationDist; + +var float GameTime; +var bool bGameOVer; + +var Actor Ball; + +var bool bInitDone; +var bool bInputDelayFinished; + +var int GameTimeDelta; + +var SoundCue BallHitSound; +var SoundCue BallSpawnSound; + + +function InputDelayTimer() +{ + bInputDelayFinished = true; +} + +function ProcessLookUpInput() +{ + local float TimerDelta; + + + + if (!bInputDelayFinished) + return; + + + if (PlayerInput.aLookUp > 0) + { + KickAngle++; + } + else + if (PlayerInput.aLookUp < 0) + { + KickAngle--; + } + + KickAngle = Clamp(KickAngle,0,90); + + TimerDelta = 0.05; + bInputDelayFinished = false; + SetTimer(TimerDelta, false, 'InputDelayTimer'); +} + +function UpdateRotation( float DeltaTime ) +{ + local Rotator DeltaRot, newRotation, ViewRotation; + + ViewRotation = Rotation; + if (Pawn!=none) + { + Pawn.SetDesiredRotation(ViewRotation); + } + + // Calculate Delta to be applied on ViewRotation + DeltaRot.Yaw = PlayerInput.aTurn; + + //DeltaRot.Pitch = PlayerInput.aLookUp; + ProcessLookUpInput(); + + + ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot ); + SetRotation(ViewRotation); + + ViewShake( deltaTime ); + + NewRotation = ViewRotation; + NewRotation.Roll = Rotation.Roll; + + if ( Pawn != None ) + Pawn.FaceRotation(NewRotation, deltatime); +} + +function GameTimer() +{ + if (bGameOVer) + { + return; + } + + GameTime = GameTime + GameTimeDelta; +} + +simulated function PostBeginPlay() +{ + Super.PostBeginPlay(); + + SetTimer(GameTimeDelta, true, 'GameTimer'); +} + +function ApplyForceRigidBody(Actor SelectedActor, Vector ImpulseDir,float ImpulseMag, Vector HitLocation) +{ + if (SelectedActor.IsA('KActor')) + { + WorldInfo.Game.Broadcast(self,"*** Thrown object " @ SelectedActor @ + ", ImpulseDir = " @ ImpulseDir @ + ", ImpulseMag = " @ ImpulseMag @ + ", HitLocation = " @ HitLocation); + KActor(SelectedActor).ApplyImpulse(ImpulseDir,ImpulseMag, HitLocation); + } + else + if (SelectedActor.IsA('KAsset')) + { + WorldInfo.Game.Broadcast(self,"*** Thrown object " @ SelectedActor @ + ", ImpulseDir = " @ ImpulseDir @ + ", ImpulseMag = " @ ImpulseMag @ + ", HitLocation = " @ HitLocation); + KAsset(SelectedActor).SkeletalMeshComponent.AddImpulse(ImpulseDir* ImpulseMag, ,'Bone06'); + } + else + { + WorldInfo.Game.Broadcast(self,"!!!ERROR Selected Actor " @ SelectedActor @ + " is not a KActor or KAsset, you can not apply an impulse to this object!!!"); + } +} + +function Actor PickActor(Vector2D PickLocation, out Vector HitLocation, out TraceHitInfo HitInfo) +{ + local Vector TouchOrigin, TouchDir; + local Vector HitNormal; + local Actor PickedActor; + local vector Extent; + + + //Transform absolute screen coordinates to relative coordinates + PickLocation.X = PickLocation.X / ViewportSize.X; + PickLocation.Y = PickLocation.Y / ViewportSize.Y; + + //Transform to world coordinates to get pick ray + LocalPlayer(Player).Deproject(PickLocation, TouchOrigin, TouchDir); + + //Perform trace to find touched actor + Extent = vect(0,0,0); + PickedActor = Trace(HitLocation, + HitNormal, + TouchOrigin + (TouchDir * PickDistance), + TouchOrigin, + True, + Extent, + HitInfo); + + + //Return the touched actor for good measure + return PickedActor; +} + + +function CreateNewGameBall() +{ + local vector FrontVec; + local vector BallLocation; + + local Vector HitLocation; + local Vector ImpulseDir; + local float ImpulseMag; + + FrontVec = Normal(Vector(Pawn.Rotation)); + BallLocation = Pawn.Location + (FrontVec * BallCreationDist); + + Ball = Spawn(class'GameBall',,,BallLocation); + PlaySound(BallSpawnSound); + + ImpulseDir = Vect(0,0,1); + ImpulseMag = 5; + HitLocation = Vect(0,0,0); + ApplyForceRigidBody(Ball, ImpulseDir, ImpulseMag, HitLocation); +} + +function ResetGame() +{ + LoadLevel("ExampleCh9Map"); +} + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + local Actor PickedActor; + local Vector HitLocation; + local TraceHitInfo HitInfo; + + + // Variables for physics + local Vector ImpulseDir; + local float ImpulseMag; + local float RadKickAngle; + + + retval = true; + + + if (EventType == ZoneEvent_Touch) + { + // If screen touched then pick actor + PickedActor = PickActor(TouchLocation,HitLocation,HitInfo); + + //WorldInfo.Game.Broadcast(self,"PICKED ACTOR = " @ + // PickedActor @ + // ", HitLocation = " @ HitLocation @ + // ", Zone Touched = " @ Zone @ + // ", Touch Location = " @ TouchLocation.x @ "," @ TouchLocation.y); + + + // Reset Game + if (bGameOver) + { + ResetGame(); + return retval; + } + + + if (PickedActor.IsA('GameBall')) + { + RadKickAngle = KickAngle * DegToRad; + + ImpulseDir = (Normal(Vector(Pawn.Rotation)) * cos(RadKickAngle)) + (vect(0,0,1) * sin(RadKickAngle)); + ImpulseMag = 500; + + ApplyForceRigidBody(PickedActor,ImpulseDir,ImpulseMag,HitLocation); + PlaySound(BallHitSound); + } + else + { + CreateNewGameBall(); + } + + } + else + if(EventType == ZoneEvent_Update) + { + + } + else + if (EventType == ZoneEvent_UnTouch) + { + + } + + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + + } + } +} + +function bool AllBlocksDestroyed() +{ + local RigidBodyCube TempBlock; + local bool bAllBlocksDestroyed; + + + bAllBlocksDestroyed = true; + + foreach AllActors(class'RigidBodyCube', TempBlock) + { + if (!TempBlock.bDestroyed) + { + bAllBlocksDestroyed = false; + } + } + + return bAllBlocksDestroyed; +} + +function LoadLevel(string LevelName) +{ + local string Command; + + + Command = "open " @ LevelName; + ConsoleCommand(Command); +} + +function InitKickBallGame() +{ + bInitDone = true; +} + +function PlayerTick(float DeltaTime) +{ + Super.PlayerTick(DeltaTime); + + + if (!bInitDone) + { + InitKickBallGame(); + } + + if (AllBlocksDestroyed()) + { + bGameOver = true; + } + + if (bGameOver) + { + Pawn.SetHidden(true); + Pawn.Velocity = vect(0,0,0); + } + + +} + +defaultproperties +{ + PickDistance = 10000 + KickAngle = 45 + + bInitDone = false; + + bInputDelayFinished = true + BallCreationDist = 500 + + GameTime=0 + GameTimeDelta = 1 + bGameOver = false; + + BallHitSound = SoundCue'A_Weapon_BioRifle.Weapon.A_BioRifle_FireImpactFizzle_Cue' + BallSpawnSound = SoundCue'A_Pickups.Generic.Cue.A_Pickups_Generic_ItemRespawn_Cue' +} + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/GameBall.uc b/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/GameBall.uc new file mode 100644 index 0000000..8f47676 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/GameBall.uc @@ -0,0 +1,61 @@ +class GameBall extends KActorSpawnable; + +var SoundCue BallImpact; +var float MinimumForceForSound; + + +/** Called when a PrimitiveComponent this Actor owns has: + * -bNotifyRigidBodyCollision set to true + * -ScriptRigidBodyCollisionThreshold > 0 + * -it is involved in a physics collision where the relative velocity exceeds ScriptRigidBodyCollisionThreshold + * + * @param HitComponent the component of this Actor that collided + * @param OtherComponent the other component that collided + * @param RigidCollisionData information on the collision itslef, including contact points + * @param ContactIndex the element in each ContactInfos' ContactVelocity and PhysMaterial arrays that corresponds + * to this Actor/HitComponent + */ +event RigidBodyCollision(PrimitiveComponent HitComponent, + PrimitiveComponent OtherComponent, + const out CollisionImpactData RigidCollisionData, + int ContactIndex) +{ + + local float CollisionForce; + + + CollisionForce = VSize(RigidCollisionData.TotalNormalForceVector); + if (CollisionForce >= MinimumForceForSound) + { + PlaySound(BallImpact); + } +} + +event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + WorldInfo.Game.Broadcast(self,"GameBall Has Been Touched"); +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=GameBallMesh + StaticMesh=StaticMesh'EngineMeshes.Sphere' + Translation=(X=0.000000,Y=0.000000,Z=0.000000) + Scale3D=(X=0.10000,Y=0.10000,Z=0.1000) + + CollideActors=true + BlockActors=true + BlockRigidBody=true + bNotifyRigidBodyCollision=true + ScriptRigidBodyCollisionThreshold=0.001 + RBChannel=RBCC_GameplayPhysics + RBCollideWithChannels=(Default=TRUE,BlockingVolume=TRUE,GameplayPhysics=TRUE,EffectPhysics=TRUE) + End Object + Components.Add(GameBallMesh) + CollisionComponent = GameBallMesh + + + BallImpact = SoundCue'A_Character_BodyImpacts.BodyImpacts.A_Character_RobotImpact_GibLarge_Cue' + MinimumForceForSound = 50; +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/KickBallHUD.uc b/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/KickBallHUD.uc new file mode 100644 index 0000000..a11a2fd --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/KickBallHUD.uc @@ -0,0 +1,132 @@ +class KickBallHUD extends UDKHud; + +var Texture DefaultTexture1; +var Texture DefaultTexture2; +var Texture DefaultTexture3; +var Texture DefaultTexture4; +var Texture DefaultTexture5; + +struct HUDInfo +{ + var string Label; + var Vector2D TextLocation; + var Color TextColor; + var Vector2D Scale; +}; + +// HUD +var HUDInfo HUDKickAngle; +var HUDInfo HUDGameTime; +var HUDInfo HUDGameOver; +var HUDInfo HUDScore; + + +simulated function PostBeginPlay() +{ + Super.PostBeginPlay(); + + HUDKickAngle.Label = "KickAngle:"; + HUDKickAngle.TextLocation.x = 1000; + HUDKickAngle.TextLocation.y = 50; + HUDKickAngle.TextColor.R = 0; + HUDKickAngle.TextColor.G = 0; + HUDKickAngle.TextColor.B = 255; + HUDKickAngle.Scale.X = 2; + HUDKickAngle.Scale.Y = 4; + + HUDGameTime.Label = "Time:"; + HUDGameTime.TextLocation.x = 600; + HUDGameTime.TextLocation.y = 50; + HUDGameTime.TextColor.R = 255; + HUDGameTime.TextColor.G = 255; + HUDGameTime.TextColor.B = 0; + HUDGameTime.Scale.X = 2; + HUDGameTime.Scale.Y = 4; + + HUDGameOver.Label = "Level Complete"; + HUDGameOver.TextLocation.x = 250; + HUDGameOver.TextLocation.y = 300; + HUDGameOver.TextColor.R = 255; + HUDGameOver.TextColor.G = 0; + HUDGameOver.TextColor.B = 255; + HUDGameOver.Scale.X = 7; + HUDGameOver.Scale.Y = 7; + + HUDScore.Label = "Score:"; + HUDScore.TextLocation.x = 0; + HUDScore.TextLocation.y = 50; + HUDScore.TextColor.R = 255; + HUDScore.TextColor.G = 0; + HUDScore.TextColor.B = 0; + HUDScore.Scale.X = 2; + HUDScore.Scale.Y = 4; +} + +function DrawHUDItem(HUDInfo Info, coerce string Value) +{ + local Vector2D TextSize; + + Canvas.SetDrawColor(Info.TextColor.R, Info.TextColor.G, Info.TextColor.B); + Canvas.SetPos(Info.TextLocation.X, Info.TextLocation.Y); + Canvas.DrawText(Info.Label, ,Info.Scale.X,Info.Scale.Y); + Canvas.TextSize(Info.Label, TextSize.X, TextSize.Y); + Canvas.SetPos(Info.TextLocation.X + (TextSize.X * Info.Scale.X), Info.TextLocation.Y); + Canvas.DrawText(Value, , Info.Scale.X, Info.Scale.Y); +} + +function DrawHUD() +{ + local int Time; + + super.DrawHUD(); + + /* + // Blend Modes = BLEND_Opaque, BLEND_Additive, and BLEND_Modulate modes + Canvas.SetPos(0,0); + Canvas.DrawTextureBlended(DefaultTexture1, 1, BLEND_Opaque); + + Canvas.SetPos(150,0); + Canvas.DrawTextureBlended(DefaultTexture2, 1, BLEND_Additive); + + Canvas.SetPos(300,0); + Canvas.DrawTextureBlended(DefaultTexture3, 1, BLEND_Masked); + + Canvas.SetPos(450,0); + Canvas.DrawTextureBlended(DefaultTexture4, 1,BLEND_Masked); + + Canvas.SetPos(600,0); + Canvas.DrawTextureBlended(DefaultTexture5, 1, BLEND_Masked); + + */ + + + Canvas.Font = class'Engine'.static.GetLargeFont(); + + // Score + DrawHUDItem(HUDScore, ExampleCh9Game(WorldInfo.Game).Score); + + // Time + Time = ExampleCh9PC(PlayerOwner).GameTime; + DrawHUDItem(HUDGameTime, Time); + + // Kick Angle + DrawHUDItem(HUDKickAngle,ExampleCh9PC(PlayerOwner).KickAngle); + + // Game Over + if (ExampleCh9PC(PlayerOwner).bGameOVer) + { + DrawHUDItem(HUDGameOver, ""); + } + +} + +defaultProperties +{ + DefaultTexture1= Texture2D'EditorResources.Ambientcreatures' // Yellow Chick 32 by 32 + DefaultTexture2= Texture2D'EditorResources.Ammo' // Ammo Icon 32 by 32 + DefaultTexture3= Texture2D'EditorResources.LookTarget' // Target 32 by 32 + DefaultTexture4= Texture2D'EditorMaterials.Tick' // Green Check 32 by 32 + DefaultTexture5= Texture2D'EditorMaterials.GreyCheck' // Grey Check 32 by 32 + +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/RigidBodyCubeEx.uc b/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/RigidBodyCubeEx.uc new file mode 100644 index 0000000..14d8cdf --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9/Classes/RigidBodyCubeEx.uc @@ -0,0 +1,37 @@ +class RigidBodyCubeEx extends RigidBodyCube; + +var SoundCue ExplosionSound; +var() float ItemValue; + + +/** Called when a PrimitiveComponent this Actor owns has: + * -bNotifyRigidBodyCollision set to true + * -ScriptRigidBodyCollisionThreshold > 0 + * -it is involved in a physics collision where the relative velocity exceeds ScriptRigidBodyCollisionThreshold + * + * @param HitComponent the component of this Actor that collided + * @param OtherComponent the other component that collided + * @param RigidCollisionData information on the collision itslef, including contact points + * @param ContactIndex the element in each ContactInfos' ContactVelocity and PhysMaterial arrays that corresponds + * to this Actor/HitComponent + */ +event RigidBodyCollision(PrimitiveComponent HitComponent, + PrimitiveComponent OtherComponent, + const out CollisionImpactData RigidCollisionData, + int ContactIndex) +{ + super.RigidBodyCollision(HitComponent, OtherComponent, RigidCollisionData, ContactIndex); + + if (bDestroyed) + { + PlaySound(ExplosionSound); + ExampleCh9Game(WorldInfo.Game).Score += ItemValue; + } +} + +defaultproperties +{ + ExplosionSound = SoundCue'A_Weapon_ShockRifle.Cue.A_Weapon_SR_ComboExplosionCue' + ItemValue = 10; +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9Map.udk b/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9Map.udk new file mode 100644 index 0000000..8135472 Binary files /dev/null and b/Beginning iOS 3D Unreal Games Dev/Ch09/ExampleCh9Map.udk differ diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/Bonus1.uc b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/Bonus1.uc new file mode 100644 index 0000000..df9b4b6 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/Bonus1.uc @@ -0,0 +1,66 @@ +class Bonus1 extends Actor + placeable; + +var() float Value; +var SoundCue PickupSound; +var int SoundCueLength; + +event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + WorldInfo.Game.Broadcast(self,"Health Bonus1 Has Been Touched by " @ Other @ ", Bonus Value = " @ Value); + + + if (Other.IsA('JazzCh10Pawn')) + { + JazzCh10Pawn(Other).AddHealthBonus(Value); + PlaySound(PickUpSound); + destroy(); + } + else + if (Other.IsA('BotPawnCh10')) + { + BotPawnCh10(Other).AddHealthBonus(Value); + PlaySound(PickUpSound); + destroy(); + } +} + +function Tick(FLOAT DeltaTime) +{ + local Rotator TempRot; + + + //WorldInfo.Game.Broadcast(self,"TICKING BONUS1 - DeltaTime = " @ DeltaTime); + + TempRot = Rotation; + TempRot.yaw = Rotation.yaw + (15000 * DeltaTime); + SetRotation(TempRot); +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=HealthMesh + //StaticMesh=StaticMesh'EngineMeshes.Sphere' + StaticMesh=StaticMesh'Pickups.Health_Large.Mesh.S_Pickups_Health_Large_Keg' + + //Scale3D=(X=0.250000,Y=0.250000,Z=0.25000) + End Object + Components.Add(HealthMesh) + + + Begin Object Class=CylinderComponent NAME=CollisionCylinder + CollideActors=true + CollisionRadius=+0040.000000 + CollisionHeight=+0040.000000 + End Object + CollisionComponent=CollisionCylinder + Components.Add(CollisionCylinder) + + + bCollideActors=true + bEdShouldSnap=True + + value = 25 + PickupSound = SoundCue'A_Pickups.Health.Cue.A_Pickups_Health_Super_Cue' + SoundCueLength = 3 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotAttackCoverController.uc b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotAttackCoverController.uc new file mode 100644 index 0000000..57398df --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotAttackCoverController.uc @@ -0,0 +1,538 @@ +class BotAttackCoverController extends UDKBot; + +// Navigation +var Actor CurrentGoal; +var Vector TempDest; +var Actor TempGoal; + +// Cover Link +var CoverLink CurrentCover; +var bool BotInCover; + +// Bot's Enemy +var Pawn BotThreat; + +// Health Pickups +var bool bGotHealthPickup; +var int HealthPickupTrigger; + +// Respawn +var bool bJustRespawned; + +// Attack State +var int AttackOffsetDist; +var bool bAttackDone; +var int AttackTimeInterval; +var bool bStartAttackEnemy; + + + +function UnclaimAllSlots() +{ + local CoverLink CoverNodePointer; + local CoverLink TempNodePointer; + local bool done; + + CoverNodePointer = WorldInfo.Coverlist; + + done = false; + while (!done) + { + CoverNodePointer.Unclaim(Pawn, 0, true); + + if (CoverNodePointer.NextCoverLink != None) + { + TempNodePointer = CoverNodePointer.NextCoverLink; + CoverNodePointer = TempNodePointer; + } + else + { + done = true; + } + } + + Pawn.ShouldCrouch(false); + BotInCover = false; +} + +function FindEnemyLocation(out vector EnemyLocation) +{ + EnemyLocation = BotThreat.Location; +} + +function CoverLink FindClosestEmptyCoverNodeWithinRange(Vector ThreatLocation, vector Position, float Radius) +{ + local CoverLink CoverNodePointer; + local CoverLink TempNodePointer; + local bool done; + + local CoverLink ValidCoverNode; + local bool SlotValid; + local bool SlotAvailable; + local bool NodeFound; + local int DefaultSlot; + + local float Dist2Cover; + local float ClosestCoverNode; + + + CoverNodePointer = WorldInfo.Coverlist; + DefaultSlot = 0; // Assume only 1 slot per cover node. + ClosestCoverNode = 999999999; + + ValidCoverNode = None; + NodeFound = false; + + done = false; + while (!done) + { + SlotValid = CoverLinkEx(CoverNodePointer).IsCoverSlotValid(0,ThreatLocation); + SlotAvailable = CoverLinkEx(CoverNodePointer).IsCoverSlotAvailable(0); + + Dist2Cover = VSize(CoverNodePointer.GetSlotLocation(DefaultSlot) - Position); + + if (SlotValid && SlotAvailable && (Dist2Cover < ClosestCoverNode)) + { + ValidCoverNode = CoverNodePointer; + ClosestCoverNode = Dist2Cover; + NodeFound = true; + } + + // Goto Next CoverNode + if (CoverNodePointer.NextCoverLink != None) + { + TempNodePointer = CoverNodePointer.NextCoverLink; + CoverNodePointer = TempNodePointer; + } + else + { + // No more Cover Nodes + done = true; + } + } + + if (!NodeFound) + { + WorldInfo.Game.Broadcast(self,"!!! Can Not Find Valid CoverNode"); + } + + return ValidCoverNode; +} + +function bool IsCurrentCoverValid() +{ + local bool RetVal; + local vector ThreatLoc; + + + RetVal = false; + + if (CurrentCover != None) + { + FindEnemyLocation(ThreatLoc); + RetVal = CoverLinkEx(CurrentCover).IsCoverSlotValid(0, ThreatLoc); + } + + return Retval; +} + +function PrepMoveToCover() +{ + local vector ThreatLoc; + local CoverLink NextCover; + + + FindEnemyLocation(ThreatLoc); + NextCover = FindClosestEmptyCoverNodeWithinRange(ThreatLoc, Pawn.Location, 9999999); + + + if (NextCover != None) + { + WorldInfo.Game.Broadcast(self, self @ " moving to Next Cover " @ NextCover); + CurrentCover = NextCover; + CurrentGoal = CurrentCover; + BotInCover = false; + UnclaimAllSlots(); + CurrentCover.Claim(Pawn, 0); + } + + //Pawn.StopFire(0); + +} + +event bool GeneratePathTo(Actor Goal, optional float WithinDistance, optional bool bAllowPartialPath) +{ + if( NavigationHandle == None ) + return FALSE; + + // Clear cache and constraints (ignore recycling for the moment) + NavigationHandle.PathConstraintList = none; + NavigationHandle.PathGoalList = none; + + class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle, Goal ); + class'NavMeshGoal_At'.static.AtActor( NavigationHandle, Goal, WithinDistance, bAllowPartialPath ); + + return NavigationHandle.FindPath(); +} + + +function AttackEnemyTimer() +{ + bStartAttackEnemy = true; +} + +state TakeCover +{ + + event BeginState( Name PreviousStateName ) + { + // Put code here that is to only be executed when the state is first entered + bStartAttackEnemy = false; + SetTimer(AttackTimeInterval, false, 'AttackEnemyTimer'); + } + + event EndState( Name NextStateName ) + { + // Put code here that is to be executed only when exiting this state + } + + + Begin: + + //WorldInfo.Game.Broadcast(self,"BOTATTACKCOVERCONTROLLER - NAVMESH, CurrentGoal = " @ CurrentGoal @ + // ", CurrentCover = " @ CurrentCover @ " , BotInCover = " @ BotInCover @ + // ",bStartAttackEnemy = " @ bStartAttackEnemy); + WorldInfo.Game.Broadcast(self,"*********** In State TAKECOVER"); + + if (CurrentGoal != None) + { + if(GeneratePathTo(CurrentGoal)) + { + NavigationHandle.SetFinalDestination(CurrentGoal.Location); + if( NavigationHandle.ActorReachable(CurrentGoal) ) + { + // then move directly to the actor + MoveTo(CurrentGoal.Location, BotThreat); + BotInCover = true; + } + else + { + // move to the first node on the path + if( NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()) ) + { + // suggest move preparation will return TRUE when the edge's + // logic is getting the bot to the edge point + // FALSE if we should run there ourselves + if (!NavigationHandle.SuggestMovePreparation(TempDest,self)) + { + MoveTo(TempDest, BotThreat); + } + } + } + } + else + { + //give up because the nav mesh failed to find a path + WorldInfo.Game.Broadcast(self,"FindNavMeshPath failed to find a path!, CurrentGoal = " @ CurrentGoal); + MoveTo(Pawn.Location); + } + } + + LatentWhatToDoNext(); +} + +function bool NeedHealthPickup() +{ + local bool bresult; + + if (Pawn.Health < HealthPickupTrigger) + { + bresult = true; + } + else + { + bresult = false; + } + + return bresult; +} + +function Actor HealthPickupAvailable() +{ + local Bonus1 TempBonus; + local Actor ReturnActor; + local float ClosestDist; + local float TempDist; + + ReturnActor = None; + ClosestDist = 999999; + + foreach AllActors(class'Bonus1', TempBonus) + { + TempDist = VSize(Pawn.Location - TempBonus.Location); + If (TempDist < ClosestDist) + { + ReturnActor = TempBonus; + ClosestDist = TempDist; + } + } + + return ReturnActor; +} + +function PrepGettingHealthPickup(Actor Pickup) +{ + UnclaimAllSlots(); + CurrentGoal = Pickup; + CurrentCover = None; + bGotHealthPickup = false; +} + +state GettingHealthPickup +{ + + event BeginState( Name PreviousStateName ) + { + // Put code here that is to only be executed when the state is first entered + } + + event EndState( Name NextStateName ) + { + // Put code here that is to be executed only when exiting this state + } + + + Begin: + + WorldInfo.Game.Broadcast(self,"-----------> In state GettingHealthPickup"); + + if (CurrentGoal != None) + { + if(GeneratePathTo(CurrentGoal)) + { + NavigationHandle.SetFinalDestination(CurrentGoal.Location); + if( NavigationHandle.ActorReachable(CurrentGoal) ) + { + // then move directly to the actor + //MoveTo(CurrentGoal.Location, BotThreat); + MoveTo(CurrentGoal.Location); + bGotHealthPickup = true; + } + else + { + // move to the first node on the path + if( NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()) ) + { + // suggest move preparation will return TRUE when the edge's + // logic is getting the bot to the edge point + // FALSE if we should run there ourselves + if (!NavigationHandle.SuggestMovePreparation(TempDest,self)) + { + MoveTo(TempDest, BotThreat); + } + } + } + } + else + { + //give up because the nav mesh failed to find a path + //WorldInfo.Game.Broadcast(self,"FindNavMeshPath failed to find a path!, CurrentGoal = " @ CurrentGoal); + MoveTo(Pawn.Location); + } + } + + LatentWhatToDoNext(); +} + +function PrepAttackingEnemy() +{ + bAttackDone = false; + + UnclaimAllSlots(); + CurrentGoal = BotThreat; + CurrentCover = None; + + Pawn.StartFire(0); +} + +state AttackingEnemy +{ + event BeginState( Name PreviousStateName ) + { + // Put code here that is to only be executed when the state is first entered + PrepAttackingEnemy(); + } + + event EndState( Name NextStateName ) + { + // Put code here that is to be executed only when exiting this state + Pawn.StopFire(0); + } + + + Begin: + + WorldInfo.Game.Broadcast(self,"############# In State AttackingEnemy"); + + + if (CurrentGoal != None) + { + if(GeneratePathTo(CurrentGoal)) + { + NavigationHandle.SetFinalDestination(CurrentGoal.Location); + if( NavigationHandle.ActorReachable(CurrentGoal) ) + { + // then move directly to the actor + MoveTo(CurrentGoal.Location, BotThreat, AttackOffsetDist); + bAttackDone = true; + } + else + { + // move to the first node on the path + if( NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()) ) + { + // suggest move preparation will return TRUE when the edge's + // logic is getting the bot to the edge point + // FALSE if we should run there ourselves + if (!NavigationHandle.SuggestMovePreparation(TempDest,self)) + { + MoveTo(TempDest, BotThreat); + } + } + } + } + else + { + //give up because the nav mesh failed to find a path + //WorldInfo.Game.Broadcast(self,"FindNavMeshPath failed to find a path!, CurrentGoal = " @ CurrentGoal); + MoveTo(Pawn.Location); + } + } + + LatentWhatToDoNext(); +} + +function ResetAfterSpawn() +{ + bJustRespawned = true; +} + +function ExecuteResetAfterSpawn() +{ + UnclaimAllSlots(); + CurrentCover = None; + CurrentGoal = None; + bGotHealthPickup = false; + BotInCover = false; + + PrepMoveToCover(); +} + +auto state Initial +{ + Begin: + LatentWhatToDoNext(); +} + +event WhatToDoNext() +{ + DecisionComponent.bTriggered = true; +} + +protected event ExecuteWhatToDoNext() +{ + local Actor TempActor; + + + if (bJustRespawned) + { + bJustRespawned = false; + ExecuteResetAfterSpawn(); + GotoState('TakeCover', 'Begin'); + } + else + if (IsInState('Initial')) + { + PrepMoveToCover(); + GotoState('TakeCover', 'Begin'); + } + else + if (IsInState('TakeCover')) + { + if (BotInCover) + { + TempActor = HealthPickupAvailable(); + if (NeedHealthPickup() && (TempActor != None)) + { + // Health Pickup available and needed + PrepGettingHealthPickup(TempActor); + GotoState('GettingHealthPickup','Begin'); + } + else + if (IsCurrentCoverValid()) + { + if (bStartAttackEnemy) + { + GotoState('AttackingEnemy', 'Begin'); + } + else + { + GotoState('TakeCover', 'Begin'); + } + } + else + { + PrepMoveToCover(); + GotoState('TakeCover', 'Begin'); + } + } + else + { + GotoState('TakeCover', 'Begin'); + } + } + else + if (IsInState('GettingHealthPickup')) + { + if (!bGotHealthPickup) + { + GotoState('GettingHealthPickup','Begin'); + } + else + { + // Got Pickup Now Take Cover + PrepMoveToCover(); + GotoState('TakeCover', 'Begin'); + } + } + else + if (IsInState('AttackingEnemy')) + { + if (!bAttackDone) + { + GotoState('AttackingEnemy', 'Begin'); + } + else + { + PrepMoveToCover(); + GotoState('TakeCover', 'Begin'); + } + } + +} + +defaultproperties +{ + CurrentGoal = None + CurrentCover = None + BotInCover = false + + bGotHealthPickup = false + HealthPickupTrigger = 49 + bJustRespawned = false + + AttackOffsetDist = 700 + bAttackDone = false + AttackTimeInterval = 3 + bStartAttackEnemy = false +} diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotBulletCh10.uc b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotBulletCh10.uc new file mode 100644 index 0000000..f661e0a --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotBulletCh10.uc @@ -0,0 +1,7 @@ +class BotBulletCh10 extends JazzBulletSound; + +simulated singular event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + Other.TakeDamage(2, InstigatorController, HitLocation, -HitNormal, None); +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotPawnCh10.uc b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotPawnCh10.uc new file mode 100644 index 0000000..db7d65b --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotPawnCh10.uc @@ -0,0 +1,78 @@ +class BotPawnCh10 extends BotPawn2; + + +var array SpawnPadLocations; + +var SoundCue DeathSound; +var SoundCue HurtSound; + +function vector GetRandomSpawnPosition() +{ + local int RandPad; + local int MaxPads; + local vector returnvec; + + MaxPads = ExampleCh10Game(WorldInfo.Game).MaxSpawnPads; + Randpad = Rand(MaxPads); + + WorldInfo.Game.Broadcast(self,"*************** " @ self @ " RESPAWNED at pad number " @ RandPad); + + if (RandPad >= SpawnPadLocations.length) + { + // error + return InitialLocation; + } + else + { + returnvec = SpawnPadLocations[RandPad]; + } + + return returnvec; +} + +function AddHealthBonus(int Value) +{ + Health = Health + value; +} + +event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + PlaySound(HurtSound); + + Health = Health - Damage; + //WorldInfo.Game.Broadcast(self,self @ " Has Taken Damage IN TAKEDAMAGE, HEALTH = " @ Health); + + if (Health <= 0) + { + PlaySound(DeathSound); + SetLocation(GetRandomSpawnPosition()); + + SetPhysics(PHYS_Falling); + Health = 100; + + BotAttackCoverController(Controller).ResetAfterSpawn(); + + // Process Kill + if (PlayerController(InstigatedBy) != None) + { + // Add kill to Player's Score + ExampleCh10Game(WorldInfo.Game).Score += KillValue; + } + } +} + +function AddDefaultInventory() +{ + MainGun = InvManager.CreateInventory(class'BotWeaponCh10'); + MainGun.SetHidden(false); + + AddGunToSocket('Weapon_R'); + + Weapon(MainGun).FireOffset = vect(0,50,-70); +} + +defaultproperties +{ + DeathSound = SoundCue'KismetGame_Assets.Sounds.Jazz_Death_Cue' + HurtSound = SoundCue'KismetGame_Assets.Sounds.Jazz_SpinStop_Cue' +} diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotSpawnPad.uc b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotSpawnPad.uc new file mode 100644 index 0000000..30b53aa --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotSpawnPad.uc @@ -0,0 +1,24 @@ +class BotSpawnPad extends Actor +placeable; + +var() int PadNumber; + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=StaticMeshComponent0 + StaticMesh=StaticMesh'Pickups.jump_pad.S_Pickups_Jump_Pad' + End Object + Components.Add(StaticMeshComponent0) + + Begin Object Class=CylinderComponent NAME=CollisionCylinder + CollideActors=true + CollisionRadius=+0040.000000 + CollisionHeight=+0040.000000 + End Object + CollisionComponent=CollisionCylinder + Components.Add(CollisionCylinder) + + bCollideActors=true + + PadNumber = 0 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotWeaponCh10.uc b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotWeaponCh10.uc new file mode 100644 index 0000000..2dfe740 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/BotWeaponCh10.uc @@ -0,0 +1,26 @@ +class BotWeaponCh10 extends Weapon; + +defaultproperties +{ + Begin Object Class=SkeletalMeshComponent Name=FirstPersonMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + Mesh=FirstPersonMesh + Components.Add(FirstPersonMesh); + + Begin Object Class=SkeletalMeshComponent Name=PickupMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + DroppedPickupMesh=PickupMesh + PickupFactoryMesh=PickupMesh + + WeaponFireTypes(0)=EWFT_Projectile + WeaponFireTypes(1)=EWFT_NONE + + WeaponProjectiles(0)=class'BotBulletCh10' + WeaponProjectiles(1)=class'BotBulletCh10' + + FiringStatesArray(0)=WeaponFiring + FireInterval(0)=0.25 + Spread(0)=0 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/ExampleCh10Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/ExampleCh10Game.uc new file mode 100644 index 0000000..dd0677e --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/ExampleCh10Game.uc @@ -0,0 +1,40 @@ +class ExampleCh10Game extends FrameworkGame; + +var int Score; +var int MaxSpawnPads; +var bool bGameOver; + + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh10Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh10.ExampleCh10PC' + + DefaultPawnClass=class'JazzCh10Pawn' + HUDType=class'FPSHUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false + + Score = 0 + MaxSpawnPads = 4 + bGameOver = false; +} + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/ExampleCh10PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/ExampleCh10PC.uc new file mode 100644 index 0000000..f71a8ea --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/ExampleCh10PC.uc @@ -0,0 +1,217 @@ +class ExampleCh10PC extends SimplePC; + + +var Controller EnemyBot; +Var Pawn EnemyPawn; + +var bool BotSpawned; +var Actor BotTarget; + +var bool bGameOver; + +var array SpawnPadLocations; + + + +function ResetGame() +{ + ExampleCh10Game(WorldInfo.Game).bGameOver = false; + ExampleCh10Game(WorldInfo.Game).Score = 0; + Pawn.Health = 100; + + Pawn.SetHidden(false); + Pawn.Weapon.SetHidden(false); + Pawn.SetLocation(JazzCh10Pawn(Pawn).InitialLocation); + +} + +function Actor FindSpawnPad(int PadNumber) +{ + local BotSpawnPad TempSpawnPad; + local Actor ReturnSpawnPad; + + ReturnSpawnPad = None; + foreach AllActors(class'BotSpawnPad', TempSpawnPad) + { + SpawnPadLocations.Additem(TempSpawnPad.Location); + if(TempSpawnPad.PadNumber == PadNumber) + { + ReturnSpawnPad = TempSpawnPad; + } + } + + return ReturnSpawnPad; +} + +function SpawnBot(Vector SpawnLocation, optional Vector Offset) +{ + SpawnLocation = SpawnLocation + Offset; + + EnemyBot = Spawn(class'BotAttackCoverController',,,SpawnLocation); + EnemyPawn = Spawn(class'BotPawnCh10',,,SpawnLocation); + EnemyBot.Possess(EnemyPawn,false); + + BotAttackCoverController(EnemyBot).BotThreat = Pawn; + BotPawnCh10(EnemyPawn).AddDefaultInventory(); + BotPawnCh10(EnemyPawn).InitialLocation = SpawnLocation; + + BotPawnCh10(EnemyPawn).SpawnPadLocations = SpawnPadLocations; + + + EnemyPawn.SetPhysics(PHYS_Falling); +} + +function SpawnBotOnRandomPad(vector AlternateLocation, vector offset) +{ + local int RandomPadNumber; + local Actor SpawnPad; + local int MaxPads; + + MaxPads = ExampleCh10Game(WorldInfo.Game).MaxSpawnPads; + RandomPadNumber = Rand(MaxPads);// Number from 0 to Max-1. + + WorldInfo.Game.Broadcast(self,"RANDOMPADNUMBER = " @ RandomPadNumber); + + SpawnPad = FindSpawnPad(RandomPadNumber); + if (SpawnPad != None) + { + SpawnBot(SpawnPad.Location, offset); + } + else + { + SpawnBot(AlternateLocation, Offset); + } +} + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + + retval = true; + + + if (EventType == ZoneEvent_Touch) + { + //WorldInfo.Game.Broadcast(self,"You touched the screen at = " @ + // TouchLocation.x @ " , " @ TouchLocation.y @ + // ", Zone Touched = " @ Zone); + + + // Reset Game + if (ExampleCh10Game(WorldInfo.Game).bGameOver) + { + ResetGame(); + } + else + { + // Start Firing pawn's weapon + StartFire(0); + } + } + else + if(EventType == ZoneEvent_Update) + { + } + else + if (EventType == ZoneEvent_UnTouch) + { + // Stop Firing Pawn's weapon + StopFire(0); + } + + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + + } + } +} + +function PlaceWeapon() +{ + // First Person + local vector WeaponLocation; + local Rotator WeaponRotation,TempRot; + local Weapon TestW; + local vector WeaponAimVect; + + + WeaponRotation.yaw = -16000; // 90 Degrees turn = OFFSET + + + TempRot = Pawn.GetBaseAimRotation(); + WeaponRotation.pitch = TempRot.roll; + WeaponRotation.yaw += TempRot.yaw; + WeaponRotation.roll -= TempRot.pitch; // Swith due to weapon local axes orientation + + WeaponAimVect = Normal(Vector(TempRot)); + WeaponLocation = Pawn.Location + (40 * WeaponAimVect) + vect(0,0,30); + + TestW = Pawn.Weapon; //Pawn.InvManager.GetBestWeapon(); + + if (TestW != None) + { + TestW.SetLocation(WeaponLocation); + TestW.SetRotation(WeaponRotation); + } + else + { + WorldInfo.Game.Broadcast(self,"Player has no weapon!!!!!"); + } + +} + +function PlayerTick(float DeltaTime) +{ + Super.PlayerTick(DeltaTime); + + PlaceWeapon(); + + + if (!BotSpawned) + { + SpawnBotOnRandomPad(Pawn.Location, vect(0,0,500)); + BotSpawned = true; + JazzCh10Pawn(Pawn).InitialLocation = Pawn.Location; + } + + if (Pawn.Health <= 0) + { + ExampleCh10Game(WorldInfo.Game).bGameOver = true; + } + + if (ExampleCh10Game(WorldInfo.Game).bGameOver) + { + Pawn.Health = 0; + StopFire(0); + Pawn.SetHidden(true); + Pawn.Weapon.SetHidden(true); + Pawn.Velocity = vect(0,0,0); + } +} + +defaultproperties +{ + BotSpawned = false; +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/FPSHUD.uc b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/FPSHUD.uc new file mode 100644 index 0000000..cc292f7 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/FPSHUD.uc @@ -0,0 +1,129 @@ +class FPSHUD extends UDKHud; + +var Texture DefaultTexture1; +var Texture DefaultTexture2; +var Texture DefaultTexture3; +var Texture DefaultTexture4; +var Texture DefaultTexture5; + +struct HUDInfo +{ + var string Label; + var Vector2D TextLocation; + var Color TextColor; + var Vector2D Scale; +}; + +// HUD +var HUDInfo HUDHealth; +var HUDInfo HUDEnemyHealth; +var HUDInfo HUDGameOver; +var HUDInfo HUDScore; + + +simulated function PostBeginPlay() +{ + Super.PostBeginPlay(); + + HUDHealth.Label = "Health:"; + HUDHealth.TextLocation.x = 1100; + HUDHealth.TextLocation.y = 0; + HUDHealth.TextColor.R = 255; + HUDHealth.TextColor.G = 0; + HUDHealth.TextColor.B = 0; + HUDHealth.Scale.X = 2; + HUDHealth.Scale.Y = 4; + + HUDEnemyHealth.Label = "Enemy Health:"; + HUDEnemyHealth.TextLocation.x = 500; + HUDEnemyHealth.TextLocation.y = 0; + HUDEnemyHealth.TextColor.R = 255; + HUDEnemyHealth.TextColor.G = 0; + HUDEnemyHealth.TextColor.B = 0; + HUDEnemyHealth.Scale.X = 2; + HUDEnemyHealth.Scale.Y = 4; + + HUDGameOver.Label = "GAME OVER"; + HUDGameOver.TextLocation.x = 400; + HUDGameOver.TextLocation.y = 300; + HUDGameOver.TextColor.R = 255; + HUDGameOver.TextColor.G = 0; + HUDGameOver.TextColor.B = 255; + HUDGameOver.Scale.X = 7; + HUDGameOver.Scale.Y = 7; + + HUDScore.Label = "Score:"; + HUDScore.TextLocation.x = 0; + HUDScore.TextLocation.y = 0; + HUDScore.TextColor.R = 255; + HUDScore.TextColor.G = 0; + HUDScore.TextColor.B = 0; + HUDScore.Scale.X = 2; + HUDScore.Scale.Y = 4; +} + +function DrawHUDItem(HUDInfo Info, coerce string Value) +{ + local Vector2D TextSize; + + Canvas.SetDrawColor(Info.TextColor.R, Info.TextColor.G, Info.TextColor.B); + Canvas.SetPos(Info.TextLocation.X, Info.TextLocation.Y); + Canvas.DrawText(Info.Label, ,Info.Scale.X,Info.Scale.Y); + Canvas.TextSize(Info.Label, TextSize.X, TextSize.Y); + Canvas.SetPos(Info.TextLocation.X + (TextSize.X * Info.Scale.X), Info.TextLocation.Y); + Canvas.DrawText(Value, , Info.Scale.X, Info.Scale.Y); +} + +function DrawHUD() +{ + + super.DrawHUD(); + + /* + // Blend Modes = BLEND_Opaque, BLEND_Additive, and BLEND_Modulate modes + Canvas.SetPos(0,0); + Canvas.DrawTextureBlended(DefaultTexture1, 1, BLEND_Opaque); + + Canvas.SetPos(150,0); + Canvas.DrawTextureBlended(DefaultTexture2, 1, BLEND_Additive); + + Canvas.SetPos(300,0); + Canvas.DrawTextureBlended(DefaultTexture3, 1, BLEND_Masked); + + Canvas.SetPos(450,0); + Canvas.DrawTextureBlended(DefaultTexture4, 1,BLEND_Masked); + + Canvas.SetPos(600,0); + Canvas.DrawTextureBlended(DefaultTexture5, 1, BLEND_Masked); + + */ + + Canvas.Font = class'Engine'.static.GetLargeFont(); + + // Score + DrawHUDItem(HUDScore,ExampleCh10Game(WorldInfo.Game).Score); + + // Enemy Health + DrawHUDItem(HUDEnemyHealth, ExampleCh10PC(PlayerOwner).EnemyPawn.Health); + + // Health + DrawHUDItem(HUDHealth,PlayerOwner.Pawn.Health); + + // Game Over + if (ExampleCh10Game(WorldInfo.Game).bGameOver) + { + DrawHUDItem(HUDGameOver, ""); + } + +} + +defaultProperties +{ + DefaultTexture1= Texture2D'EditorResources.Ambientcreatures' // Yellow Chick 32 by 32 + DefaultTexture2= Texture2D'EditorResources.Ammo' // Ammo Icon 32 by 32 + DefaultTexture3= Texture2D'EditorResources.LookTarget' // Target 32 by 32 + DefaultTexture4= Texture2D'EditorMaterials.Tick' // Green Check 32 by 32 + DefaultTexture5= Texture2D'EditorMaterials.GreyCheck' // Grey Check 32 by 32 + +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/JazzBulletCh10.uc b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/JazzBulletCh10.uc new file mode 100644 index 0000000..69f505d --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/JazzBulletCh10.uc @@ -0,0 +1,58 @@ +class JazzBulletCh10 extends Projectile; + +var SoundCue FireSound; +var bool ImpactSoundPlayed; + + + +simulated singular event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + Other.TakeDamage(33, InstigatorController, HitLocation, -HitNormal, None); +} + +simulated function Explode(vector HitLocation, vector HitNormal) +{ + if (!ImpactSoundPlayed) + { + PlaySound(ImpactSound); + ImpactSoundPlayed = true; + } + + SetPhysics(Phys_Falling); +} + +function Init( Vector Direction ) +{ + super.Init(Direction); + RandSpin(90000); + + + PlaySound(SpawnSound); + PlaySound(FireSound, , , true,,); + +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=Bullet + StaticMesh=StaticMesh'Castle_Assets.Meshes.SM_RiverRock_01' + Scale3D=(X=0.300000,Y=0.30000,Z=0.3000) + End Object + Components.Add(Bullet) + + Begin Object Class=ParticleSystemComponent Name=BulletTrail + Template=ParticleSystem'Castle_Assets.FX.P_FX_Fire_SubUV_01' + End Object + Components.Add(BulletTrail) + + MaxSpeed=+05000.000000 + Speed=+05000.000000 + + + FireSound = SoundCue'A_Vehicle_Generic.Vehicle.Vehicle_Damage_FireLoop_Cue' + ImpactSound = SoundCue'A_Character_BodyImpacts.BodyImpacts.A_Character_RobotImpact_HeadshotRoll_Cue' + SpawnSound = SoundCue'KismetGame_Assets.Sounds.S_WeaponRespawn_01_Cue' + + ImpactSoundPlayed = false + +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/JazzCh10Pawn.uc b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/JazzCh10Pawn.uc new file mode 100644 index 0000000..b7e06ca --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/JazzCh10Pawn.uc @@ -0,0 +1,37 @@ +class JazzCh10Pawn extends SimplePawn; + + +var Inventory MainGun; +var vector InitialLocation; +var SoundCue PawnHitSound; + + +function AddHealthBonus(int Value) +{ + Health = Health + value; +} + +event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + PlaySound(PawnHitSound); + Health = Health - Damage; + + //WorldInfo.Game.Broadcast(self,self @ " Has Taken Damage IN TAKEDAMAGE, HEALTH = " @ Health); +} + +function AddDefaultInventory() +{ + MainGun = InvManager.CreateInventory(class'JazzWeaponCh10'); + MainGun.SetHidden(false); + + Weapon(MainGun).FireOffset = vect(0,0,-70); +} + +defaultproperties +{ + InventoryManagerClass=class'WeaponsIM1' + + PawnHitSound = SoundCue'A_Character_CorruptEnigma_Cue.Mean_Efforts.A_Effort_EnigmaMean_Death_Cue' +} + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/JazzWeaponCh10.uc b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/JazzWeaponCh10.uc new file mode 100644 index 0000000..9ffe866 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10/Classes/JazzWeaponCh10.uc @@ -0,0 +1,26 @@ +class JazzWeaponCh10 extends Weapon; + +defaultproperties +{ + Begin Object Class=SkeletalMeshComponent Name=FirstPersonMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + Mesh=FirstPersonMesh + Components.Add(FirstPersonMesh); + + Begin Object Class=SkeletalMeshComponent Name=PickupMesh + SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun' + End Object + DroppedPickupMesh=PickupMesh + PickupFactoryMesh=PickupMesh + + WeaponFireTypes(0)=EWFT_Projectile + WeaponFireTypes(1)=EWFT_NONE + + WeaponProjectiles(0)=class'JazzBulletCh10' + WeaponProjectiles(1)=class'JazzBulletCh10' + + FiringStatesArray(0)=WeaponFiring + FireInterval(0)=0.25 + Spread(0)=0 +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10Map.udk b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10Map.udk new file mode 100644 index 0000000..0a3b8ee Binary files /dev/null and b/Beginning iOS 3D Unreal Games Dev/Ch10/ExampleCh10Map.udk differ diff --git a/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/BotAllyController.uc b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/BotAllyController.uc new file mode 100644 index 0000000..4a78578 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/BotAllyController.uc @@ -0,0 +1,292 @@ +class BotAllyController extends UDKBot; + +var Vector TempDest; + +var float FollowDistanceTarget; +var float FollowDistanceMarker; + +var Actor TempGoal; + +var float AttackOffsetDist; +var bool bAttackDone; + +var Pawn BotOwner; + +var Actor FollowTarget; +var Actor MoveToTarget; +var Actor AttackTarget; + +enum BotCommand +{ + Follow, + Move, + Attack +}; + +var BotCommand Command; + + +function SetCommand(BotCommand Order, Actor Target) +{ + Command = Order; + + if (Command == Follow) + { + FollowTarget = Target; + } + else + if (Command == Move) + { + MoveToTarget = Target; + } + else + if (Command == Attack) + { + AttackTarget = Target; + bAttackDone = false; + } +} + +event bool GeneratePathTo(Actor Goal, optional float WithinDistance, optional bool bAllowPartialPath) +{ + if( NavigationHandle == None ) + return FALSE; + + // Clear cache and constraints (ignore recycling for the moment) + NavigationHandle.PathConstraintList = none; + NavigationHandle.PathGoalList = none; + + class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle, Goal ); + class'NavMeshGoal_At'.static.AtActor( NavigationHandle, Goal, WithinDistance, bAllowPartialPath ); + + return NavigationHandle.FindPath(); +} + + +state FollowingTarget +{ + event BeginState( Name PreviousStateName ) + { + // Put code here that is to only be executed when the state is first entered + + } + + event EndState( Name NextStateName ) + { + // Put code here that is to be executed only when exiting this state + + } + + + Begin: + + WorldInfo.Game.Broadcast(self,"************** IN State FollowTarget "); + + // Move Bot to Target + if (FollowTarget != None) + { + if(GeneratePathTo(FollowTarget)) + { + NavigationHandle.SetFinalDestination(FollowTarget.Location); + if( NavigationHandle.ActorReachable(FollowTarget) ) + { + // then move directly to the actor + MoveTo(FollowTarget.Location, ,FollowDistanceTarget); + } + else + { + // move to the first node on the path + if( NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()) ) + { + // suggest move preparation will return TRUE when the edge's + // logic is getting the bot to the edge point + // FALSE if we should run there ourselves + if (!NavigationHandle.SuggestMovePreparation(TempDest,self)) + { + MoveTo(TempDest); + } + } + } + } + else + { + //give up because the nav mesh failed to find a path + `warn("FindNavMeshPath failed to find a path!"); + WorldInfo.Game.Broadcast(self,"FindNavMeshPath failed to find a path!, FollowTarget= " @ FollowTarget); + MoveTo(Pawn.Location); + } + } + LatentWhatToDoNext(); +} + +state MovingToMarker +{ + event BeginState( Name PreviousStateName ) + { + // Put code here that is to only be executed when the state is first entered + + } + + event EndState( Name NextStateName ) + { + // Put code here that is to be executed only when exiting this state + + } + + + Begin: + + WorldInfo.Game.Broadcast(self,"************** IN State MoveToMarker "); + + // Move Bot to Target + if (MoveToTarget != None) + { + if(GeneratePathTo(MoveToTarget)) + { + NavigationHandle.SetFinalDestination(MoveToTarget.Location); + if( NavigationHandle.ActorReachable(MoveToTarget) ) + { + // then move directly to the actor + MoveTo(MoveToTarget.Location, ,FollowDistanceMarker); + } + else + { + // move to the first node on the path + if( NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()) ) + { + // suggest move preparation will return TRUE when the edge's + // logic is getting the bot to the edge point + // FALSE if we should run there ourselves + if (!NavigationHandle.SuggestMovePreparation(TempDest,self)) + { + MoveTo(TempDest); + } + } + } + } + else + { + //give up because the nav mesh failed to find a path + `warn("FindNavMeshPath failed to find a path!"); + WorldInfo.Game.Broadcast(self,"FindNavMeshPath failed to find a path!, MoveToTarget= " @ MoveToTarget); + MoveTo(Pawn.Location); + } + } + LatentWhatToDoNext(); +} + +state AttackingEnemy +{ + event BeginState( Name PreviousStateName ) + { + // Put code here that is to only be executed when the state is first entered + Pawn.StartFire(0); + bAttackDone = false; + } + + event EndState( Name NextStateName ) + { + // Put code here that is to be executed only when exiting this state + Pawn.StopFire(0); + } + + + Begin: + + WorldInfo.Game.Broadcast(self,"############# In State AttackingEnemy"); + + if (AttackTarget != None) + { + if(GeneratePathTo(AttackTarget)) + { + NavigationHandle.SetFinalDestination(AttackTarget.Location); + if( NavigationHandle.ActorReachable(AttackTarget) ) + { + // then move directly to the actor + MoveTo(AttackTarget.Location, AttackTarget, AttackOffsetDist); + bAttackDone = true; + } + else + { + // move to the first node on the path + if( NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()) ) + { + // suggest move preparation will return TRUE when the edge's + // logic is getting the bot to the edge point + // FALSE if we should run there ourselves + if (!NavigationHandle.SuggestMovePreparation(TempDest,self)) + { + MoveTo(TempDest, AttackTarget); + } + } + } + } + else + { + //give up because the nav mesh failed to find a path + WorldInfo.Game.Broadcast(self,"FindNavMeshPath failed to find a path!,AttackTarget = " @ AttackTarget); + MoveTo(Pawn.Location); + } + } + + LatentWhatToDoNext(); +} + +auto state Initial +{ + Begin: + + LatentWhatToDoNext(); +} + +/** triggers ExecuteWhatToDoNext() to occur during the next tick + * this is also where logic that is unsafe to do during the physics tick should be added + * @note: in state code, you probably want LatentWhatToDoNext() so the state is paused while waiting for ExecuteWhatToDoNext() to be called + */ +event WhatToDoNext() +{ + DecisionComponent.bTriggered = true; +} + +/** entry point for AI decision making + * this gets executed during the physics tick so actions that could change the physics state (e.g. firing weapons) are not allowed + */ +protected event ExecuteWhatToDoNext() +{ + if (IsInState('Initial')) + { + GotoState('FollowingTarget', 'Begin'); + } + else + if (Command == Follow) + { + GotoState('FollowingTarget', 'Begin'); + } + else + if (Command == Move) + { + GotoState('MovingToMarker', 'Begin'); + } + else + if (Command == Attack) + { + if (!bAttackDone) + { + GotoState('AttackingEnemy', 'Begin'); + } + else + { + Command = Follow; + GotoState('FollowingTarget', 'Begin'); + } + } +} + +defaultproperties +{ + FollowDistanceTarget = 250; + FollowDistanceMarker = 75; + + AttackOffsetDist = 500; + bAttackDone = false +} diff --git a/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/BotControllerGuard.uc b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/BotControllerGuard.uc new file mode 100644 index 0000000..3ff3ccd --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/BotControllerGuard.uc @@ -0,0 +1,289 @@ +class BotControllerGuard extends UDKBot; + +var Actor CurrentGoal; +var Vector TempDest; +var Actor TempGoal; + +var float GuardDistance; +var float AttackDistance; +var float GuardRadius; + +var Actor GuardedStructure; + +var Pawn Threat; + + +////////////////////////////////////////// PAthnode Related Functions ////////////////////////////////////////////////// +/* +state FollowTarget +{ + Begin: + + //WorldInfo.Game.Broadcast(self,"BotController-USING PATHNODES FOR FOLLOWTARGET STATE"); + + // Move Bot to Target + if (CurrentGoal != None) + { + TempGoal = FindPathToward(CurrentGoal); + + if (ActorReachable(CurrentGoal)) + { + MoveTo(CurrentGoal.Location, ,FollowDistance); + } + else + if (TempGoal != None) + { + MoveToward(TempGoal); + } + else + { + //give up because the nav mesh failed to find a path + `warn("PATCHNODES failed to find a path!"); + WorldInfo.Game.Broadcast(self,"PATHNODES failed to find a path!, CurrentGoal = " @ CurrentGoal); + MoveTo(Pawn.Location); + } + } + LatentWhatToDoNext(); +} +*/ + +////////////////////////////////////////// Navigation Mesh Related Functions ////////////////////////////////////////////// + +event bool GeneratePathTo(Actor Goal, optional float WithinDistance, optional bool bAllowPartialPath) +{ + if( NavigationHandle == None ) + return FALSE; + + // Clear cache and constraints (ignore recycling for the moment) + NavigationHandle.PathConstraintList = none; + NavigationHandle.PathGoalList = none; + + class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle, Goal ); + class'NavMeshGoal_At'.static.AtActor( NavigationHandle, Goal, WithinDistance, bAllowPartialPath ); + + return NavigationHandle.FindPath(); +} + +function Actor FindUnguardedGenerator() +{ + local Generator TempGenerator; + local Actor ReturnGenerator; + + ReturnGenerator = None; + foreach AllActors(class'Generator', TempGenerator) + { + if(TempGenerator.Guard == None) + { + ReturnGenerator = TempGenerator; + } + } + + return ReturnGenerator; +} + +state Guarding +{ + event BeginState( Name PreviousStateName ) + { + // Put code here that is to only be executed when the state is first entered + CurrentGoal = GuardedStructure; + Threat = None; + } + + event EndState( Name NextStateName ) + { + // Put code here that is to be executed only when exiting this state + } + + + Begin: + + //WorldInfo.Game.Broadcast(self,"BotControllerGuard-USING NAVMESH FOR FOLLOWTARGET STATE"); + + // Move Bot to Target + if (CurrentGoal != None) + { + if(GeneratePathTo(CurrentGoal)) + { + NavigationHandle.SetFinalDestination(CurrentGoal.Location); + if( NavigationHandle.ActorReachable(CurrentGoal) ) + { + // then move directly to the actor + MoveTo(CurrentGoal.Location, CurrentGoal,GuardDistance); + } + else + { + // move to the first node on the path + if( NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()) ) + { + // suggest move preparation will return TRUE when the edge's + // logic is getting the bot to the edge point + // FALSE if we should run there ourselves + if (!NavigationHandle.SuggestMovePreparation(TempDest,self)) + { + MoveTo(TempDest); + } + } + } + } + else + { + //give up because the nav mesh failed to find a path + `warn("FindNavMeshPath failed to find a path!"); + WorldInfo.Game.Broadcast(self,"GUARDING - FindNavMeshPath failed to find a path!, CurrentGoal = " @ CurrentGoal); + MoveTo(Pawn.Location); + } + } + LatentWhatToDoNext(); +} + +function bool IsInPatrolRange() +{ + local bool retval; + local float Distance; + + + Distance = VSize(Pawn.Location - GuardedStructure.Location); + + if (Distance <= GuardRadius) + { + retval = true; + } + else + { + retval = false; + } + + return retval; +} + +state Attacking +{ + + event BeginState( Name PreviousStateName ) + { + // Put code here that is to only be executed when the state is first entered + CurrentGoal = Threat; + Pawn.StartFire(0); + + } + + event EndState( Name NextStateName ) + { + // Put code here that is to be executed only when exiting this state + Pawn.StopFire(0); + } + + + Begin: + + //WorldInfo.Game.Broadcast(self,"BotControllerGuard-USING NAVMESH FOR FOLLOWTARGET STATE"); + + // Move Bot to Target + if (CurrentGoal != None) + { + if(GeneratePathTo(CurrentGoal)) + { + NavigationHandle.SetFinalDestination(CurrentGoal.Location); + if( NavigationHandle.ActorReachable(CurrentGoal) ) + { + // then move directly to the actor + MoveTo(CurrentGoal.Location, CurrentGoal,AttackDistance); + } + else + { + // move to the first node on the path + if( NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()) ) + { + // suggest move preparation will return TRUE when the edge's + // logic is getting the bot to the edge point + // FALSE if we should run there ourselves + if (!NavigationHandle.SuggestMovePreparation(TempDest,self)) + { + MoveTo(TempDest); + } + } + } + } + else + { + //give up because the nav mesh failed to find a path + `warn("FindNavMeshPath failed to find a path!"); + WorldInfo.Game.Broadcast(self,"GUARDING - FindNavMeshPath failed to find a path!, CurrentGoal = " @ CurrentGoal); + MoveTo(Pawn.Location); + } + } + + if (!IsInPatrolRange()) + { + GotoState('Guarding', 'Begin'); + } + + LatentWhatToDoNext(); + +} + +auto state Initial +{ + Begin: + + LatentWhatToDoNext(); +} + +/** triggers ExecuteWhatToDoNext() to occur during the next tick + * this is also where logic that is unsafe to do during the physics tick should be added + * @note: in state code, you probably want LatentWhatToDoNext() so the state is paused while waiting for ExecuteWhatToDoNext() to be called + */ +event WhatToDoNext() +{ + DecisionComponent.bTriggered = true; +} + +/** entry point for AI decision making + * this gets executed during the physics tick so actions that could change the physics state (e.g. firing weapons) are not allowed + */ +protected event ExecuteWhatToDoNext() +{ + local Actor TempGenerator; + + if (IsInState('Initial')) + { + TempGenerator = FindUnguardedGenerator(); + if (TempGenerator != None) + { + Generator(TempGenerator).Guard = Pawn; + GuardedStructure = TempGenerator; + GotoState('Guarding', 'Begin'); + } + else + { + GotoState('Inital', 'Begin'); + } + } + else + if (IsInState('Guarding')) + { + if (Threat != None) + { + GotoState('Attacking', 'Begin'); + } + else + { + GotoState('Guarding', 'Begin'); + } + } + else + if (IsInState('Attacking')) + { + GotoState('Attacking', 'Begin'); + } +} + +defaultproperties +{ + CurrentGoal = None + GuardDistance = 300 + AttackDistance = 200 + Threat = None + GuardRadius = 1000; +} diff --git a/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/BotMarker2.uc b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/BotMarker2.uc new file mode 100644 index 0000000..385f5b1 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/BotMarker2.uc @@ -0,0 +1,30 @@ +class BotMarker2 extends Actor; + +event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + //WorldInfo.Game.Broadcast(self,"BotMarker Has Been Touched"); +} + +function Tick(FLOAT DeltaTime) +{ + local Rotator TempRot; + + + TempRot = Rotation; + TempRot.yaw = Rotation.yaw + (15000 * DeltaTime); + SetRotation(TempRot); +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=StaticMeshComponent0 + StaticMesh=StaticMesh'CastleEffects.TouchToMoveArrow' + Scale3D=(X=2.0000,Y=2.0000,Z=2.000) + + //bAllowApproximateOcclusion=True + //bForceDirectLightMap=True + //bCastDynamicShadow=False + //LightingChannels=(Dynamic=False,Static=True) + End Object + Components.Add(StaticMeshComponent0) +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/Ch11HUD.uc b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/Ch11HUD.uc new file mode 100644 index 0000000..1052e87 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/Ch11HUD.uc @@ -0,0 +1,133 @@ +class Ch11HUD extends UDKHud; + +var Texture DefaultTexture1; +var Texture DefaultTexture2; +var Texture DefaultTexture3; +var Texture DefaultTexture4; +var Texture DefaultTexture5; + +struct HUDInfo +{ + var string Label; + var Vector2D TextLocation; + var Color TextColor; + var Vector2D Scale; +}; + +// HUD +var HUDInfo HUDHealth; +var HUDInfo HUDAllyHealth; +var HUDInfo HUDObjectiveHealth; +var HUDInfo HUDGameOver; + + +simulated function PostBeginPlay() +{ + Super.PostBeginPlay(); + + HUDHealth.Label = "Health:"; + HUDHealth.TextLocation.x = 1100; + HUDHealth.TextLocation.y = 50; + HUDHealth.TextColor.R = 0; + HUDHealth.TextColor.G = 0; + HUDHealth.TextColor.B = 255; + HUDHealth.Scale.X = 2; + HUDHealth.Scale.Y = 4; + + HUDAllyHealth.Label = "AllyHealth:"; + HUDAllyHealth.TextLocation.x = 600; + HUDAllyHealth.TextLocation.y = 50; + HUDAllyHealth.TextColor.R = 0; + HUDAllyHealth.TextColor.G = 255; + HUDAllyHealth.TextColor.B = 0; + HUDAllyHealth.Scale.X = 2; + HUDAllyHealth.Scale.Y = 4; + + HUDGameOver.Label = "Objective Killed"; + HUDGameOver.TextLocation.x = 300; + HUDGameOver.TextLocation.y = 300; + HUDGameOver.TextColor.R = 255; + HUDGameOver.TextColor.G = 0; + HUDGameOver.TextColor.B = 255; + HUDGameOver.Scale.X = 7; + HUDGameOver.Scale.Y = 7; + + HUDObjectiveHealth.Label = "ObjectiveHealth:"; + HUDObjectiveHealth.TextLocation.x = 0; + HUDObjectiveHealth.TextLocation.y = 50; + HUDObjectiveHealth.TextColor.R = 255; + HUDObjectiveHealth.TextColor.G = 0; + HUDObjectiveHealth.TextColor.B = 0; + HUDObjectiveHealth.Scale.X = 2; + HUDObjectiveHealth.Scale.Y = 4; +} + +function DrawHUDItem(HUDInfo Info, coerce string Value) +{ + local Vector2D TextSize; + + Canvas.SetDrawColor(Info.TextColor.R, Info.TextColor.G, Info.TextColor.B); + Canvas.SetPos(Info.TextLocation.X, Info.TextLocation.Y); + Canvas.DrawText(Info.Label, ,Info.Scale.X,Info.Scale.Y); + Canvas.TextSize(Info.Label, TextSize.X, TextSize.Y); + Canvas.SetPos(Info.TextLocation.X + (TextSize.X * Info.Scale.X), Info.TextLocation.Y); + Canvas.DrawText(Value, , Info.Scale.X, Info.Scale.Y); +} + +function DrawHUD() +{ + local int Health; + + + super.DrawHUD(); + + /* + // Blend Modes = BLEND_Opaque, BLEND_Additive, and BLEND_Modulate modes + Canvas.SetPos(0,0); + Canvas.DrawTextureBlended(DefaultTexture1, 1, BLEND_Opaque); + + Canvas.SetPos(150,0); + Canvas.DrawTextureBlended(DefaultTexture2, 1, BLEND_Additive); + + Canvas.SetPos(300,0); + Canvas.DrawTextureBlended(DefaultTexture3, 1, BLEND_Masked); + + Canvas.SetPos(450,0); + Canvas.DrawTextureBlended(DefaultTexture4, 1,BLEND_Masked); + + Canvas.SetPos(600,0); + Canvas.DrawTextureBlended(DefaultTexture5, 1, BLEND_Masked); + + */ + + + Canvas.Font = class'Engine'.static.GetLargeFont(); + + // Objective Health + DrawHUDItem(HUDObjectiveHealth,ExampleCh11PC(PlayerOwner).ObjectiveHealth); + + // Ally Bot Health + Health = ExampleCh11PC(PlayerOwner).AllyBot.Pawn.Health; + DrawHUDItem(HUDAllyHealth, Health); + + // Health + DrawHUDItem(HUDHealth,PlayerOwner.Pawn.Health); + + // Game Over + if (ExampleCh11PC(PlayerOwner).bGameOVer) + { + DrawHUDItem(HUDGameOver, ""); + } + +} + +defaultProperties +{ + DefaultTexture1= Texture2D'EditorResources.Ambientcreatures' // Yellow Chick 32 by 32 + DefaultTexture2= Texture2D'EditorResources.Ammo' // Ammo Icon 32 by 32 + DefaultTexture3= Texture2D'EditorResources.LookTarget' // Target 32 by 32 + DefaultTexture4= Texture2D'EditorMaterials.Tick' // Green Check 32 by 32 + DefaultTexture5= Texture2D'EditorMaterials.GreyCheck' // Grey Check 32 by 32 + +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/ExampleCh11Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/ExampleCh11Game.uc new file mode 100644 index 0000000..714bd1a --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/ExampleCh11Game.uc @@ -0,0 +1,29 @@ +class ExampleCh11Game extends FrameworkGame; + + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh11Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh11.ExampleCh11PC' + DefaultPawnClass=class'JazzPawnDamage' + HUDType=class'Ch11HUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/ExampleCh11PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/ExampleCh11PC.uc new file mode 100644 index 0000000..d1eddaa --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/ExampleCh11PC.uc @@ -0,0 +1,296 @@ +class ExampleCh11PC extends SimplePC; + +var Controller AllyBot; +Var Pawn AllyPawn; + +var Controller GuardBot; +Var Pawn GuardPawn; + +var bool BotSpawned; +var Actor BotTarget; + +var float PickDistance; + +var bool bBotCommandStateActive; + +var int ObjectiveHealth; +var bool bGameOver; + + +function FindObjectiveHealth() +{ + local Generator TempGenerator; + + foreach AllActors(class'Generator', TempGenerator) + { + ObjectiveHealth = TempGenerator.Health; + } +} + +function Actor PickActor(Vector2D PickLocation, out Vector HitLocation, out TraceHitInfo HitInfo) +{ + local Vector TouchOrigin, TouchDir; + local Vector HitNormal; + local Actor PickedActor; + local vector Extent; + + //Transform absolute screen coordinates to relative coordinates + PickLocation.X = PickLocation.X / ViewportSize.X; + PickLocation.Y = PickLocation.Y / ViewportSize.Y; + + //Transform to world coordinates to get pick ray + LocalPlayer(Player).Deproject(PickLocation, TouchOrigin, TouchDir); + + //Perform trace to find touched actor + Extent = vect(0,0,0); + PickedActor = Trace(HitLocation, + HitNormal, + TouchOrigin + (TouchDir * PickDistance), + TouchOrigin, + True, + Extent, + HitInfo); + + //Return the touched actor for good measure + return PickedActor; +} + +function SetBotMarkerGraphic(vector Loc, optional vector offset) +{ + Loc = Loc + offset; + + If (BotTarget == None) + { + WorldInfo.Game.Broadcast(None,"Creating New Move Marker!!!!!!!!"); + BotTarget = Spawn(class'BotMarker2',,,Loc); + } + else + { + BotTarget.SetLocation(Loc); + } +} + +reliable server function ExecuteBotMoveCommand(Vector HitLocation) +{ + // 1. Set Marker + Hitlocation.z += 50; // Add offset to help bot navigate to point + SetBotMarkerGraphic(Hitlocation); + + // 2. Send Move Command to bot along with target location + BotAllyController(AllyBot).SetCommand(Move, BotTarget); +} + +function ExecuteBotAttackCommand(Actor Target) +{ + // 1. Set Marker + SetBotMarkerGraphic(Target.Location, vect(0,0,200)); + + // 2. Send Attack Command to bot along with target location + BotAllyController(AllyBot).SetCommand(Attack, Target); +} + +function SelectBotAllyGraphic(vector Loc) +{ + Loc.z += 200; // Add offset to help bot navigate to point + + SetBotMarkerGraphic(Loc); +} + +function Actor FindSpawnPad(int PadNumber) +{ + local BotSpawnPad TempSpawnPad; + local Actor ReturnSpawnPad; + + ReturnSpawnPad = None; + foreach AllActors(class'BotSpawnPad', TempSpawnPad) + { + if(TempSpawnPad.PadNumber == PadNumber) + { + ReturnSpawnPad = TempSpawnPad; + } + } + + return ReturnSpawnPad; +} + +function SpawnGuardBot(Vector SpawnLocation,optional Vector Offset) +{ + SpawnLocation = SpawnLocation + Offset; + + GuardBot = Spawn(class'BotControllerGuard',,,SpawnLocation); + GuardPawn = Spawn(class'GuardPawn',,,SpawnLocation); + GuardBot.Possess(GuardPawn,false); + + GuardPawn(GuardPawn).AddDefaultInventory(); + GuardPawn(GuardPawn).InitialLocation = SpawnLocation; + + GuardPawn.SetPhysics(PHYS_Falling); +} + +function CreateNewGuardBot() +{ + local Actor TempPad; + + TempPad = FindSpawnPad(0); + if (TempPad != None) + { + SpawnGuardBot(TempPad.Location); + } + +} + +function SpawnAllyBot(Vector SpawnLocation, optional Vector Offset) +{ + SpawnLocation = SpawnLocation + Offset; + + AllyBot = Spawn(class'BotAllyController',,,SpawnLocation); + AllyPawn = Spawn(class'BotPawn',,,SpawnLocation); + AllyBot.Possess(AllyPawn,false); + + BotAllyController(AllyBot).SetCommand(Follow, Pawn); + BotAllyController(AllyBot).BotOwner = Pawn; + + BotPawn(AllyPawn).AddDefaultInventory(); + BotPawn(AllyPawn).InitialLocation = SpawnLocation; + + AllyPawn.SetPhysics(PHYS_Falling); +} + +function bool IsActorAllyBot(Actor TestBot) +{ + local bool bretval; + + bretval = TestBot.IsA('BotPawn'); + return bretval; +} + +function bool IsActorGuardBot(Actor TestBot) +{ + local bool bretval; + + bretval = TestBot.IsA('GuardPawn'); + return bretval; +} + +function ProcessTouch(Actor TouchedActor, vector HitLocation) +{ + if (bBotCommandStateActive) + { + if (IsActorGuardBot(TouchedActor)) + { + ExecuteBotAttackCommand(TouchedActor); + bBotCommandStateActive = false; + } + else + if (!IsActorAllyBot(TouchedActor)) + { + ExecuteBotMoveCommand(HitLocation); + bBotCommandStateActive = false; + } + } + else + { + if (IsActorAllyBot(TouchedActor)) + { + SelectBotAllyGraphic(TouchedActor.Location); + bBotCommandStateActive = true; + } + else + { + // Start Firing pawn's weapon + StartFire(0); + } + } +} + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + local Actor TempActor; + local Vector HitLocation; + local TraceHitInfo HitInfo; + + retval = true; + + + if (EventType == ZoneEvent_Touch) + { + //WorldInfo.Game.Broadcast(self,"You touched the screen at = " @ + // TouchLocation.x @ " , " @ TouchLocation.y @ + // ", Zone Touched = " @ Zone); + + // Code for Setting Bot WayPoint + TempActor = PickActor(TouchLocation, HitLocation, HitInfo); + ProcessTouch(TempActor, HitLocation); + } + else + if(EventType == ZoneEvent_Update) + { + + } + else + if (EventType == ZoneEvent_UnTouch) + { + // Stop Firing Pawn's weapon + StopFire(0); + } + + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + + } + } +} + +function PlayerTick(float DeltaTime) +{ + local vector AllyBotPos; + + Super.PlayerTick(DeltaTime); + + + if (!BotSpawned) + { + AllyBotPos = Pawn.Location + Normal(Vector(Pawn.Rotation)) * 100; + SpawnAllyBot(AllyBotPos,vect(0,0,500)); + BotSpawned = true; + JazzPawnDamage(Pawn).InitialLocation = Pawn.Location; + CreateNewGuardBot(); + } + + FindObjectiveHealth(); + if (ObjectiveHealth <= 0) + { + bGameOver = true; + } +} + +defaultproperties +{ + BotSpawned=false + PickDistance = 10000 + bBotCommandStateActive = false + bGameOver = false +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/Generator.uc b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/Generator.uc new file mode 100644 index 0000000..eb7cc19 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/Generator.uc @@ -0,0 +1,67 @@ +class Generator extends Actor +placeable; + +var ParticleSystem ExplosionTemplate; +var ParticleSystemComponent Explosion; +var SoundCue HitSound; + +var int Health; +var Pawn Guard; + + +event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + //WorldInfo.Game.Broadcast(self,"Generator Has Been Damaged by " @ InstigatedBy); + + PlaySound(HitSound); + Explosion = WorldInfo.MyEmitterPool.SpawnEmitter(ExplosionTemplate, HitLocation); + BotControllerGuard(Guard.Controller).Threat = InstigatedBy.Pawn; + + if (InstigatedBy.IsA('ExampleCh11PC')) + { + Health = Health - Damage; + } +} + +event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + WorldInfo.Game.Broadcast(self,"Generator Has Been Touched by " @ Other ); +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=StaticMeshComponent0 + StaticMesh=StaticMesh'Pickups.Health_Large.Mesh.S_Pickups_Health_Large_Keg' + Scale3D=(X=5.0000,Y=5.0000,Z=5.000) + CollideActors=true + BlockActors=true + //bAllowApproximateOcclusion=True + //bForceDirectLightMap=True + //bCastDynamicShadow=False + //LightingChannels=(Dynamic=False,Static=True) + End Object + Components.Add(StaticMeshComponent0) + + Begin Object Class=CylinderComponent NAME=CollisionCylinder + CollideActors=true + BlockActors=true + CollisionRadius=+0140.000000 + CollisionHeight=+0140.000000 + End Object + Components.Add(CollisionCylinder) + CollisionComponent = CollisionCylinder + + bCollideActors=true + bBlockActors = true + + HitSound = SoundCue'A_Gameplay.Gameplay.A_Gameplay_ArmorHitCue' + ExplosionTemplate = ParticleSystem'Castle_Assets.FX.P_FX_Fire_SubUV_01' + + Guard = None; + Health = 300; + +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/GuardPawn.uc b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/GuardPawn.uc new file mode 100644 index 0000000..41451ce --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11/Classes/GuardPawn.uc @@ -0,0 +1,15 @@ +class GuardPawn extends BotPawnCh10; + +event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + PlaySound(HurtSound); + Health = Health - Damage; + + if (Health <= 0) + { + PlaySound(DeathSound); + destroy(); + } + + BotControllerGuard(Controller).Threat = InstigatedBy.Pawn; +} diff --git a/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11Map.udk b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11Map.udk new file mode 100644 index 0000000..7aa4331 Binary files /dev/null and b/Beginning iOS 3D Unreal Games Dev/Ch11/ExampleCh11Map.udk differ diff --git a/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/BotPawnCh12.uc b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/BotPawnCh12.uc new file mode 100644 index 0000000..218e1c9 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/BotPawnCh12.uc @@ -0,0 +1,27 @@ +class BotPawnCh12 extends BotPawn; + +var string CharacterName; +var int Experience; + + +event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + PlaySound(JazzHitSound); + Health = Health - Damage; + //WorldInfo.Game.Broadcast(self,self @ " Has Taken Damage IN TAKEDAMAGE, HEALTH = " @ Health); + + if (Health <= 0) + { + SetLocation(InitialLocation); + SetPhysics(PHYS_Falling); + + Health = 100; + Experience = 0; + } +} + +defaultproperties +{ + CharacterName = "TeamMember1" + Experience = 0; +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/Ch12HUD.uc b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/Ch12HUD.uc new file mode 100644 index 0000000..446c68d --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/Ch12HUD.uc @@ -0,0 +1,168 @@ +class Ch12HUD extends UDKHud; + +var Texture DefaultTexture1; +var Texture DefaultTexture2; +var Texture DefaultTexture3; +var Texture DefaultTexture4; +var Texture DefaultTexture5; + +struct HUDInfo +{ + var string Label; + var Vector2D TextLocation; + var Color TextColor; + var Vector2D Scale; +}; + +// HUD +var HUDInfo HUDHealth; +var HUDInfo HUDName; +var HUDInfo HUDExperience; +var HUDInfo HUDGameOver; + + +simulated function PostBeginPlay() +{ + Super.PostBeginPlay(); + + HUDHealth.Label = "HitPoints:"; + HUDHealth.TextLocation.x = 1100; + HUDHealth.TextLocation.y = 50; + HUDHealth.TextColor.R = 0; + HUDHealth.TextColor.G = 0; + HUDHealth.TextColor.B = 255; + HUDHealth.Scale.X = 2; + HUDHealth.Scale.Y = 4; + + HUDName.Label = "Name:"; + HUDName.TextLocation.x = 600; + HUDName.TextLocation.y = 50; + HUDName.TextColor.R = 0; + HUDName.TextColor.G = 255; + HUDName.TextColor.B = 0; + HUDName.Scale.X = 2; + HUDName.Scale.Y = 4; + + HUDGameOver.Label = "Objective Killed"; + HUDGameOver.TextLocation.x = 300; + HUDGameOver.TextLocation.y = 300; + HUDGameOver.TextColor.R = 255; + HUDGameOver.TextColor.G = 0; + HUDGameOver.TextColor.B = 255; + HUDGameOver.Scale.X = 7; + HUDGameOver.Scale.Y = 7; + + HUDExperience.Label = "Experience:"; + HUDExperience.TextLocation.x = 0; + HUDExperience.TextLocation.y = 50; + HUDExperience.TextColor.R = 255; + HUDExperience.TextColor.G = 0; + HUDExperience.TextColor.B = 0; + HUDExperience.Scale.X = 2; + HUDExperience.Scale.Y = 4; +} + +function DrawHUDItem(HUDInfo Info, coerce string Value) +{ + local Vector2D TextSize; + + Canvas.SetDrawColor(Info.TextColor.R, Info.TextColor.G, Info.TextColor.B); + Canvas.SetPos(Info.TextLocation.X, Info.TextLocation.Y); + Canvas.DrawText(Info.Label, ,Info.Scale.X,Info.Scale.Y); + Canvas.TextSize(Info.Label, TextSize.X, TextSize.Y); + Canvas.SetPos(Info.TextLocation.X + (TextSize.X * Info.Scale.X), Info.TextLocation.Y); + Canvas.DrawText(Value, , Info.Scale.X, Info.Scale.Y); +} + + + +function DrawPlayerHUD(Pawn HUDPawn) +{ + local string CharacterName; + local int Experience; + local int HitPoints; + + CharacterName = PlayerPawnCh12(HUDPawn).CharacterName; + Experience = PlayerPawnCh12(HUDPawn).Experience; + HitPoints = HUDPawn.Health; + + DrawHUDItem(HUDExperience, Experience); + DrawHUDItem(HUDName, CharacterName); + DrawHUDItem(HUDHealth, HitPoints); +} + +function DrawAllyHUD(Pawn HUDPawn) +{ + local string CharacterName; + local int Experience; + local int HitPoints; + + + CharacterName = BotPawnCh12(HUDPawn).CharacterName; + Experience = BotPawnCh12(HUDPawn).Experience; + HitPoints = HUDPawn.Health; + + DrawHUDItem(HUDExperience, Experience); + DrawHUDItem(HUDName, CharacterName); + DrawHUDItem(HUDHealth, HitPoints); +} + + +function DrawHUD() +{ + local Pawn HUDPawn; + + + super.DrawHUD(); + + /* + // Blend Modes = BLEND_Opaque, BLEND_Additive, and BLEND_Modulate modes + Canvas.SetPos(0,0); + Canvas.DrawTextureBlended(DefaultTexture1, 1, BLEND_Opaque); + + Canvas.SetPos(150,0); + Canvas.DrawTextureBlended(DefaultTexture2, 1, BLEND_Additive); + + Canvas.SetPos(300,0); + Canvas.DrawTextureBlended(DefaultTexture3, 1, BLEND_Masked); + + Canvas.SetPos(450,0); + Canvas.DrawTextureBlended(DefaultTexture4, 1,BLEND_Masked); + + Canvas.SetPos(600,0); + Canvas.DrawTextureBlended(DefaultTexture5, 1, BLEND_Masked); + + */ + + Canvas.Font = class'Engine'.static.GetLargeFont(); + + + HUDPawn = ExampleCh12PC(PlayerOwner).HUDPawn; + if (HUDPawn.IsA('PlayerPawnCh12')) + { + DrawPlayerHUD(HUDPawn); + } + else + if (HUDPawn.IsA('BotPawnCh12')) + { + DrawAllyHUD(HUDPawn); + } + + // Game Over + if (ExampleCh12PC(PlayerOwner).bGameOVer) + { + DrawHUDItem(HUDGameOver, ""); + } + +} + +defaultProperties +{ + DefaultTexture1= Texture2D'EditorResources.Ambientcreatures' // Yellow Chick 32 by 32 + DefaultTexture2= Texture2D'EditorResources.Ammo' // Ammo Icon 32 by 32 + DefaultTexture3= Texture2D'EditorResources.LookTarget' // Target 32 by 32 + DefaultTexture4= Texture2D'EditorMaterials.Tick' // Green Check 32 by 32 + DefaultTexture5= Texture2D'EditorMaterials.GreyCheck' // Grey Check 32 by 32 + +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/CharacterInfo.uc b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/CharacterInfo.uc new file mode 100644 index 0000000..21486ba --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/CharacterInfo.uc @@ -0,0 +1,10 @@ +class CharacterInfo extends Actor; + + +var int PlayerHitPoints; +var int PlayerExperience; + + +var int AllyHitPoints; +var int AllyExperience; + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/ExampleCh12Game.uc b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/ExampleCh12Game.uc new file mode 100644 index 0000000..8820adb --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/ExampleCh12Game.uc @@ -0,0 +1,29 @@ +class ExampleCh12Game extends FrameworkGame; + + +event OnEngineHasLoaded() +{ + WorldInfo.Game.Broadcast(self,"ExampleCh12Game Type Active - Engine Has Loaded !!!!"); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + return true; +} + +static event class SetGameType(string MapName, string Options, string Portal) +{ + return super.SetGameType(MapName, Options, Portal); +} + +defaultproperties +{ + PlayerControllerClass=class'ExampleCh12.ExampleCh12PC' + DefaultPawnClass=class'PlayerPawnCh12' + HUDType=class'Ch12HUD' + + bRestartLevel=false + bWaitingToStartMatch=true + bDelayedStart=false +} + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/ExampleCh12PC.uc b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/ExampleCh12PC.uc new file mode 100644 index 0000000..10d9106 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/ExampleCh12PC.uc @@ -0,0 +1,424 @@ +class ExampleCh12PC extends SimplePC; + +var Controller AllyBot; +Var Pawn AllyPawn; + +var Controller GuardBot; +Var Pawn GuardPawn; + +var bool BotSpawned; +var Actor BotTarget; + +var float PickDistance; + +var bool bBotCommandStateActive; + +var int ObjectiveHealth; +var bool bGameOver; + +var Pawn HUDPawn; + + +var CharacterInfo CharacterFile; + + + + + +function SaveCharacterInfo() +{ + class'Engine'.static.BasicSaveObject(CharacterFile, "CharacterInfo.bin", true, 1); +} + +function LoadCharacterInfo() +{ + class'Engine'.static.BasicLoadObject(CharacterFile, "CharacterInfo.bin", true, 1); +} + +function SaveSquadInfo() +{ + CharacterFile.PlayerHitPoints = PlayerPawnCh12(Pawn).Health; + CharacterFile.PlayerExperience = PlayerPawnCh12(Pawn).Experience; + + CharacterFile.AllyHitPoints = BotPawnCh12(AllyPawn).Health; + CharacterFile.AllyExperience = BotPawnCh12(AllyPawn).Experience; + + + SaveCharacterInfo(); +} + +function LoadSquadInfo() +{ + LoadCharacterInfo(); + + // Put data back into variables + + PlayerPawnCh12(Pawn).Health = CharacterFile.PlayerHitPoints; + PlayerPawnCh12(Pawn).Experience = CharacterFile.PlayerExperience; + + BotPawnCh12(AllyPawn).Health = CharacterFile.AllyHitPoints; + BotPawnCh12(AllyPawn).Experience = CharacterFile.AllyExperience; + + +} + +simulated function PostBeginPlay() +{ + Super.PostBeginPlay(); + + CharacterFile = Spawn(class'CharacterInfo'); + +} + +state PlayerWalking +{ +ignores SeePlayer, HearNoise, Bump; + + function PlayerMove( float DeltaTime ) + { + local vector X,Y,Z, NewAccel; + local eDoubleClickDir DoubleClickMove; + local rotator OldRotation; + local bool bSaveJump; + + if( Pawn == None ) + { + GotoState('Dead'); + } + else + { + GetAxes(Pawn.Rotation,X,Y,Z); + + // New Custom Code + NewAccel.y = PlayerInput.aStrafe; + NewAccel.x = PlayerInput.aForward; + NewAccel.Z = 0; + NewAccel = Pawn.AccelRate * Normal(NewAccel); + + if (IsLocalPlayerController()) + { + AdjustPlayerWalkingMoveAccel(NewAccel); + } + + DoubleClickMove = PlayerInput.CheckForDoubleClickMove( DeltaTime/WorldInfo.TimeDilation ); + + // Update rotation. + OldRotation = Rotation; + UpdateRotation( DeltaTime ); + bDoubleJump = false; + + if( bPressedJump && Pawn.CannotJumpNow() ) + { + bSaveJump = true; + bPressedJump = false; + } + else + { + bSaveJump = false; + } + + if( Role < ROLE_Authority ) // then save this move and replicate it + { + ReplicateMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); + } + else + { + ProcessMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); + } + bPressedJump = bSaveJump; + } + } + +} + +function FindObjectiveHealth() +{ + local Generator TempGenerator; + + foreach AllActors(class'Generator', TempGenerator) + { + ObjectiveHealth = TempGenerator.Health; + } +} + +function Actor PickActor(Vector2D PickLocation, out Vector HitLocation, out TraceHitInfo HitInfo) +{ + local Vector TouchOrigin, TouchDir; + local Vector HitNormal; + local Actor PickedActor; + local vector Extent; + + //Transform absolute screen coordinates to relative coordinates + PickLocation.X = PickLocation.X / ViewportSize.X; + PickLocation.Y = PickLocation.Y / ViewportSize.Y; + + //Transform to world coordinates to get pick ray + LocalPlayer(Player).Deproject(PickLocation, TouchOrigin, TouchDir); + + //Perform trace to find touched actor + Extent = vect(0,0,0); + PickedActor = Trace(HitLocation, + HitNormal, + TouchOrigin + (TouchDir * PickDistance), + TouchOrigin, + True, + Extent, + HitInfo); + + //Return the touched actor for good measure + return PickedActor; +} + +function SetBotMarkerGraphic(vector Loc, optional vector offset) +{ + Loc = Loc + offset; + + If (BotTarget == None) + { + WorldInfo.Game.Broadcast(None,"Creating New Move Marker!!!!!!!!"); + BotTarget = Spawn(class'BotMarker2',,,Loc); + } + else + { + BotTarget.SetLocation(Loc); + } +} + +reliable server function ExecuteBotMoveCommand(Vector HitLocation) +{ + // 1. Set Marker + Hitlocation.z += 50; // Add offset to help bot navigate to point + SetBotMarkerGraphic(Hitlocation); + + // 2. Send Move Command to bot along with target location + BotAllyController(AllyBot).SetCommand(Move, BotTarget); +} + +function ExecuteBotAttackCommand(Actor Target) +{ + // 1. Set Marker + SetBotMarkerGraphic(Target.Location, vect(0,0,200)); + + // 2. Send Attack Command to bot along with target location + BotAllyController(AllyBot).SetCommand(Attack, Target); +} + +function SelectBotAllyGraphic(vector Loc) +{ + Loc.z += 200; // Add offset to help bot navigate to point + + SetBotMarkerGraphic(Loc); +} + +function Actor FindSpawnPad(int PadNumber) +{ + local BotSpawnPad TempSpawnPad; + local Actor ReturnSpawnPad; + + ReturnSpawnPad = None; + foreach AllActors(class'BotSpawnPad', TempSpawnPad) + { + if(TempSpawnPad.PadNumber == PadNumber) + { + ReturnSpawnPad = TempSpawnPad; + } + } + + return ReturnSpawnPad; +} + +function SpawnGuardBot(Vector SpawnLocation,optional Vector Offset) +{ + SpawnLocation = SpawnLocation + Offset; + + GuardBot = Spawn(class'BotControllerGuard',,,SpawnLocation); + GuardPawn = Spawn(class'GuardPawn2',,,SpawnLocation); + GuardBot.Possess(GuardPawn,false); + + GuardPawn2(GuardPawn).AddDefaultInventory(); + GuardPawn2(GuardPawn).InitialLocation = SpawnLocation; + + GuardPawn.SetPhysics(PHYS_Falling); +} + +function CreateNewGuardBot() +{ + local Actor TempPad; + + TempPad = FindSpawnPad(0); + if (TempPad != None) + { + SpawnGuardBot(TempPad.Location); + } + +} + +function SpawnAllyBot(Vector SpawnLocation, optional Vector Offset) +{ + SpawnLocation = SpawnLocation + Offset; + + AllyBot = Spawn(class'BotAllyController',,,SpawnLocation); + AllyPawn = Spawn(class'BotPawnCh12',,,SpawnLocation); + AllyBot.Possess(AllyPawn,false); + + BotAllyController(AllyBot).SetCommand(Follow, Pawn); + BotAllyController(AllyBot).BotOwner = Pawn; + + BotPawnCh12(AllyPawn).AddDefaultInventory(); + BotPawnCh12(AllyPawn).InitialLocation = SpawnLocation; + + AllyPawn.SetPhysics(PHYS_Falling); +} + +function bool IsActorAllyBot(Actor TestBot) +{ + local bool bretval; + + bretval = TestBot.IsA('BotPawnCh12'); + return bretval; +} + +function bool IsActorGuardBot(Actor TestBot) +{ + local bool bretval; + + bretval = TestBot.IsA('GuardPawn2'); + return bretval; +} + +function SetHUDPawn(Actor TouchedActor) +{ + if (IsActorAllyBot(TouchedActor)) + { + HUDPawn = Pawn(TouchedActor); + } + else + { + // Set Default to Player Pawn + HUDPawn = Pawn; + } +} + +function ProcessTouch(Actor TouchedActor, vector HitLocation) +{ + if (bBotCommandStateActive) + { + if (IsActorGuardBot(TouchedActor)) + { + ExecuteBotAttackCommand(TouchedActor); + bBotCommandStateActive = false; + } + else + if (!IsActorAllyBot(TouchedActor)) + { + ExecuteBotMoveCommand(HitLocation); + bBotCommandStateActive = false; + } + } + else + { + if (IsActorAllyBot(TouchedActor)) + { + SelectBotAllyGraphic(TouchedActor.Location); + bBotCommandStateActive = true; + } + else + { + // Start Firing pawn's weapon + StartFire(0); + } + } +} + +function bool SwipeZoneCallback(MobileInputZone Zone, + float DeltaTime, + int Handle, + EZoneTouchEvent EventType, + Vector2D TouchLocation) +{ + local bool retval; + + local Actor TempActor; + local Vector HitLocation; + local TraceHitInfo HitInfo; + + retval = true; + + + if (EventType == ZoneEvent_Touch) + { + //WorldInfo.Game.Broadcast(self,"You touched the screen at = " @ + // TouchLocation.x @ " , " @ TouchLocation.y @ + // ", Zone Touched = " @ Zone); + + // Code for Setting Bot WayPoint + TempActor = PickActor(TouchLocation, HitLocation, HitInfo); + ProcessTouch(TempActor, HitLocation); + SetHUDPawn(TempActor); + } + else + if(EventType == ZoneEvent_Update) + { + + } + else + if (EventType == ZoneEvent_UnTouch) + { + // Stop Firing Pawn's weapon + StopFire(0); + } + + return retval; +} + +function SetupZones() +{ + Super.SetupZones(); + + // If we have a game class, configure the zones + if (MPI != None && WorldInfo.GRI.GameClass != none) + { + LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize); + + if (FreeLookZone != none) + { + FreeLookZone.OnProcessInputDelegate = SwipeZoneCallback; + + } + } +} + +function PlayerTick(float DeltaTime) +{ + local vector AllyBotPos; + + Super.PlayerTick(DeltaTime); + + + if (!BotSpawned) + { + AllyBotPos = Pawn.Location + Normal(Vector(Pawn.Rotation)) * 100; + SpawnAllyBot(AllyBotPos,vect(0,0,500)); + BotSpawned = true; + JazzPawnDamage(Pawn).InitialLocation = Pawn.Location; + CreateNewGuardBot(); + } + + FindObjectiveHealth(); + if (ObjectiveHealth <= 0) + { + bGameOver = true; + } +} + +defaultproperties +{ + BotSpawned=false + PickDistance = 10000 + bBotCommandStateActive = false + bGameOver = false +} + + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/GuardPawn2.uc b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/GuardPawn2.uc new file mode 100644 index 0000000..b286b70 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/GuardPawn2.uc @@ -0,0 +1,41 @@ +class GuardPawn2 extends BotPawnCh10; + +var int ExperienceValue; + +event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + PlaySound(HurtSound); + Health = Health - Damage; + + if (Health <= 0) + { + PlaySound(DeathSound); + + + // Add experience points to player or member of player's group if this pawn is killed by one of them + if (InstigatedBy.IsA('ExampleCh12PC')) + { + PlayerPawnCh12(InstigatedBy.Pawn).Experience += ExperienceValue; + } + else + if (InstigatedBy.IsA('BotAllyController')) + { + BotPawnCh12(InstigatedBy.Pawn).Experience += ExperienceValue; + } + + //destroy(); + SetLocation(InitialLocation); + SetPhysics(PHYS_Falling); + Health = 100; + + + } + + BotControllerGuard(Controller).Threat = InstigatedBy.Pawn; + +} + +defaultproperties +{ + ExperienceValue = 100; +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/LoadMarker.uc b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/LoadMarker.uc new file mode 100644 index 0000000..083a4cb --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/LoadMarker.uc @@ -0,0 +1,46 @@ +class LoadMarker extends Actor +placeable; + +var SoundCue SaveSound; + +event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + if (!Other.IsA('PlayerPawnCh12')) + { + return; + } + + PlaySound(SaveSound); + + ExampleCh12PC(Pawn(Other).Controller).LoadSquadInfo(); +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=StaticMeshComponent0 + StaticMesh=StaticMesh'HU_Deco_Statues.SM.Mesh.S_HU_Deco_Statues_SM_Statue03_01' + Scale3D=(X=2.0000,Y=2.0000,Z=2.000) + + //bAllowApproximateOcclusion=True + //bForceDirectLightMap=True + //bCastDynamicShadow=False + //LightingChannels=(Dynamic=False,Static=True) + End Object + Components.Add(StaticMeshComponent0) + + Begin Object Class=CylinderComponent NAME=CollisionCylinder + CollideActors=true + BlockActors=false + CollisionRadius=+0140.000000 + CollisionHeight=+0240.000000 + End Object + Components.Add(CollisionCylinder) + CollisionComponent = CollisionCylinder + + bCollideActors=true + bBlockActors = false + + SaveSound = SoundCue'A_Interface.menu.UT3MenuAcceptCue' + + +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/PlayerPawnCh12.uc b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/PlayerPawnCh12.uc new file mode 100644 index 0000000..543ce53 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/PlayerPawnCh12.uc @@ -0,0 +1,54 @@ +class PlayerPawnCh12 extends JazzPawnDamage; + +var bool bFollowPlayerRotation; +var string CharacterName; +var int Experience; + +//////////////////////////////////////// Top Down View ///////////////////////////////////////////// + +simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) +{ + out_CamLoc = Location; + out_CamLoc.Z += CamOffsetDistance; + + if(!bFollowPlayerRotation) + { + out_CamRot.Pitch = -16384; + out_CamRot.Yaw = 0; + out_CamRot.Roll = 0; + } + else + { + out_CamRot.Pitch = -16384; + out_CamRot.Yaw = Rotation.Yaw; + out_CamRot.Roll = 0; + } + + return true; +} + +simulated singular event Rotator GetBaseAimRotation() +{ + local rotator POVRot, tempRot; + + tempRot = Rotation; + tempRot.Pitch = 0; + SetRotation(tempRot); + POVRot = Rotation; + POVRot.Pitch = 0; + + return POVRot; +} + + +defaultproperties +{ + bFollowPlayerRotation = false + CamOffsetDistance= 1500.0 + + CharacterName = "Player" + Experience = 0 +} + + + diff --git a/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/SaveMarker.uc b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/SaveMarker.uc new file mode 100644 index 0000000..e0d76e0 --- /dev/null +++ b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12/Classes/SaveMarker.uc @@ -0,0 +1,51 @@ +class SaveMarker extends Actor +placeable; + +var SoundCue SaveSound; + +event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + if (!Other.IsA('PlayerPawnCh12')) + { + return; + } + + PlaySound(SaveSound); + + ExampleCh12PC(Pawn(Other).Controller).SaveSquadInfo(); + +} + +defaultproperties +{ + Begin Object Class=StaticMeshComponent Name=StaticMeshComponent0 + //StaticMesh=StaticMesh'CastleEffects.TouchToMoveArrow' + //StaticMesh'Castle_Assets.Meshes.SM_MonkStatue_01' + //StaticMesh'HU_Deco_Statues.SM.Mesh.S_HU_Deco_Statues_SM_Statue03_01' + StaticMesh=StaticMesh'FoliageDemo2.Mesh.S_Statue_01' + + Scale3D=(X=3.0000,Y=3.0000,Z=3.000) + + //bAllowApproximateOcclusion=True + //bForceDirectLightMap=True + //bCastDynamicShadow=False + //LightingChannels=(Dynamic=False,Static=True) + End Object + Components.Add(StaticMeshComponent0) + + Begin Object Class=CylinderComponent NAME=CollisionCylinder + CollideActors=true + BlockActors=false + CollisionRadius=+0140.000000 + CollisionHeight=+0240.000000 + End Object + Components.Add(CollisionCylinder) + CollisionComponent = CollisionCylinder + + bCollideActors=true + bBlockActors = false + + SaveSound = SoundCue'A_Interface.menu.UT3MenuAcceptCue' + + +} \ No newline at end of file diff --git a/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12Map.udk b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12Map.udk new file mode 100644 index 0000000..767b66c Binary files /dev/null and b/Beginning iOS 3D Unreal Games Dev/Ch12/ExampleCh12Map.udk differ diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..5d08af9 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,27 @@ +Freeware License, some rights reserved + +Copyright (c) 2012 Robert Chin + +Permission is hereby granted, free of charge, to anyone obtaining a copy +of this software and associated documentation files (the "Software"), +to work with the Software within the limits of freeware distribution and fair use. +This includes the rights to use, copy, and modify the Software for personal use. +Users are also allowed and encouraged to submit corrections and modifications +to the Software for the benefit of other users. + +It is not allowed to reuse, modify, or redistribute the Software for +commercial use in any way, or for a user’s educational materials such as books +or blog articles without prior permission from the copyright holder. + +The above copyright notice and this permission notice need to be included +in all copies or substantial portions of the software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..67ed9ae --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +#Apress Source Code + +This repository accompanies [*Beginning iOS 3D Unreal Games Development*](http://www.apress.com/9781430240358) by Robert Chin (Apress, 2012). + +![Cover image](9781430240358.jpg) + +Download the files as a zip using the green button, or clone the repository to your machine using Git. + +##Releases + +Release v1.0 corresponds to the code in the published book, without corrections or updates. + +##Contributions + +See the file Contributing.md for more information on how you can contribute to this repository. diff --git a/contributing.md b/contributing.md new file mode 100644 index 0000000..f6005ad --- /dev/null +++ b/contributing.md @@ -0,0 +1,14 @@ +# Contributing to Apress Source Code + +Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. + +## How to Contribute + +1. Make sure you have a GitHub account. +2. Fork the repository for the relevant book. +3. Create a new branch on which to make your change, e.g. +`git checkout -b my_code_contribution` +4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. +5. Submit a pull request. + +Thank you for your contribution! \ No newline at end of file