UDN
Search public documentation:

MobileVehicleExample
日本語訳
中国翻译
한국어

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 Home > Mobile Home > Mobile Vehicle Example

Mobile Vehicle Example


Last tested against UDK Oct, 2011

Overview


Vehicles in Unreal Engine 3 are physics simulated objects that provide new game play options to the player. Most vehicle types such as cars, trucks, tanks, helicopters or planes can all be simulated on mobile devices. The UDN provides a lot of information on vehicles already, and the aim of this document is to provide an example for mobile platforms such as iOS.

Related topics

MobileVehicleGameInfo


This custom GameInfo spawns a vehicle for the player, and gets the player to drive it automatically.

MobileVehicleGameInfo.uc
class MobileVehicleGameInfo extends SimpleGame;

function RestartPlayer(Controller NewPlayer)
{
  local NavigationPoint StartSpot;
  local int Idx;
  local array<SequenceObject> Events;
  local SeqEvent_PlayerSpawned SpawnedEvent;
  local Vehicle Vehicle;

  if (bRestartLevel && WorldInfo.NetMode!= NM_DedicatedServer && WorldInfo.NetMode!= NM_ListenServer)
  {
    return;
  }

  StartSpot = FindPlayerStart(NewPlayer, 255);

  if (StartSpot == None)
  {
    if (NewPlayer.StartSpot != None)
    {
      StartSpot = NewPlayer.StartSpot;
    }
    else
    {
      return;
    }
  }

  if (NewPlayer.Pawn == None)
  {
    NewPlayer.Pawn = Spawn(class'MobileVehiclePawn',,, StartSpot.Location, StartSpot.Rotation);
  }

  if (NewPlayer.Pawn == None)
  {
    NewPlayer.GotoState('Dead');

    if (PlayerController(NewPlayer) != None)
    {
      PlayerController(NewPlayer).ClientGotoState('Dead', 'Begin');
    }
  }
  else
  {
    NewPlayer.Pawn.SetAnchor(StartSpot);

    if (PlayerController(NewPlayer) != None)
    {
      PlayerController(NewPlayer).TimeMargin = -0.1;
      StartSpot.AnchoredPawn = None;
    }

    NewPlayer.Pawn.LastStartSpot = PlayerStart(StartSpot);
    NewPlayer.Pawn.LastStartTime = WorldInfo.TimeSeconds;
    NewPlayer.Possess(NewPlayer.Pawn, false);
    NewPlayer.ClientSetRotation(NewPlayer.Pawn.Rotation, true);

    SetPlayerDefaults(NewPlayer.Pawn);

    if (WorldInfo.GetGameSequence() != None)
    {
      WorldInfo.GetGameSequence().FindSeqObjectsByClass(class'SeqEvent_PlayerSpawned', true, Events);

      for (Idx = 0; Idx < Events.Length; Idx++)
      {
        SpawnedEvent = SeqEvent_PlayerSpawned(Events[Idx]);

        if (SpawnedEvent != None && SpawnedEvent.CheckActivate(NewPlayer,NewPlayer))
        {
          SpawnedEvent.SpawnPoint = startSpot;
          SpawnedEvent.PopulateLinkedVariableValues();
        }
      }
    }

    NewPlayer.Pawn.SetCollision(false, false, false);
    Vehicle = Spawn(class'MobileVehicleScorpion',,, StartSpot.Location, StartSpot.Rotation);

    if (Vehicle != None)
    {
      Vehicle.TryToDrive(NewPlayer.Pawn);
    }
  }
}

defaultproperties
{
  PlayerControllerClass=class'MobileVehiclePlayerController'
}

MobileVehiclePawn


This class was created because TickSpecial in SimplePawn tried to access the controller and was returning Access Nones. TickSpecial is stubbed to prevent this warning from occurring.

MobileVehiclePawn.uc
class MobileVehiclePawn extends SimplePawn;

event TickSpecial(float DeltaTime);

defaultproperties
{
}

MobileVehiclePlayerController


This class was created because PlayerTick in SimplePC was playing back foot step sounds, which is incorrect for driving. PlayerDriving has been altered to use PlayerInput.aForward and PlayerInput.aStrafe to control the vehicle. This is because the default virtual joy stick maps to these input variables.

Motion control is also added so that the player can tilt the device to control the vehicle.

MobileVehiclePlayerController.uc
class MobileVehiclePlayerController extends SimplePC;

function PlayerTick(float DeltaTime)
{
  Super(GamePlayerController).PlayerTick(DeltaTime);
}

