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
  }
  

내려받기


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