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.