state PlayerDriving
{
ignores SeePlayer, HearNoise, Bump;

  function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot);

  function ProcessDrive(float InForward, float InStrafe, float InUp, bool InJump)
  {
    local Vehicle CurrentVehicle;

    CurrentVehicle = Vehicle(Pawn);

    if (CurrentVehicle != None)
    {
      bPressedJump = InJump;
      CurrentVehicle.SetInputs(InForward, -InStrafe, InUp);
      CheckJumpOrDuck();
    }
  }

  function PlayerMove(float DeltaTime)
  {
    local float Forward, Strafe;

    UpdateRotation(DeltaTime);

    // Get the forward input information
    Forward = PlayerInput.aForward;
    // Get the strafe input information
    Strafe = PlayerInput.aStrafe;

    if (PlayerInput != None)
    {
      Forward = (((PlayerInput.aTilt.X * UnrRotToDeg) - 30.f) / 50.f) * -1.f;
      Strafe = (PlayerInput.aTilt.Z * UnrRotToDeg) / 20.f;
    }

    // Clamp the forward to within -1.f and 1.f
    Forward = FClamp(Forward, -1.f, 1.f);
    // Clamp the strafe to within -1.f and 1.f
    Strafe = FClamp(Strafe, -1.f, 1.f);

    ProcessDrive(Forward, Strafe, PlayerInput.aUp, bPressedJump);

    if (Role < ROLE_Authority)
    {
      ServerDrive(PlayerInput.aForward, PlayerInput.aStrafe, PlayerInput.aUp, bPressedJump, ((Rotation.Yaw & 65535) << 16) + (Rotation.Pitch & 65535));
    }

    bPressedJump = false;
  }

  event BeginState(Name PreviousStateName)
  {
    CleanOutSavedMoves();
  }

  event EndState(Name NextStateName)
  {
    CleanOutSavedMoves();
  }
}

defaultproperties
{
}

MobileVehicleScorpion


This class represents the Scorpion vehicle. It is simply a compilation of UTVehicle_Scorpion and UTVehicle_Scorpion_Content. SVehicle is used as the base for simplicity sakes.

MobileVehicleScorpion.uc
class MobileVehicleScorpion extends SVehicle;

var DynamicLightEnvironmentComponent LightEnvironment;

