I have ended up finding a solution to this by using script. the solution is from http://udn.epicgames.com/Three/MobileInputSystem.html under the mobile input in unrealscript. The documentation is pretty much accurate and complete, so thanks for that epic guys 
im using udk-2012-3
I've posted all the script, skeletalmesh and kismet settings that i've used in case it helps anyone else out there.
im creating a kids game, a chameleon that goes around eating bugs.
cham.jpg
in the image i have butterflies that i want the user to be able to touch and then the chameleon goes over and grabs them with his tongue and eats them. the image is from the pc previewer, the mobile previewer looks good too, but doesnt have depth of field. (does anyone know if it is possible to do DOF on mobile?)
I found out that the butterfly skeletalmesh needs collisions on, which by default doesnt seem to happen. so i used the per bone collisions and turned off the default simple line and simple box collision
mesh.jpg
Kismet is used to spawn butterflies. the actor factory used the butterflycontroller and butterflypawn classes. the factory type is actoryfactoryAI. and then there are a number of pathnodes to spawn at.
kismet.jpg
now the scripting
my classes are all in the one spot
C:\UDK\UDK-2012-03\Development\Src\ChamGame\Classes
Firstly an interface that the pawns will be derived from. this is straight from the documentation
ITouchable.uc
Code:
Interface ITouchable;
function OnTouch(ETouchType Type, float X, float Y);
next a child class of MobilePlaceablePawn, which implements the interface. when you click on a pawn it shows a message on screen saying the pawn name
UDNMobilePawn.uc
Code:
class UDNMobilePawn extends MobilePlaceablePawn implements(ITouchable);
function OnTouch(ETouchType Type, float X, float Y)
{
WorldInfo.Game.Broadcast(self, "Touched:"@self);
}
next my butterfly pawn class, with a lot of default settings, the most important being the mesh, the animtree and the animset. i have all my assets in the kismetgame_assets.
ButterflyPawn.uc
Code:
class ButterflyPawn extends UDNMobilePawn;
defaultproperties
{
GroundSpeed=200.0
AirSpeed=200.0
WaterSpeed=220.0
AccelRate=2048.0
LandMovementState=PlayerFlying
Components.Remove(Sprite)
Begin Object Class=SkeletalMeshComponent Name=WPawnSkeletalMeshComponent
SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.butterfly_mesh'
AnimTreeTemplate=AnimTree'KismetGame_Assets.Anims.Butterfly_Animtree'
// PhysicsAsset=PhysicsAsset'CH_AnimCorrupt.Mesh.SK_CH_Corrupt_Male_Physics'
AnimSets(0)=AnimSet'KismetGame_Assets.Anims.Butterfly_AnimSet'
Scale= 100
//General Mesh Properties
bCacheAnimSequenceNodes=FALSE
AlwaysLoadOnClient=true
AlwaysLoadOnServer=true
bOwnerNoSee=false
CastShadow=true
BlockRigidBody=TRUE
bUpdateSkelWhenNotRendered=false
bIgnoreControllersWhenNotRendered=TRUE
bUpdateKinematicBonesFromAnimation=true
bCastDynamicShadow=true
RBChannel=RBCC_Untitled3
RBCollideWithChannels=(Untitled3=true)
LightEnvironment=MyLightEnvironment
bOverrideAttachmentOwnerVisibility=true
bAcceptsDynamicDecals=FALSE
bHasPhysicsAssetInstance=false
TickGroup=TG_PreAsyncWork
MinDistFactorForKinematicUpdate=0.2
bChartDistanceFactor=true
RBDominanceGroup=20
bUseOnePassLightingOnTranslucency=TRUE
bPerBoneMotionBlur=true
End Object
Mesh=WPawnSkeletalMeshComponent
Components.Add(WPawnSkeletalMeshComponent)
Begin Object Name=CollisionCylinder
CollisionRadius=+150.000000
CollisionHeight=+100.000000
End Object
CylinderComponent=CollisionCylinder
}
Next the butterfly controller which provides the AI for my butterfly ( it flys to random pathnodes on the map)
ButterflyController.uc
Code:
class ButterflyController extends AIController;
var array<Pathnode> nodes;
var Pathnode node;
simulated function PostBeginPlay()
{
foreach Worldinfo.AllActors(class'Pathnode', node)
{
nodes.AddItem(node);
}
}
event Possess(Pawn inPawn, bool bVehicleTransition)
{
super.Possess(inPawn, bVehicleTransition);
Pawn.SetMovementPhysics();
}
auto state Idle
{
Begin:
MoveTo(nodes[Rand(nodes.Length)].Location);
goto 'Begin';
}
DefaultProperties
{
}
Now the complicated one, fortunately this comes straight from the mobile documentation. the GamePlayerController class.
It handles any touch or swipe and works out if a pawn based on the interface ITouchable has been touched. if it has, it calls the pawns OnTouch method which in my case displays the pawns name on screen (for the moment)
ChamGamePlayerController.uc
Code:
class ChamGamePlayerController extends GamePlayerController;
/** Holds the dimensions of the device's screen */
var vector2D ViewportSize;
/** If TRUE, a new touch was detected (must be the only touch active) */
var bool bPendingTouch;
/** Holds the handle of the most recent touch */
var int PendingTouchHandle;
/** Holds the Actor that was selected */
var Actor SelectedActor;
/** Maximum distance an Actor can be to be picked */
var float PickDistance;
/** Maximum amount the mouse can move between touch and untouch to be considered a 'click' */
var float ClickTolerance;
/** Cache a reference to the MobilePlayerInput */
var MobilePlayerInput MPI;
/** find actor under touch location
*
* @PickLocation - Screen coordinates of touch
*/
function Actor PickActor(Vector2D PickLocation)
{
local Vector TouchOrigin, TouchDir;
local Vector HitLocation, HitNormal;
local Actor PickedActor;
//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
PickedActor = Trace(HitLocation, HitNormal, TouchOrigin + (TouchDir * PickDistance), TouchOrigin, true);
//Casting to ITouchable determines if the touched actor can indeed be touched
if(Itouchable(PickedActor) != none)
{
Itouchable(PickedActor).OnTouch(Touch_Began, PickLocation.X, PickLocation.Y);
}
//Return the touched actor for good measure
return PickedActor;
}
function HandleInputTouch(int Handle, ETouchType Type, Vector2D TouchLocation, float DeviceTimestamp, int TouchpadIndex)
{
local Actor PickedActor;
local int i;
//New touch event
if(Type == Touch_Began)
{
//Specify a new touch has occurred
PendingTouchHandle = Handle;
bPendingTouch = true;
}
//Touch in progress
else if(Type == Touch_Moved)
{
for(i=0; i<MPI.NumTouchDataEntries; i++)
{
//Test distance touch has moved and cancel touch if moved too far; update touch location if not
if(MPI.Touches[i].Handle == PendingTouchHandle && MPI.Touches[i].TotalMoveDistance > ClickTolerance)
{
bPendingTouch = false;
}
}
}
//End of touch
else if(Type == Touch_Ended)
{
//Check if a touch is active
if(Handle == PendingTouchHandle && bPendingTouch)
{
//Get actor under touch
PickedActor = PickActor(TouchLocation);
//Check if actor is touchable and set it as selected; clear current selected if not
if(ITouchable(PickedActor) != none)
{
SelectedActor = PickedActor;
}
else
{
SelectedActor = none;
}
//cancel active touch
bPendingTouch = false;
}
}
}
event InitInputSystem()
{
Super.InitInputSystem();
//Get a reference to the local MobilePlayerInput
MPI = MobilePlayerInput(PlayerInput);
//Accessing the input handler function to the delegate
MPI.OnInputTouch = HandleInputTouch;
//get the screen dimensions (used to transform to relative screen coords for the DeProject)
LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize);
}
defaultproperties
{
PickDistance=10000
ClickTolerance=5
InputClass=class'GameFramework.MobilePlayerInput'
}
lastly we need to create a gametype that uses the ChamGamePlayerController
ChamGame.uc
Code:
class ChamGame extends SimpleGame;
defaultproperties
{
PlayerControllerClass=class'ChamGame.ChamGamePlayerController'
DefaultPawnClass=class'ChamGame.UDNMobilePawn'
bDelayedStart=false
}
In the worldInfo property, we have to set the gametype to ChamGame to actually make use of the gametype.
The defaultpawnclass setting probably isnt needed in my case because i am specifically spawning pawns based on the UDNMobilePawn anyway, but it is in the doucmentation, so i left it in.
Hopefully the above helps anyone else looking at mobile touch games.
Cheers
Anton
Bookmarks