UDN
Search public documentation:

MobileVehicleExampleKR
English Translation
日本語訳
中国翻译

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 홈 > 모바일 홈 > 모바일 비히클 예제

모바일 비히클 예제


문서 변경내역: James Tan 작성. 홍성진 번역.
UDK 2011년 10월 버전으로 최종 테스팅

개요


언리얼 엔진 3의 비히클(Vehicle, 탈것)이란, 플레이어에게 새로운 게임플레이 옵션이 될 수 있는 물리 시뮬레이팅 오브젝트를 말합니다. 차, 트럭, 탱크, 헬리콥터, 비행기와 같은 대부분의 비히클 타입 전부 모바일 디바이스에서 시뮬레이팅 가능합니다. 비히클 관련 정보는 이미 UDN에 많이 있으니, 여기서는 iOS 같은 모바일 플랫폼용 예제에만 충실하도록 하겠습니다.

관련 토픽

MobileVehicleGameInfo


플레이어용 비히클을 스폰하고, 플레이어가 자동으로 운전하도록 하는 커스텀 GameInfo 입니다.

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


이 클래스를 만든 이유는, SimplePawn 의 TickSpecial 이 콘트롤러를 액세스하려 한 데다 Access Nodes 를 반환하기 때문입니다. 이러한 경고 발생을 방지하기 위해 TickSpecial 을 stub화했습니다.

MobileVehiclePawn.uc
class MobileVehiclePawn extends SimplePawn;

event TickSpecial(float DeltaTime);

defaultproperties
{
}

MobileVehiclePlayerController


이 클래스를 만든 이유는, SimplePC 의 PlayerTick 이 발자욱 소리를 재생하는데, 탑승시에는 맞지 않기 때문입니다. 비히클 제어를 위해 PlayerInput.aForward 와 PlayerInput.aStrafe 를 사용하도록 PlayerDriving 을 변경했습니다. 디폴트 가상 조이스틱이 이 입력 변수로 매핑되기 때문입니다.

플레이어가 디바이스를 기울여(tilt) 비히클을 제어할 수 있도록 하기 위해 모션 콘트롤도 추가했습니다.

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);

    // 포워드 입력 정보 구하기
    Forward = PlayerInput.aForward;
    // 스트레이프 입력 정보 구하기
    Strafe = PlayerInput.aStrafe;

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

    // 포워드 값을 -1.f 에서 1.f 범위로 제한
    Forward = FClamp(Forward, -1.f, 1.f);
    // 스트레이프 값을 -1.f 에서 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


이 클래스는 스콜피온 비히클을 나타냅니다. 그저 UTVehicle_Scorpion 과 UTVehicle_Scorpion_Content 를 컴파일했을 뿐입니다. 단순성을 위해 SVehicle 을 베이스로 사용합니다.

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


이 클래스는 UTGame 패키지에서 찾을 수 있는 UTVehicleScorpionWheel 과 같습니다.

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
}

내려받기


  • 이 예제에서 사용된 콘텐츠와 코드 내려받기.