UDN
Search public documentation:
CameraTechnicalGuideJP
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
中国翻译
한국어
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 ホーム > ゲームプレイプログラミング > カメラの技術ガイド
カメラの技術ガイド
概観
Camera (カメラ)
- General
- PCOwner - このカメラを所有する PlayerController への参照。
- CameraStyle - このカメラにおける現在のカメラモード。ビューターゲットによって視点がオーバーライドされていないときに、カメラのスタイル(たとえば、1 人称、3 人称、フリーなど)を決定するために使用します。
- Target - カメラが"追跡する" Target のアクタです。
- TViewTarget
- Target - 理想的な視点を計算するために使用されるターゲットアクタです。
- Controller - Target のコントローラです。(Pawn の場合)
- POV - Target のための理想的な視点です。タイプは TPOV です。
- TPOV
- Location - 視点の位置です。
- Rotation - 視点の回転です。
- FOV - 視点のための視野角です。
- AspectRatio - Target のために使用するアスペクト比です。
- PRI - Pawn の遷移を通じて同一プレーヤーを追尾するために使用するプレーヤーの複製情報です。
- TPOV
- POV - Target のための理想的な視点です。タイプは TPOV です。
- FOV
- DefaultFOV - カメラのためのデフォルトの視野角です。
- bLockedFOV - True の場合は、カメラの視野角が LockedFOV の値にロックされます。
- LockedFOV - FOV(視野角)がロックされたときに使用する視野角です。
- Aspect Ratio
- DefaultAspectRatio - カメラのためのデフォルトのアスペクト比です。
- bConstrainAspectRatio - True の場合、カメラのアスペクト比が、 ConstrainedAspectRatio の値に制約されます。
- ConstrainedAspectRatio - カメラのアスペクト比が制約されているときに使用するアスペクト比です。
- General
- UpdateCamera [DeltaTime] - 1 フレームにつき 1 回呼び出されることによって、カメラの更新を実行します。
- DeltaTime - 最後の更新が行われてから経過した時間です。
- GetCameraViewPoint [OutCamLoc] [OutCamRot] - カメラの位置と回転を検索します。この関数を直接呼び出してはいけません。そのかわりに、 PCOwner の GetPlayerViewPoint() 関数を呼び出します。
- OutCamLoc - カメラの位置を出力します。
- OutCamRot - カメラの回転を出力します。
- ProcessViewRotation [DeltaTime] [OutViewRotation] [OutDeltaRot] - 各カメラモディファイアに適用して、視界回転とデルタ回転の調整を可能にします。
- DeltaTime - 最後の更新が行われてから経過した時間です。
- OutViewRotation - 調整されたカメラの視点回転を出力します。
- OutDeltaRot - 調整されたカメラのデルタ回転を出力します。
- UpdateCamera [DeltaTime] - 1 フレームにつき 1 回呼び出されることによって、カメラの更新を実行します。
- FOV
- GetFOVAngle - カメラの現在の視野角を返します。
- SetFOV [NewFOV] - カメラの視野角を NewFOV という値に設定します。
- NewFOV - カメラの視野角として設定する値です。
- View Target
- SetViewTarget [NewViewTarget] [TransitionParams] - カメラのビューターゲットを設定します。
- NewViewTarget - カメラのビューターゲットとして設定するアクタです。
- TransitionParams - 新たなビューターゲットに遷移するときに使用するブレンドパラメータです。
- UpdateViewTarget [OutVT] [DeltaTime] - カメラのビューターゲットにオーバーライドする機会を与えるあいだに、カメラのビューターゲットを設定します。
- OutVT - ビューターゲットとカメラの視点を保持しているデータ構造体を出力します。
- DeltaTime - 最後の更新が行われてから経過した時間です。
- SetViewTarget [NewViewTarget] [TransitionParams] - カメラのビューターゲットを設定します。
ポストプロセスエフェクト
ポストプロセスエフェクトとは、プレーヤーに表示される前のレンダリングされたシーンに対して適用するエフェクトのことです。カメラはそれぞれ自身のポストプロセス設定を適用することができます。この設定は、ワールドまたはボリューム、デフォルトのポストプロセスの設定をオーバーライドできます。 ポストプロセスエフェクトの詳細については、ポストプロセス エディタ ユーザガイドおよびポストプロセス テクニカルガイド 、ポストプロセスによるマテリアル使用法をご覧ください。 Post Process Effects Properties- CameOverridePostProcessAlpha - ワールドおよびボリューム、デフォルトのポストプロセス設定に対して、カメラのポストプロセス設定がもつ影響度を設定します。値が 0.0 の場合は、ワールドおよびボリューム、デフォルトのポストプロセスが、完全な影響度をもちます。値が 1.0 の場合は、カメラのポストプロセスが、完全な影響度をもちます。
- CamPostProcessSettings - カメラが、ワールドおよびボリューム、デフォルトのポストプロセスをオーバーライドしている時に使用するポストプロセスの設定です。
- bEnableColorScaling - True の場合は、最終イメージ内のカラーチャンネルが、 ColorScale の値に基づいてスケーリングされます。
- ColorScale -最終イメージ内の個々のカラーチャンネルをスケーリングするためのベクタです。
- bEnableColorScaleInterp - True の場合、カメラは、新たなカラースケーリング値が SetDesiredColorScale() 関数を通じて設定される際に、カラースケーリング間で補間します。
- bEnableFading - True の場合、カメラは、 FadeColor の FadeAmount をスクリーンに適用します。
- FadeColor - カメラがフェードしつつあるときにスクリーンに適用するカラーです。
- FadeAmount - 適用するフェード量です。基本的には、フェードのアルファです。
- SetDesiredColorScale [NewColorScale] [InterpTime] - 新たなカラースケーリング値を設定します。また、任意で、 bEnableColorScaleInterp の値に基づいて補間します。
- NewColorScale - カラースケーリングのために使用する新たな値です。
- InterpTime - 新たなカラースケーリング値に対して補間するのに必要となる時間です。
レンズエフェクト
レンズエフェクトとは、プレーヤーのカメラのレンズに適用するパーティクルエフェクトのことです。このレンズエフェクトを使用することによって、カメラレンズを滴り落ちる雨とか、レンズ上に飛び散る血や泥、ホコリといったものを作ることができます。カメラクラスには、これらのタイプのエフェクトを適用させる関数が含まれています。 パーティクルエフェクトの詳細については、パーティクル システムをご覧ください。 Lens Effects Properties-
- CameraLensEffects - カメラに現在適用されているすべてのパーティクルエフェクトの配列です。
- FindCameraLensEffect [LensEffectEmitterClass] - 現在カメラに適用されているレンズエフェクトを検索し、合致するタイプのものをすべて返します。
- LensEffectEmitterType - 検索するレンズエフェクトのクラスです。
- AddCameraLensEffect [LensEffectEmitterClass] -指定された種類の新たなレンズエフェクトをカメラに適用します。
- LensEffectEmitterClass - カメラに適用するレンズエフェクトのクラスです。
- RemoveCameraLensEffect [Emitter] - カメラからレンズエフェクトを削除します。
- Emitter - カメラから削除するレンズエフェクトです。
- ClearCameraLensEffects - カメラに現在適用されているレンズエフェクトをすべて削除します。
カメラアニメーション
カメラアニメーションとは、 Matinee 内で作成されるアニメーションのことです。(任意で、外部のアニメーションエディタで作成、インポートすることができます)これは、アニメーションの平行移動および回転の情報を使用することによって、再生中にカメラをオフセットするとともに、通常 Matinee でアニメートが可能なカメラがもつ他のプロパティをアニメートできるようにします。これは、カメラ振動や手で支えられたカメラの上下動など、アニメーションエフェクトを作成する場合に、たいへん便利です。 カメラアニメーションの詳細については、カメラのセットアップをご覧ください。 Camera Animation Functions- PlayCameraAnim [CameraAnim] [Rate] [Scale] [BlendInTime] [BlendOutTime] [bLoop] [bRandomStartTime] [Duration] [bSingleInstance] - カメラ上でカメラアニメーションを再生します。
- CameraAnim - 再生するカメラアニメーションです。
- Rate - 任意。カメラアニメーションを再生するスピードです。
- Scale - 任意。カメラアニメーションの変形に適用する強度乗数です。
- BlendInTime - 任意。カメラアニメーションにブレンドするのにかかる時間です。
- BlendOutTime - 任意。カメラアニメーションからブレンドするのにかかる時間です。
- bLoop - 任意。True の場合、カメラアニメーションは、明示的に停止されるまでループし続けます。
- bRandomStartTime - 任意。True の場合、カメラアニメーションは、アニメーションのタイムライン内のランダムな時間に再生を開始します。
- Duration - 任意。アニメーションを再生する時間です。これが設定されていない場合は、アニメーション全体が再生されます。
- bSingleInstance - 任意。True の場合、カメラ振動のインスタンスが、1 度に 1 つだけ存在することが許されます。
- StopAllCameraAnims [bImmediate] - 現在再生中のカメラアニメーションをすべて停止します。
- bImmediate - 任意。True の場合、アニメーションは、設定されているブレンド時間を無視して、即座に停止します。
- StopAllCameraAnimsByType [Anim] [bImmediate] - 特定のタイプのカメラアニメーションのインスタンスをすべて停止します。
- Anim - 停止するカメラアニメーションのタイプです。
- bImmediate - 任意。True の場合、アニメーションは、設定されているブレンド時間を無視して、即座に停止します。
- StopCameraAnim [AnimInst] [bImmediate] - カメラアニメーションの特定のインスタンスを停止します。
- AnimInst - 停止するカメラアニメーションです。
- bImmediate - 任意。True の場合、アニメーションは、設定されているブレンド時間を無視して、即座に停止します。
カメラモディファイア
カメラモディファイアは、カメラに適用した場合に、そのカメラのプロパティを修正することができるオブジェクトです。 CameraModifier クラスは、これらのエフェクトのための基本クラスです。このクラスをサブクラス化し、中の関数をオーバーライドすることによって、完全にカスタム仕様のモディファイアを作成できます。 CameraModifier_CameraShake クラスは、カメラモディファイアを使用してできるものの良い例です。 Camera Modifier Properties-
- ModifierList - カメラに現在適用されているすべてのカメラモディファイアの配列です。
- CameraShakeModClass - 円錐主導型カメラ振動(例: Kismet による非カメラのアニメーションスクリーン振動)のために使用するクラスです。
- PlayCameraShake [Shake] [Scale] [PlaySpace] [UserPlaySpaceRot] - カメラ振動エフェクトをカメラ上で再生します。
- Shake - カメラ振動エフェクトのために使用する、 CamerShake の設定値です。
- Scale - カメラ振動の設定値に掛け合わせるスケーリング係数です。
- PlaySpace - 任意。カメラ振動のために使用する空間を再生します。
- UserPlaySpaceRot - 任意。ユーザーによって定義された再生空間のために使用する回転です。
- StopCameraShake [Shake] - カメラ上でカメラ振動エフェクトを再生するのを停止します。
- Shake - 再生を停止するカメラ振動です。
- CalcRadialCameraShake [Cam] [Epicenter] [InnerRadius] [OuterRadius] [Falloff] - ラジアル振動の特定カメラに関する強度を計算して返します。
- Cam - 強度を計算するカメラです。
- Epicenter - カメラ振動の発生源の位置です。
- InnerRadius - フォールオフが始まる地点からの距離です。
- OuterRadius - カメラ振動エフェクトの終わる地点からの距離です。
- Falloff - 強度のフォールオフを計算するために使われる指数です。
- PlayWorldCameraShake [Shake] [ShakeInstigator] [Epicenter] [InnerRadius] [OuterRadius] [Falloff] [bTrForceFeedback] [bOrientShakeTowardEpicenter] - 近くにある全カメラに影響を及ぼすインワールドのカメラ振動を再生します。
- Shake - 再生するカメラ振動です。
- ShakeInstigator - カメラ振動の原因となるアクタです。
- Epicenter - カメラ振動の発生源の位置です。
- InnerRadius - フォールオフが始まる地点からの距離です。
- OuterRadius - カメラ振動エフェクトの終わる地点からの距離です。
- Falloff - 強度のフォールオフを計算するために使われる指数です。
- bTryForceFeedback - True の場合は、影響を受けているあらゆるコントローラーに対して、力フィードバックの適用が試みられます。
- bOrientShakeTowardEpicenter - 任意。True の場合、カメラ振動内のあらゆるオフセットが、発生地点に向き合うことに関連して適用されます。その場合、正の X 軸は、発生地点に向かっています。
- ClearAllCameraShakes - カメラに現在適用されているカメラ振動をすべて削除します。
プレーヤーコントローラー
- PlayerCamera - プレーヤーのカメラへの参照です。
- CameraClass - プレーヤーのために使用されるカメラのクラスです。
- ViewTarget - プレーヤーのカメラがもつ現在のビューターゲットです。
- RealViewTarget - プレーヤーのカメラがもつビューターゲットのプレーヤー複製情報です。
- FOVangle - プレーヤーのカメラの視野角です。
- DefaultFOV - プレーヤーのカメラのために使用されるデフォルトの視野角です。
- GetPlayerViewPoint [out_Location] [out_Rotation] - Controller が所有する Pawn の視点を返します。人プレーヤーにとっては、カメラの視点になります。AI に制御されるプレーヤーにとっては、 Pawn の目から見た視点になります。基本的な実装では、単に Controller 自体の位置と回転に相当します。
- out_Location - プレーヤーの視点の位置を出力します。
- out_Rotation - プレーヤーの視点の回転を出力します。
- GetActorEyesViewPoint [out_Location] [out_Rotation] - Controller またはその Pawn が存在している場合、その視点を返します。基本的には、プレーヤーがどの方向をどこから見ているかという情報を返します。
- out_Location - プレーヤーの目の位置を出力します。
- out_Rotation - プレーヤーの目の回転を出力します。
- UpdateRotation [DeltaTime] - プレーヤーの入力に基づいて、 Controller の回転および Controller が所有する Pawn の回転を更新します。
- DeltaTime - 最後の更新が行われてから経過した時間です。
- ProcessViewRotation [DeltaTime] [out_ViewRotation] [DeltaRot] - プレーヤーの入力に基づいて、プレーヤーの視点の回転を処理するとともに、その結果得られる回転を出力します。この関数は、 UpdateRotation() によって呼び出されます。
- DeltaTime - 最後の更新が行われてから経過した時間です。
- out_ViewRotation - プレーヤーの視点回転を出力します。
- DeltaRot - プレーヤーの入力による回転の変更です。
- PlayerMove [DeltaTime] - 現在の移動のために新たな加速値と回転値を計算します。その後、 ProcessMove()(プレーヤーが1人の場合またはリッスンサーバーの場合)、または、 ReplicateMove()(ネットワーククライアントの場合)のいずれかを呼び出します。基本 PlayerController クラスにおいては、この関数はスタブにすぎませんが、 PlayerWalking ステートなどのような移動に関係する何らかのステート内においては、オーバーライドされます。この関数は、 PlayerTick() 関数によって毎サイクルごとに呼び出されます。
- ProcessMove [DeltaTime] [newAccel] [DoubleClickMove] [DeltaRot] - クライアント上で現在の移動を処理します。この関数は、移動のために特別な機能が必要となるある種のステート内で、オーバーライドされます。
Pawn (ポーン)
- CalcCamera [DeltaTime] [out_CamLoc] [out_CamRot] [out_FOV] - Pawn から眺めた時のカメラの視点を計算します。これがプレーヤーのための主となるカメラ計算となります。
- DeltaTime - 最後の更新が行われてから経過した時間です。
- out_CamLoc - カメラの位置を出力します。
- out_CamRot - カメラの回転を出力します。
- out_FOV - カメラの視野角を出力します。
- GetDefaultCameraMode [RequestedBy] - この Pawn のために使用されるべきデフォルトのカメラモードを名前として返します。この関数は、 Pawn を所有する時にコントローラーによって呼び出されます。
- RequestedBy - デフォルトのカメラモードを必要とするコントローラーです。
- ProcessViewRotation [deltaTime] [out_ViewRotation] [out_DeltaRot] - プレーヤーの視点の回転を処理するとともに、 out_ViewRotation パラメータとして最終的な視点の回転を返します。この関数は、 PlayerController の UpdateRotation() 関数から呼び出されます。
- deltaTime - 最後に更新が行われてから経過した時間です。
- out_ViewRotation - Pawn の視点の回転を出力します。
- out_DeltaRot - デルタ回転を出力します。
- SetViewRotation [NewRotation] - Controller が存在する場合は、その回転を設定します。 Controller が存在しない場合は、 Pawn 自体の回転を設定します。
- NewRotation - Pawn の視点に設定する新しい回転です。
- GetActorEyesViewPoint [out_Location] [out_Rotation] - Pawn の目、すなわち、プレーヤーの視点の位置と志向性を返します。第 1 の人のパースペクティブについては、カメラの位置および志向性と同一です。これは、大多数のトレースが実行される際の起点となる視点ともなります。
- out_Location - Pawn の目の位置を出力します。
- out_Rotation - Pawn の目の回転を出力します。
カメラの動作をカスタマイズする
例
class UDNGame extends UTDeathMatch; defaultproperties { DefaultPawnClass=class'UDNExamples.UDNPawn' PlayerControllerClass=class'UDNExamples.UDNPlayerController' MapPrefixes[0]="UDN" }
[Engine.GameInfo] DefaultGame=UDNExamples.UDNGame DefaultServerGame=UDNExamples.UDNGame
一人称カメラの例
一人称のパースペクティブは、 UTPawn を拡張した Pawn クラスのためのデフォルトのカメラタイプです。例は、関連するクラスそれぞれから、カメラタイプを構成する中心部分を抜粋し、新しいサブクラスに配置したものです。これによって、基本的な一人称カメラを作成する際に関連するプロセスについて、効果的に説明することができます。 UDNPawn.ucclass UDNPawn extends UTPawn; simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) { // Calculate first person camera position and rotation GetActorEyesViewPoint( out_CamLoc, out_CamRot ); return true; } defaultproperties { }
Class UDNPlayerController extends UTPlayerController; state PlayerWalking { ignores SeePlayer, HearNoise, Bump; function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { if( Pawn == None ) { return; } if (Role == ROLE_Authority) { // Update ViewPitch for remote clients Pawn.SetRemoteViewPitch( Rotation.Pitch ); } Pawn.Acceleration = NewAccel; CheckJumpOrDuck(); } } function UpdateRotation( float DeltaTime ) { local Rotator DeltaRot, newRotation, ViewRotation; ViewRotation = Rotation; if (Pawn!=none) { Pawn.SetDesiredRotation(ViewRotation); } // Calculate Delta to be applied on ViewRotation DeltaRot.Yaw = PlayerInput.aTurn; DeltaRot.Pitch = PlayerInput.aLookUp; ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot ); SetRotation(ViewRotation); NewRotation = ViewRotation; NewRotation.Roll = Rotation.Roll; if ( Pawn != None ) Pawn.FaceRotation(NewRotation, deltatime); } defaultproperties { }
三人称カメラの例
UTPawn から派生するすべてのサブクラスのための代替カメラタイプとして、三人称カメラの設定も含まれています。例では、中心部分を抜粋し、デフォルトのカメラをオーバーライドすることによって、三人称カメラにしています。 UDNPawn.ucclass UDNPawn extends UTPawn; //override to make player mesh visible by default simulated event BecomeViewTarget( PlayerController PC ) { local UTPlayerController UTPC; Super.BecomeViewTarget(PC); if (LocalPlayer(PC.Player) != None) { UTPC = UTPlayerController(PC); if (UTPC != None) { //set player controller to behind view and make mesh visible UTPC.SetBehindView(true); SetMeshVisibility(UTPC.bBehindView); } } } simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) { local vector CamStart, HitLocation, HitNormal, CamDirX, CamDirY, CamDirZ, CurrentCamOffset; local float DesiredCameraZOffset; CamStart = Location; CurrentCamOffset = CamOffset; DesiredCameraZOffset = (Health > 0) ? 1.2 * GetCollisionHeight() + Mesh.Translation.Z : 0.f; CameraZOffset = (fDeltaTime < 0.2) ? DesiredCameraZOffset * 5 * fDeltaTime + (1 - 5*fDeltaTime) * CameraZOffset : DesiredCameraZOffset; if ( Health <= 0 ) { CurrentCamOffset = vect(0,0,0); CurrentCamOffset.X = GetCollisionRadius(); } CamStart.Z += CameraZOffset; GetAxes(out_CamRot, CamDirX, CamDirY, CamDirZ); CamDirX *= CurrentCameraScale; if ( (Health <= 0) || bFeigningDeath ) { // adjust camera position to make sure it's not clipping into world // @todo fixmesteve. Note that you can still get clipping if FindSpot fails (happens rarely) FindSpot(GetCollisionExtent(),CamStart); } if (CurrentCameraScale < CameraScale) { CurrentCameraScale = FMin(CameraScale, CurrentCameraScale + 5 * FMax(CameraScale - CurrentCameraScale, 0.3)*fDeltaTime); } else if (CurrentCameraScale > CameraScale) { CurrentCameraScale = FMax(CameraScale, CurrentCameraScale - 5 * FMax(CameraScale - CurrentCameraScale, 0.3)*fDeltaTime); } if (CamDirX.Z > GetCollisionHeight()) { CamDirX *= square(cos(out_CamRot.Pitch * 0.0000958738)); // 0.0000958738 = 2*PI/65536 } out_CamLoc = CamStart - CamDirX*CurrentCamOffset.X + CurrentCamOffset.Y*CamDirY + CurrentCamOffset.Z*CamDirZ; if (Trace(HitLocation, HitNormal, out_CamLoc, CamStart, false, vect(12,12,12)) != None) { out_CamLoc = HitLocation; } return true; } defaultproperties { }
Class UDNPlayerController extends UTPlayerController; state PlayerWalking { ignores SeePlayer, HearNoise, Bump; function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { if( Pawn == None ) { return; } if (Role == ROLE_Authority) { // Update ViewPitch for remote clients Pawn.SetRemoteViewPitch( Rotation.Pitch ); } Pawn.Acceleration = NewAccel; } } function UpdateRotation( float DeltaTime ) { local Rotator DeltaRot, newRotation, ViewRotation; ViewRotation = Rotation; if (Pawn!=none) { Pawn.SetDesiredRotation(ViewRotation); } // Calculate Delta to be applied on ViewRotation DeltaRot.Yaw = PlayerInput.aTurn; DeltaRot.Pitch = PlayerInput.aLookUp; ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot ); SetRotation(ViewRotation); NewRotation = ViewRotation; NewRotation.Roll = Rotation.Roll; if ( Pawn != None ) Pawn.FaceRotation(NewRotation, deltatime); } defaultproperties { }
トップダウン(上からの)カメラの例
トップダウンカメラは、修正を加えることによって作成できます。三人称カメラの設定と似ていますが、 Pawn の回転が制限されます。特に、ピッチが制限されます。これは、上下に照準を向けることができないためです。 UDNPawn.ucclass UDNPawn extends UTPawn; var float CamOffsetDistance; //distance to offset the camera above the player var bool bFollowPlayerRotation; //If true, camera rotates with player //override to make player mesh visible by default simulated event BecomeViewTarget( PlayerController PC ) { local UTPlayerController UTPC; Super.BecomeViewTarget(PC); if (LocalPlayer(PC.Player) != None) { UTPC = UTPlayerController(PC); if (UTPC != None) { //set player controller to behind view and make mesh visible UTPC.SetBehindView(true); SetMeshVisibility(UTPC.bBehindView); UTPC.bNoCrosshair = true; } } } simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) { out_CamLoc = Location; out_CamLoc.Z += CamOffsetDistance; if(!bFollowPlayerRotation) { out_CamRot.Pitch = -16384; out_CamRot.Yaw = 0; out_CamRot.Roll = 0; } else { out_CamRot.Pitch = -16384; out_CamRot.Yaw = Rotation.Yaw; out_CamRot.Roll = 0; } return true; } simulated singular event Rotator GetBaseAimRotation() { local rotator POVRot, tempRot; tempRot = Rotation; tempRot.Pitch = 0; SetRotation(tempRot); POVRot = Rotation; POVRot.Pitch = 0; return POVRot; } defaultproperties { bFollowPlayerRotation = false; CamOffsetDistance=384.0 }
Class UDNPlayerController extends UTPlayerController; state PlayerWalking { ignores SeePlayer, HearNoise, Bump; function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { if( Pawn == None ) { return; } if (Role == ROLE_Authority) { // Update ViewPitch for remote clients Pawn.SetRemoteViewPitch( Rotation.Pitch ); } Pawn.Acceleration = NewAccel; CheckJumpOrDuck(); } } function UpdateRotation( float DeltaTime ) { local Rotator DeltaRot, newRotation, ViewRotation; ViewRotation = Rotation; if (Pawn!=none) { Pawn.SetDesiredRotation(ViewRotation); } // Calculate Delta to be applied on ViewRotation DeltaRot.Yaw = PlayerInput.aTurn; DeltaRot.Pitch = 0; ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot ); SetRotation(ViewRotation); NewRotation = ViewRotation; NewRotation.Roll = Rotation.Roll; if ( Pawn != None ) Pawn.FaceRotation(NewRotation, deltatime); } defaultproperties { }
等角投影法カメラの例
単純な等角投影法型のカメラは、先に解説したトップダウンカメラの例にかなり類似しています。カメラは、X 軸とZ 軸 2 つの軸に沿ったオフセットで、ピッチは、下に回転してプレーヤーにフォーカスします。 UDNPawn.ucclass UDNPawn extends UTPawn; var float CamOffsetDistance; //distance to offset the camera from the player var int IsoCamAngle; //pitch angle of the camera //override to make player mesh visible by default simulated event BecomeViewTarget( PlayerController PC ) { local UTPlayerController UTPC; Super.BecomeViewTarget(PC); if (LocalPlayer(PC.Player) != None) { UTPC = UTPlayerController(PC); if (UTPC != None) { //set player controller to behind view and make mesh visible UTPC.SetBehindView(true); SetMeshVisibility(UTPC.bBehindView); UTPC.bNoCrosshair = true; } } } simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) { out_CamLoc = Location; out_CamLoc.X -= Cos(IsoCamAngle * UnrRotToRad) * CamOffsetDistance; out_CamLoc.Z += Sin(IsoCamAngle * UnrRotToRad) * CamOffsetDistance; out_CamRot.Pitch = -1 * IsoCamAngle; out_CamRot.Yaw = 0; out_CamRot.Roll = 0; return true; } simulated singular event Rotator GetBaseAimRotation() { local rotator POVRot, tempRot; tempRot = Rotation; tempRot.Pitch = 0; SetRotation(tempRot); POVRot = Rotation; POVRot.Pitch = 0; return POVRot; } defaultproperties { IsoCamAngle=6420 //35.264 degrees CamOffsetDistance=384.0 }
Class UDNPlayerController extends UTPlayerController; state PlayerWalking { ignores SeePlayer, HearNoise, Bump; function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { if( Pawn == None ) { return; } if (Role == ROLE_Authority) { // Update ViewPitch for remote clients Pawn.SetRemoteViewPitch( Rotation.Pitch ); } Pawn.Acceleration = NewAccel; CheckJumpOrDuck(); } } function UpdateRotation( float DeltaTime ) { local Rotator DeltaRot, newRotation, ViewRotation; ViewRotation = Rotation; if (Pawn!=none) { Pawn.SetDesiredRotation(ViewRotation); } // Calculate Delta to be applied on ViewRotation DeltaRot.Yaw = PlayerInput.aTurn; DeltaRot.Pitch = 0; ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot ); SetRotation(ViewRotation); NewRotation = ViewRotation; NewRotation.Roll = Rotation.Roll; if ( Pawn != None ) Pawn.FaceRotation(NewRotation, deltatime); } defaultproperties { }
横スクロールカメラの例
横スクロールカメラでは、カメラの視点を制御する必要があるだけでなく、プレーヤーによる入力の処理の仕方を修正する必要があります。プレーヤーは、スクリーン上で左右の移動しか許可されず、常に移動する方向に面しているように強いられます。入力は、A のキーと D のキーによってプレーヤーが前後に移動するようにしなければなりません。 UDNPawn.ucclass UDNPawn extends UTPawn; var float CamOffsetDistance; //Position on Y-axis to lock camera to //override to make player mesh visible by default simulated event BecomeViewTarget( PlayerController PC ) { local UTPlayerController UTPC; Super.BecomeViewTarget(PC); if (LocalPlayer(PC.Player) != None) { UTPC = UTPlayerController(PC); if (UTPC != None) { //set player controller to behind view and make mesh visible UTPC.SetBehindView(true); SetMeshVisibility(UTPC.bBehindView); UTPC.bNoCrosshair = true; } } } simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) { out_CamLoc = Location; out_CamLoc.Y = CamOffsetDistance; out_CamRot.Pitch = 0; out_CamRot.Yaw = 16384; out_CamRot.Roll = 0; return true; } simulated singular event Rotator GetBaseAimRotation() { local vector POVLoc; POVRot = Rotation; if( (Rotation.Yaw % 65535 > 16384 && Rotation.Yaw % 65535 < 49560) || (Rotation.Yaw % 65535 < -16384 && Rotation.Yaw % 65535 > -49560) ) { POVRot.Yaw = 32768; } else { POVRot.Yaw = 0; } if( POVRot.Pitch == 0 ) { POVRot.Pitch = RemoteViewPitch << 8; } return POVRot; } defaultproperties { CamOffsetDistance=0.0 }
Class UDNPlayerController extends UTPlayerController; state PlayerWalking { ignores SeePlayer, HearNoise, Bump; function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { local Rotator tempRot; if( Pawn == None ) { return; } if (Role == ROLE_Authority) { // Update ViewPitch for remote clients Pawn.SetRemoteViewPitch( Rotation.Pitch ); } Pawn.Acceleration.X = -1 * PlayerInput.aStrafe * DeltaTime * 100 * PlayerInput.MoveForwardSpeed; Pawn.Acceleration.Y = 0; Pawn.Acceleration.Z = 0; tempRot.Pitch = Pawn.Rotation.Pitch; tempRot.Roll = 0; if(Normal(Pawn.Acceleration) Dot Vect(1,0,0) > 0) { tempRot.Yaw = 0; Pawn.SetRotation(tempRot); } else if(Normal(Pawn.Acceleration) Dot Vect(1,0,0) < 0) { tempRot.Yaw = 32768; Pawn.SetRotation(tempRot); } CheckJumpOrDuck(); } } function UpdateRotation( float DeltaTime ) { local Rotator DeltaRot, newRotation, ViewRotation; ViewRotation = Rotation; // Calculate Delta to be applied on ViewRotation DeltaRot.Yaw = Pawn.Rotation.Yaw; DeltaRot.Pitch = PlayerInput.aLookUp; ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot ); SetRotation(ViewRotation); } defaultproperties { }
オールインワンカメラの例
この例では、他のすべての例を、単一の実装にまとめたものです。それによって、プレーヤーが、いずれかのカメラタイプに切り替えることができ、実行関数を通じてそれらを調節することができます。 UDNPawn.ucclass UDNPawn extends UTPawn; Enum CameraPerspective { CAM_FirstPerson, CAM_ThirdPerson, CAM_TopDown, CAM_SideScroller, CAM_Isometric }; var bool bFollowPlayerRotation; var CameraPerspective CameraType; var float CamOffsetDistance; var int IsoCamAngle; exec function CameraMode(CameraPerspective mode) { local UTPlayerController UTPC; CameraType = mode; UTPC = UTPlayerController(Controller); if (UTPC != None) { if(CameraType != CAM_FirstPerson) { UTPC.SetBehindView(true); if(CameraType != CAM_ThirdPerson) { UTPC.bNoCrosshair = true; } else { UTPC.bNoCrosshair = false; } } else { UTPC.bNoCrosshair = false; UTPC.SetBehindView(false); } SetMeshVisibility(UTPC.bBehindView); } } exec function IsoAngle(int angle) { IsoCamAngle = angle; } /* BecomeViewTarget Called by Camera when this actor becomes its ViewTarget */ simulated event BecomeViewTarget( PlayerController PC ) { local UTPlayerController UTPC; Super.BecomeViewTarget(PC); if (LocalPlayer(PC.Player) != None) { UTPC = UTPlayerController(PC); if (UTPC != None) { if(CameraType != CAM_FirstPerson) { UTPC.SetBehindView(true); if(CameraType != CAM_ThirdPerson) { UTPC.bNoCrosshair = true; } else { UTPC.bNoCrosshair = false; } } else { UTPC.bNoCrosshair = false; UTPC.SetBehindView(false); } SetMeshVisibility(UTPC.bBehindView); } } } /** * Calculate camera view point, when viewing this pawn. * * @param fDeltaTime delta time seconds since last update * @param out_CamLoc Camera Location * @param out_CamRot Camera Rotation * @param out_FOV Field of View * * @return true if Pawn should provide the camera point of view. */ simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) { // Handle the fixed camera if (bFixedView) { out_CamLoc = FixedViewLoc; out_CamRot = FixedViewRot; } else { if ( CameraType == CAM_ThirdPerson ) // Handle BehindView { CalcThirdPersonCam(fDeltaTime, out_CamLoc, out_CamRot, out_FOV); } else if ( CameraType == CAM_TopDown ) // Handle BehindView { CalcTopDownCam(fDeltaTime, out_CamLoc, out_CamRot, out_FOV); } else if ( CameraType == CAM_SideScroller ) // Handle BehindView { CalcSideScrollerCam(fDeltaTime, out_CamLoc, out_CamRot, out_FOV); } else if ( CameraType == CAM_Isometric ) // Handle BehindView { CalcIsometricCam(fDeltaTime, out_CamLoc, out_CamRot, out_FOV); } else { // By default, we view through the Pawn's eyes.. GetActorEyesViewPoint( out_CamLoc, out_CamRot ); } if ( UTWeapon(Weapon) != none) { UTWeapon(Weapon).WeaponCalcCamera(fDeltaTime, out_CamLoc, out_CamRot); } } return true; } simulated function bool CalcTopDownCam( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) { out_CamLoc = Location; out_CamLoc.Z += CamOffsetDistance; if(!bFollowPlayerRotation) { out_CamRot.Pitch = -16384; out_CamRot.Yaw = 0; out_CamRot.Roll = 0; } else { out_CamRot.Pitch = -16384; out_CamRot.Yaw = Rotation.Yaw; out_CamRot.Roll = 0; } return true; } simulated function bool CalcSideScrollerCam( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) { out_CamLoc = Location; out_CamLoc.Y = CamOffsetDistance; out_CamRot.Pitch = 0; out_CamRot.Yaw = 16384; out_CamRot.Roll = 0; return true; } simulated function bool CalcIsometricCam( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) { out_CamLoc = Location; out_CamLoc.X -= Cos(IsoCamAngle * UnrRotToRad) * CamOffsetDistance; out_CamLoc.Z += Sin(IsoCamAngle * UnrRotToRad) * CamOffsetDistance; out_CamRot.Pitch = -1 * IsoCamAngle; out_CamRot.Yaw = 0; out_CamRot.Roll = 0; return true; } /** * returns base Aim Rotation without any adjustment (no aim error, no autolock, no adhesion.. just clean initial aim rotation!) * * @return base Aim rotation. */ simulated singular event Rotator GetBaseAimRotation() { local vector POVLoc; local rotator POVRot, tempRot; if(CameraType == CAM_TopDown || CameraType == CAM_Isometric) { tempRot = Rotation; tempRot.Pitch = 0; SetRotation(tempRot); POVRot = Rotation; POVRot.Pitch = 0; } else if(CameraType == CAM_SideScroller) { POVRot = Rotation; if( (Rotation.Yaw % 65535 > 16384 && Rotation.Yaw % 65535 < 49560) || (Rotation.Yaw % 65535 < -16384 && Rotation.Yaw % 65535 > -49560) ) { POVRot.Yaw = 32768; } else { POVRot.Yaw = 0; } if( POVRot.Pitch == 0 ) { POVRot.Pitch = RemoteViewPitch << 8; } } else { if( Controller != None && !InFreeCam() ) { Controller.GetPlayerViewPoint(POVLoc, POVRot); return POVRot; } else { POVRot = Rotation; if( POVRot.Pitch == 0 ) { POVRot.Pitch = RemoteViewPitch << 8; } } } return POVRot; } defaultproperties { CameraType=CAM_FirstPerson; bFollowPlayerRotation = false; CamOffsetDistance=384.0 IsoCamAngle=6420 //35.264 degrees }
class UDNPlayerController extends UTPlayerController; state PlayerWalking { function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { local UDNPawn P; local Rotator tempRot; if( (Pawn != None) ) { P = UDNPawn(Pawn); if(P != none) { if(P.CameraType == CAM_SideScroller) { Pawn.Acceleration.X = -1 * PlayerInput.aStrafe * DeltaTime * 100 * PlayerInput.MoveForwardSpeed; Pawn.Acceleration.Y = 0; Pawn.Acceleration.Z = 0; tempRot.Pitch = P.Rotation.Pitch; tempRot.Roll = 0; if(Normal(Pawn.Acceleration) Dot Vect(1,0,0) > 0) { tempRot.Yaw = 0; P.SetRotation(tempRot); } else if(Normal(Pawn.Acceleration) Dot Vect(1,0,0) < 0) { tempRot.Yaw = 32768; P.SetRotation(tempRot); } } else { if ( (DoubleClickMove == DCLICK_Active) && (Pawn.Physics == PHYS_Falling) ) DoubleClickDir = DCLICK_Active; else if ( (DoubleClickMove != DCLICK_None) && (DoubleClickMove < DCLICK_Active) ) { if ( UTPawn(Pawn).Dodge(DoubleClickMove) ) DoubleClickDir = DCLICK_Active; } Pawn.Acceleration = newAccel; } if (Role == ROLE_Authority) { // Update ViewPitch for remote clients Pawn.SetRemoteViewPitch( Rotation.Pitch ); } } CheckJumpOrDuck(); } } } function UpdateRotation( float DeltaTime ) { local UDNPawn P; local Rotator DeltaRot, newRotation, ViewRotation; P = UDNPawn(Pawn); ViewRotation = Rotation; if (p != none && P.CameraType != CAM_SideScroller) { Pawn.SetDesiredRotation(ViewRotation); } // Calculate Delta to be applied on ViewRotation if( P != none && P.CameraType == CAM_SideScroller ) { DeltaRot.Yaw = Pawn.Rotation.Yaw; } else { DeltaRot.Yaw = PlayerInput.aTurn; } DeltaRot.Pitch = PlayerInput.aLookUp; ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot ); SetRotation(ViewRotation); ViewShake( deltaTime ); NewRotation = ViewRotation; NewRotation.Roll = Rotation.Roll; if (P != None && P.CameraType != CAM_SideScroller ) Pawn.FaceRotation(NewRotation, deltatime); } defaultproperties { }
カスタムのカメラの例
ベースとなるカメラ モジュール
ベースとなるカメラ モジュールのクラスは、Object クラスを拡張したもので、すべてのカメラ モジュールに共通するプロパティとビヘイビアを定義します。プロパティの中には、このクラスを所有しているカメラへの参照があります。初期化および初期化解除の関数が定義されているものの、このクラスでメインとなる機能は、UpdateCamera() 関数によって実行されます。この関数は、プレイヤーのカメラの新たな位置と回転を計算するとともに、他の必要なエフェクトまたは変更を適用することができます。 このクラスの定義には config(Camera) 指定子を使用します。これによって、特定のカメラ モジュールにおいて設定可能であるか永続的でなければならないあらゆるプロパティが Camera.ini ファイルに置かれることになります。また、このクラスは abstract として定義されるため、実際に使用することはできません。それ自体実際に使用されるクラスではなく、特定のカメラ モジュールをビルドする際に基となるテンプレートと言うべきものです。 UDNCameraModule.ucclass UDNCameraModule extends Object abstract config(Camera); //owning camera var transient UDNPlayerCamera PlayerCamera; //mode-specific initialization function Init(); /** Called when the camera becomes active */ function OnBecomeActive( UDNCameraModule OldCamera ); /** Called when the camera becomes inactive */ function OnBecomeInActive( UDNCameraModule NewCamera ); //Calculate new camera location and rotation function UpdateCamera(Pawn P, UDNPlayerCamera CameraActor, float DeltaTime, out TViewTarget OutVT); //initialize new view target simulated function BecomeViewTarget( UDNPlayerController PC ); //handle zooming in function ZoomIn(); //handle zooming in function ZoomOut(); defaultproperties { }
カスタムの Camera
新たな Camera クラスは、ベースとなる Camera クラスを拡張したもので、関数をオーバーライドし、カメラ モジュールを処理する新たな機能を追加しています。このシステムにおける Camera の主な仕事は、計算の大部分を処理するため、カメラ モジュールの仲介者として振る舞うことです。 UDNPlayerCamera.ucclass UDNPlayerCamera extends Camera config(Camera); var UDNPlayerController PlayerOwner; //player controller owning this camera var UDNCameraModule CurrentCamera; //Current camera mode in use var config string DefaultCameraClass; //class for default camera mdoe function PostBeginPlay() { local class<UDNCameraModule> NewClass; Super.PostBeginPlay(); // Setup camera mode if ( (CurrentCamera == None) && (DefaultCameraClass != "") ) { //get the default camera class to use NewClass = class<UDNCameraModule>( DynamicLoadObject( DefaultCameraClass, class'Class' ) ); //create default camera CurrentCamera = CreateCamera(NewClass); } } //Initialize the PlayerCamera for the owning PlayerController function InitializeFor(PlayerController PC) { //do parent initialization Super.InitializeFor(PC); //set PlayerOwner to player controller PlayerOwner = UDNPlayerController(PC); } /** * Internal. Creates and initializes a new camera of the specified class, returns the object ref. */ function UDNCameraModule CreateCamera(class<UDNCameraModule> CameraClass) { local UDNCameraModule NewCam; //create new camera and initialize NewCam = new(Outer) CameraClass; NewCam.PlayerCamera = self; NewCam.Init(); //call active/inactive functions on new/old cameras if(CurrentCamera != none) { CurrentCamera.OnBecomeInactive(NewCam); NewCam.OnBecomeActive(CurrentCamera); } else { NewCam.OnBecomeActive(None); } //set new camera as current CurrentCamera = NewCam; return NewCam; } /** * Query ViewTarget and outputs Point Of View. * * @param OutVT ViewTarget to use. * @param DeltaTime Delta Time since last camera update (in seconds). */ function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime) { local CameraActor CamActor; local TPOV OrigPOV; local Vector Loc, Pos, HitLocation, HitNormal; local Rotator Rot; local Actor HitActor; // Don't update outgoing viewtarget during an interpolation if( PendingViewTarget.Target != None && OutVT == ViewTarget && BlendParams.bLockOutgoing ) { return; } OrigPOV = OutVT.POV; // Default FOV on viewtarget OutVT.POV.FOV = DefaultFOV; // Viewing through a camera actor. CamActor = CameraActor(OutVT.Target); if( CamActor != None ) { CamActor.GetCameraView(DeltaTime, OutVT.POV); // Grab aspect ratio from the CameraActor. bConstrainAspectRatio = bConstrainAspectRatio || CamActor.bConstrainAspectRatio; OutVT.AspectRatio = CamActor.AspectRatio; // See if the CameraActor wants to override the PostProcess settings used. CamOverridePostProcessAlpha = CamActor.CamOverridePostProcessAlpha; CamPostProcessSettings = CamActor.CamOverridePostProcess; } else { // Give Pawn Viewtarget a chance to dictate the camera position. // If Pawn doesn't override the camera view, then we proceed with our own defaults if( Pawn(OutVT.Target) == None || !Pawn(OutVT.Target).CalcCamera(DeltaTime, OutVT.POV.Location, OutVT.POV.Rotation, OutVT.POV.FOV) ) { //Pawn didn't want control and we have a custom mode if(CurrentCamera != none) { //allow mode to handle camera update CurrentCamera.UpdateCamera(Pawn(OutVT.Target), self, DeltaTime, OutVT); } //no custom mode - use default camera styles else { switch( CameraStyle ) { case 'Fixed' : // do not update, keep previous camera position by restoring // saved POV, in case CalcCamera changes it but still returns false OutVT.POV = OrigPOV; break; case 'ThirdPerson' : // Simple third person view implementation case 'FreeCam' : case 'FreeCam_Default': Loc = OutVT.Target.Location; Rot = OutVT.Target.Rotation; //OutVT.Target.GetActorEyesViewPoint(Loc, Rot); if( CameraStyle == 'FreeCam' || CameraStyle == 'FreeCam_Default' ) { Rot = PCOwner.Rotation; } Loc += FreeCamOffset >> Rot; Pos = Loc - Vector(Rot) * FreeCamDistance; // @fixme, respect BlockingVolume.bBlockCamera=false HitActor = Trace(HitLocation, HitNormal, Pos, Loc, FALSE, vect(12,12,12)); OutVT.POV.Location = (HitActor == None) ? Pos : HitLocation; OutVT.POV.Rotation = Rot; break; case 'FirstPerson' : // Simple first person, view through viewtarget's 'eyes' default : OutVT.Target.GetActorEyesViewPoint(OutVT.POV.Location, OutVT.POV.Rotation); break; } } } } ApplyCameraModifiers(DeltaTime, OutVT.POV); // set camera's location and rotation, to handle cases where we are not locked to view target SetRotation(OutVT.POV.Rotation); SetLocation(OutVT.POV.Location); } //pass view target initialization through to camera mode simulated function BecomeViewTarget( PlayerController PC ) { CurrentCamera.BecomeViewTarget(UDNPlayerController(PC)); } //pass zoom in through to camera mode function ZoomIn() { CurrentCamera.ZoomIn(); } //pass zoom out through to camera mode function ZoomOut() { CurrentCamera.ZoomOut(); } defaultproperties { }
ベースとなるコントロール モジュール
ベースとなるコントロール モジュール クラスは、Object クラスを拡張したのもので、全コントロール モジュールに共通するプロパティおよびビヘイビアをすべて定義します。このクラスは、このクラスを所有しているコントローラーへの参照を含むとともに、現在のマウスカーソルの位置を保持します。ベースとなるカメラ モジュールと同様、タイプ固有の構成または必要となるクリーンアップを可能にする初期化および初期化解除の関数が定義されています。このクラスの残りは、プレイヤーの動きおよび照準を処理する関数から構成されています。 このクラスの定義には config(Control) 指定子を使用します。これによって、特定のカメラ モジュールにおいて設定可能であるか永続的でなければならないあらゆるプロパティが Camera.ini ファイルに置かれることになります。また、このクラスは abstract として定義されるため、実際に使用することはできません。このクラスは、それ自体実際に使用されるものではなく、特定のカメラ モジュールをビルドする際に基となるテンプレートにすぎません。 UDNControlModule.ucclass UDNControlModule extends Object abstract config(Control); //reference to the owning controller var UDNPlayerController Controller; //mode-specific initialization function Init(); /** Called when the camera becomes active */ function OnBecomeActive( UDNControlModule OldModule ); /** Called when the camera becomes inactive */ function OnBecomeInActive( UDNControlModule NewModule ); //Calculate Pawn aim rotation simulated singular function Rotator GetBaseAimRotation(); //Handle custom player movement function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot); //Calculate controller rotation function UpdateRotation(float DeltaTime); defaultproperties { }
エンジンクラスのオーバーライド
いくつかのエンジンクラスを拡張することによって、新たなカメラシステムおよびコントロールシステム (主に PlayerController 、Pawn 、HUD クラス) のインターフェースとなるようにする必要があります。新たなゲームタイプも作成し、これらの新たなクラスを利用できるようにします。PlayerController
新たな PlayerController クラスは、使用されているカメラ モジュールのタイプを変更する実行関数、および、ズームインまたはズームアウトするための実行関数を追加します。(ズームのための関数の機能のしかたは、それらの関数を現在のカメラ モジュールがどのように実装するかということに依存します)。 PlayerWalking ステートの ProcessMove() 関数、および、 UpdateRotation() 関数がオーバーライドされることによって、関数呼び出しがコントロール モジュールに追加されます。最後に GetPlayerViewPoint() 関数がオーバーライドおよび変更されることによって、カメラが破壊されないようにし、新たなカスタムのカメラがある場合は PlayerController にそのカメラを使用させるようにします。 UDNPlayerController.ucclass UDNPlayerController extends UTPlayerController; var UDNControlModule ControlModule; //player control module to use var config string DefaultControlModuleClass; //default class for player control module //exec function for switching to a different camera by class exec function ChangeControls( string ClassName ) { local class<UDNControlModule> ControlClass; local UDNControlModule NewControlModule; ControlClass = class<UDNControlModule>( DynamicLoadObject( DefaultControlModuleClass, class'Class' ) ); if(ControlClass != none) { // Associate module with PlayerController NewControlModule = new(Outer) ControlClass; NewControlModule.Controller = self; NewControlModule.Init(); //call active/inactive functions on new/old modules if(ControlModule != none) { ControlModule.OnBecomeInactive(NewControlModule); NewControlModule.OnBecomeActive(ControlModule); } else { NewControlModule.OnBecomeActive(None); } ControlModule = NewControlModule; } else { `log("Couldn't get control module class!"); // not having a Control Class is fine. PlayerController will use default controls. } } //exec function for switching to a different camera by class exec function ChangeCamera( string ClassName ) { local class<UDNCameraModule> NewClass; NewClass = class<UDNCameraModule>( DynamicLoadObject( ClassName, class'Class' ) ); if(NewClass != none && UDNPlayerCamera(PlayerCamera) != none) { UDNPlayerCamera(PlayerCamera).CreateCamera(NewClass); } } //zoom in exec exec function ZoomIn() { if(UDNPlayerCamera(PlayerCamera) != none) { UDNPlayerCamera(PlayerCamera).ZoomIn(); } } //zoom out exec exec function ZoomOut() { if(UDNPlayerCamera(PlayerCamera) != none) { UDNPlayerCamera(PlayerCamera).ZoomOut(); } } simulated function PostBeginPlay() { local class<UDNControlModule> ControlClass; local UDNControlModule NewControlModule; Super.PostBeginPlay(); ControlClass = class<UDNControlModule>( DynamicLoadObject( DefaultControlModuleClass, class'Class' ) ); if(ControlClass != none) { // Associate module with PlayerController NewControlModule = new(Outer) ControlClass; NewControlModule.Controller = self; NewControlModule.Init(); //call active/inactive functions on new/old modules if(ControlModule != none) { ControlModule.OnBecomeInactive(NewControlModule); NewControlModule.OnBecomeActive(ControlModule); } else { NewControlModule.OnBecomeActive(None); } ControlModule = NewControlModule; } else { `log("Couldn't get control module class!"); // not having a Control Class is fine. PlayerController will use default controls. } } state PlayerWalking { function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { //Controller has a UDNPlayerCamera if(ControlModule != none) { //allow custom camera to override player movement ControlModule.ProcessMove(DeltaTime, NewAccel, DoubleClickMove, DeltaRot); } else { Super.ProcessMove(DeltaTime, NewAccel, DoubleClickMove, DeltaRot); } } } function UpdateRotation( float DeltaTime ) { //Controller has a UDNPlayerCamera if(ControlModule != none) { //allow custom camera to update our rotation ControlModule.UpdateRotation(DeltaTime); } else { Super.UpdateRotation(DeltaTime); } } /* GetPlayerViewPoint: Returns Player's Point of View For the AI this means the Pawn's Eyes ViewPoint For a Human player, this means the Camera's ViewPoint */ simulated event GetPlayerViewPoint( out vector POVLocation, out Rotator POVRotation ) { local float DeltaTime; local UTPawn P; P = IsLocalPlayerController() ? UTPawn(CalcViewActor) : None; if (LastCameraTimeStamp == WorldInfo.TimeSeconds && CalcViewActor == ViewTarget && CalcViewActor != None && CalcViewActor.Location == CalcViewActorLocation && CalcViewActor.Rotation == CalcViewActorRotation ) { if ( (P == None) || ((P.EyeHeight == CalcEyeHeight) && (P.WalkBob == CalcWalkBob)) ) { // use cached result POVLocation = CalcViewLocation; POVRotation = CalcViewRotation; return; } } DeltaTime = WorldInfo.TimeSeconds - LastCameraTimeStamp; LastCameraTimeStamp = WorldInfo.TimeSeconds; // support for using CameraActor views if ( CameraActor(ViewTarget) != None ) { if ( PlayerCamera == None ) { super.ResetCameraMode(); SpawnCamera(); } super.GetPlayerViewPoint( POVLocation, POVRotation ); } else { //do not destroy our camera!!! /* if ( PlayerCamera != None ) { PlayerCamera.Destroy(); PlayerCamera = None; } */ //no camera, we have view target - let view target be in control if ( PlayerCamera == None && ViewTarget != None ) { POVRotation = Rotation; if ( (PlayerReplicationInfo != None) && PlayerReplicationInfo.bOnlySpectator && (UTVehicle(ViewTarget) != None) ) { UTVehicle(ViewTarget).bSpectatedView = true; ViewTarget.CalcCamera( DeltaTime, POVLocation, POVRotation, FOVAngle ); UTVehicle(ViewTarget).bSpectatedView = false; } else { ViewTarget.CalcCamera( DeltaTime, POVLocation, POVRotation, FOVAngle ); } if ( bFreeCamera ) { POVRotation = Rotation; } } //no camera, no view target - we are in control else if(PlayerCamera == None) { CalcCamera( DeltaTime, POVLocation, POVRotation, FOVAngle ); return; } //we have a camera - let camera be in control else { POVLocation = PlayerCamera.ViewTarget.POV.Location; POVRotation = PlayerCamera.ViewTarget.POV.Rotation; FOVAngle = PlayerCamera.ViewTarget.POV.FOV; } } // apply view shake POVRotation = Normalize(POVRotation + ShakeRot); POVLocation += ShakeOffset >> Rotation; if( CameraEffect != none ) { CameraEffect.UpdateLocation(POVLocation, POVRotation, GetFOVAngle()); } // cache result CalcViewActor = ViewTarget; CalcViewActorLocation = ViewTarget.Location; CalcViewActorRotation = ViewTarget.Rotation; CalcViewLocation = POVLocation; CalcViewRotation = POVRotation; if ( P != None ) { CalcEyeHeight = P.EyeHeight; CalcWalkBob = P.WalkBob; } } defaultproperties { CameraClass=class'UDNExamples.UDNPlayerCamera' MatineeCameraClass=class'UDNExamples.UDNPlayerCamera' }
Pawn クラス
新たな Pawn クラスは、 CalcCamera() 関数をオーバーライドすることによって単に FALSE を返すようにし、新たなカメラシステムが常にカメラの位置と回転を制御できるようにします。 BecomeViewTarget() および GetBaseAimRotation() 関数は、オーバーライドされることによって、それらの機能の処理をそれぞれ、カメラシステムとコントロールシステムに渡します。 UDNPawn.ucclass UDNPawn extends UTPawn; /* BecomeViewTarget Called by Camera when this actor becomes its ViewTarget */ simulated event BecomeViewTarget( PlayerController PC ) { local UDNPlayerController UDNPC; UDNPC = UDNPlayerController(PC); //Pawn is controlled by a UDNPlayerController and has a UDNPlayerCamera if(UDNPC != none && UDNPlayerCamera(UDNPC.PlayerCamera) != none) { //allow custom camera to control mesh visibility, etc. UDNPlayerCamera(UDNPC.PlayerCamera).BecomeViewTarget(UDNPC); } else { Super.BecomeViewTarget(PC); } } /** * Calculate camera view point, when viewing this pawn. * * @param fDeltaTime delta time seconds since last update * @param out_CamLoc Camera Location * @param out_CamRot Camera Rotation * @param out_FOV Field of View * * @return true if Pawn should provide the camera point of view. */ simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) { //return false to allow custom camera to control its location and rotation return false; } /** * returns base Aim Rotation without any adjustment (no aim error, no autolock, no adhesion.. just clean initial aim rotation!) * * @return base Aim rotation. */ simulated singular event Rotator GetBaseAimRotation() { local vector POVLoc; local rotator POVRot; local UDNPlayerController PC; PC = UDNPlayerController(Controller); //Pawn is controlled by a UDNPlayerController and has a UDNPlayerCamera if(PC != none && PC.ControlModule != none) { //allow custom camera to control aim rotation return PC.ControlModule.GetBaseAimRotation(); } else { if( Controller != None && !InFreeCam() ) { Controller.GetPlayerViewPoint(POVLoc, POVRot); return POVRot; } else { POVRot = Rotation; if( POVRot.Pitch == 0 ) { POVRot.Pitch = RemoteViewPitch << 8; } return POVRot; } } } defaultproperties { }
GameInfo クラス
新たなゲームタイプ クラスは、UTDeathMatch クラスを拡張したベースとなるクラスであり、使用する新たな HUD 、Pawn 、PlayerController クラスを設定します。また、このクラスは、 bUseClassicHUD を TRUE にセットすることによって、UTGFxHUDWrapper (この bool 型がセットされていない場合に使用されるようにハードコード化されています) の代わりに、ここで指定される HUD クラスが使用されるようにします。 UDNGame.ucclass UDNGame extends UTDeathMatch; defaultproperties { DefaultPawnClass=class'UDNExamples.UDNPawn' PlayerControllerClass=class'UDNExamples.UDNPlayerController' MapPrefixes[0]="UDN" }
カメラ モジュールの例
新たなカメラのフレームワーク例として、トップダウン (上方からの) カメラを構成します。新たなカメラ モジュールを作成するということは、およそ、ベースとなるカメラ モジュール クラスで定義されている関数を実装することに他なりません。上記 CalcCamera() 例をご覧になっている場合は、その多くが見慣れたものであるはずです。 UDNCameraModule_TopDown.ucclass UDNCameraModule_TopDown extends UDNCameraModule; var float CamAltitude; //actual camera height offset from player var float DesiredCamAltitude; //new height offset to move camera to var float MaxCamAltitude; //maximum offset from player camera can be var float MinCamAltitude; //minimum offset from player camera can be var float CamZoomIncrement; //how many units to zoom with each click of mousewheel //Calculate new camera location and rotation function UpdateCamera(Pawn P, UDNPlayerCamera CameraActor, float DeltaTime, out TViewTarget OutVT) { //interpolate to new camera offest if not there if(CamAltitude != DesiredCamAltitude) { CamAltitude += (DesiredCamAltitude - CamAltitude) * DeltaTime * 3; } //align camera to player with height (Z) offset OutVT.POV.Location = OutVT.Target.Location; OutVT.POV.Location.Z += CamAltitude; //set camera rotation - face down OutVT.POV.Rotation.Pitch = -16384; OutVT.POV.Rotation.Yaw = 0; OutVT.POV.Rotation.Roll = 0; } //initialize new view target simulated function BecomeViewTarget( UDNPlayerController PC ) { if (LocalPlayer(PC.Player) != None) { //Set player mesh visible PC.SetBehindView(true); UDNPawn(PC.Pawn).SetMeshVisibility(PC.bBehindView); PC.bNoCrosshair = true; } } function ZoomIn() { //decrease camera height DesiredCamAltitude -= CamZoomIncrement; //lock camera height to limits DesiredCamAltitude = FMin(MaxCamAltitude, FMax(MinCamAltitude, DesiredCamAltitude)); } function ZoomOut() { //increase camera height DesiredCamAltitude += CamZoomIncrement; //lock camera height to limits DesiredCamAltitude = FMin(MaxCamAltitude, FMax(MinCamAltitude, DesiredCamAltitude)); } defaultproperties { CamAltitude=384.0 DesiredCamAltitude=384.0 MaxCamAltitude=1024.0 MinCamAltitude=160.0 CamZoomIncrement=96.0 }
コントロール モジュールの例
UDNControlModule_TopDown.ucclass UDNControlModule_TopDown extends UDNControlModule; //Calculate Pawn aim rotation simulated singular function Rotator GetBaseAimRotation() { local rotator POVRot; //aim where Pawn is facing - lock pitch POVRot = Controller.Pawn.Rotation; POVRot.Pitch = 0; return POVRot; } //Handle custom player movement function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { if( Controller.Pawn == None ) { return; } if (Controller.Role == ROLE_Authority) { // Update ViewPitch for remote clients Controller.Pawn.SetRemoteViewPitch( Controller.Rotation.Pitch ); } Controller.Pawn.Acceleration = NewAccel; Controller.CheckJumpOrDuck(); } //Calculate controller rotation function UpdateRotation(float DeltaTime) { local Rotator DeltaRot, NewRotation, ViewRotation; ViewRotation = Controller.Rotation; //rotate pawn to face cursor if (Controller.Pawn!=none) Controller.Pawn.SetDesiredRotation(ViewRotation); DeltaRot.Yaw = Controller.PlayerInput.aTurn; DeltaRot.Pitch = 0; Controller.ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot ); Controller.SetRotation(ViewRotation); NewRotation = ViewRotation; NewRotation.Roll = Controller.Rotation.Roll; if ( Controller.Pawn != None ) Controller.Pawn.FaceRotation(NewRotation, DeltaTime); } defaultproperties { }
Config ファイル
以下のファイルはすべて、UDKgame/Config ディレクトリに置かれなければなりません。そのうちいくつかのファイルは新たに追加されるものなので、作成する必要があります。他のファイルは、新たなコンフィギュレーション設定項目を含むように修正するだけです。 DefaultCamera.ini ファイルは、新たなカメラクラスにあるconfig 変数の値で満たす必要があります。この例では、デフォルトのカメラ モジュール クラスをセットするだけです。 DefaultCamera.ini[UDNExamples.UDNPlayerCamera] DefaultCameraClass=UDNExamples.UDNCameraModule_TopDown
... [Engine.GameInfo] DefaultGame=UDNExamples.UDNGame DefaultServerGame=UDNExamples.UDNGame ... [UDNExamples.UDNPlayerController] DefaultControlModuleClass=UDNExamples.UDNControlModule_TopDown