defaultproperties
{
  Health=300
  COMOffset=(X=-40.f,Y=0.f,Z=-36.f)
  UprightLiftStrength=280.f
  UprightTime=1.25f
  UprightTorqueStrength=500.f
  bCanFlip=true
  bHasHandbrake=true
  GroundSpeed=950
  AirSpeed=1100
  HeavySuspensionShiftPercent=0.75f
  MomentumMult=0.5f
  NonPreferredVehiclePathMultiplier=1.5f
  DrawScale=1.2f
  bAlwaysRelevant=true
  SquealThreshold=0.1f
  SquealLatThreshold=0.f2f
  LatAngleVolumeMult=30.f
  EngineStartOffsetSecs=2.f
  EngineStopOffsetSecs=1.f
  bAttachDriver=false
  BaseEyeheight=30
  Eyeheight=30

  Begin Object Class=AudioComponent Name=ScorpionEngineSound
    SoundCue=SoundCue'MobileVehicleContent.Sounds.ScorpionEngineLoopSoundCue'
  End Object
  EngineSound=ScorpionEngineSound
  Components.Add(ScorpionEngineSound);

  Begin Object Class=AudioComponent Name=ScorpionSquealSound
    SoundCue=SoundCue'MobileVehicleContent.Sounds.ScorpionSlideSoundCue'
  End Object
  SquealSound=ScorpionSquealSound
  Components.Add(ScorpionSquealSound);

  CollisionSound=SoundCue'MobileVehicleContent.Sounds.ScorpionCollideSoundCue'
  EnterVehicleSound=SoundCue'MobileVehicleContent.Sounds.ScorpionStartSoundCue'

  Begin Object Name=CollisionCylinder
    BlockNonZeroExtent=false
    BlockZeroExtent=false
    BlockActors=false
    BlockRigidBody=false
    CollideActors=false
    CollisionHeight=40.f
    CollisionRadius=100.f
    Translation=(X=-25.f)
  End Object

  Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment
    bSynthesizeSHLight=true
    bIsCharacterLightEnvironment=true
    bUseBooleanEnvironmentShadowing=true
  End Object
  Components.Add(MyLightEnvironment)
  LightEnvironment=MyLightEnvironment

  Begin Object Name=SVehicleMesh
    CastShadow=true
    bCastDynamicShadow=true
    bOverrideAttachmentOwnerVisibility=true
    bAcceptsDynamicDecals=false
    bPerBoneMotionBlur=true
    LightEnvironment=MyLightEnvironment
    SkeletalMesh=SkeletalMesh'MobileVehicleContent.SkeletalMeshes.ScorpionSkeletalMesh'
    AnimTreeTemplate=AnimTree'MobileVehicleContent.AnimTrees.ScorpionAnimTree'
    PhysicsAsset=PhysicsAsset'MobileVehicleContent.PhysicsAssets.ScorpionPhysicsAsset'
    AnimSets.Add(AnimSet'MobileVehicleContent.AnimSets.ScorpionAnimSet')
    RBCollideWithChannels=(Default=true,BlockingVolume=true,GameplayPhysics=true,EffectPhysics=true,Vehicle=true,Untitled4=true)
  End Object

  Begin Object Class=UDKVehicleSimCar Name=SimObject
    WheelSuspensionStiffness=100.f
    WheelSuspensionDamping=3.f
    WheelSuspensionBias=0.1f
    ChassisTorqueScale=0.f
    MaxBrakeTorque=5.f
    StopThreshold=100
    MaxSteerAngleCurve=(Points=((InVal=0.f,OutVal=45.f),(InVal=600.f,OutVal=15.f),(InVal=1100.f,OutVal=10.f),(InVal=1300.f,OutVal=6.f),(InVal=1600.f,OutVal=1.f)))
    SteerSpeed=110
    LSDFactor=0.f
    TorqueVSpeedCurve=(Points=((InVal=-600.f,OutVal=0.f),(InVal=-300.f,OutVal=80.f),(InVal=0.f,OutVal=130.f),(InVal=950.f,OutVal=130.f),(InVal=1050.f,OutVal=10.f),(InVal=1150.f,OutVal=0.f)))
    EngineRPMCurve=(Points=((InVal=-500.f,OutVal=2500.f),(InVal=0.f,OutVal=500.f),(InVal=549.f,OutVal=3500.f),(InVal=550.f,OutVal=1000.f),(InVal=849.f,OutVal=4500.f),(InVal=850.f,OutVal=1500.f),(InVal=1100.f,OutVal=5000.f)))
    EngineBrakeFactor=0.f25f
    ThrottleSpeed=0.2f
    WheelInertia=0.2f
    NumWheelsForFullSteering=4
    SteeringReductionFactor=0.f
    SteeringReductionMinSpeed=1100.f
    SteeringReductionSpeed=1400.f
    bAutoHandbrake=true
    bClampedFrictionModel=true
    FrontalCollisionGripFactor=0.18f
    ConsoleHardTurnGripFactor=1.f
    HardTurnMotorTorque=0.7f
    SpeedBasedTurnDamping=20.f
    AirControlTurnTorque=40.f
    InAirUprightMaxTorque=15.f
    InAirUprightTorqueFactor=-30.f
    WheelLongExtremumSlip=0.1f
    WheelLongExtremumValue=1.f
    WheelLongAsymptoteSlip=2.f
    WheelLongAsymptoteValue=0.6f
    WheelLatExtremumSlip=0.35f
    WheelLatExtremumValue=0.9f
    WheelLatAsymptoteSlip=1.4f
    WheelLatAsymptoteValue=0.9f
    bAutoDrive=false
    AutoDriveSteer=0.3f
  End Object
  SimObj=SimObject
  Components.Add(SimObject)

  Begin Object Class=MobileVehicleScorpionWheel Name=RRWheel
    BoneName="B_R_Tire"
    BoneOffset=(X=0.f,Y=20.f,Z=0.f)
    SkelControlName="B_R_Tire_Cont"
  End Object
  Wheels(0)=RRWheel

  Begin Object Class=MobileVehicleScorpionWheel Name=LRWheel
    BoneName="B_L_Tire"
    BoneOffset=(X=0.f,Y=-20.f,Z=0.f)
    SkelControlName="B_L_Tire_Cont"
  End Object
  Wheels(1)=LRWheel

  Begin Object Class=MobileVehicleScorpionWheel Name=RFWheel
    BoneName="F_R_Tire"
    BoneOffset=(X=0.f,Y=20.f,Z=0.f)
    SteerFactor=1.f
    LongSlipFactor=2.f
    LatSlipFactor=3.f
    HandbrakeLongSlipFactor=0.8
    HandbrakeLatSlipFactor=0.8
    SkelControlName="F_R_Tire_Cont"
  End Object
  Wheels(2)=RFWheel

  Begin Object Class=MobileVehicleScorpionWheel Name=LFWheel
    BoneName="F_L_Tire"
    BoneOffset=(X=0.f,Y=-20.f,Z=0.f)
    SteerFactor=1.f
    LongSlipFactor=2.f
    LatSlipFactor=3.f
    HandbrakeLongSlipFactor=0.8f
    HandbrakeLatSlipFactor=0.8f
    SkelControlName="F_L_Tire_Cont"
  End Object
  Wheels(3)=LFWheel
}

MobileVehicleScorpionWheel


This class is the same as UTVehicleScorpionWheel which can be found in the UTGame package.

MobileVehicleScorpionWheel.uc
class MobileVehicleScorpionWheel extends UDKVehicleWheel;

defaultproperties
{
  WheelRadius=27
  SuspensionTravel=40
  bPoweredWheel=true
  SteerFactor=0.0
  LongSlipFactor=2.0
  LatSlipFactor=2.75
  HandbrakeLongSlipFactor=0.7
  HandbrakeLatSlipFactor=0.3
  ParkedSlipFactor=10.0
}

Downloads


  • Download the content and code used in this example.