----------------------------------StarterPlatformGame---李明陽2015-2-19-------------------------------------
GameType
在GameInfo中定義了角色,武器庫,控制類,遊戲啟動時将會生成。
//What player controller class to create for the player
PlayerControllerClass=class'SPG_PlayerController'
//What default pawn archetype to spawn for the player
DefaultPawnArchetype=SPG_PlayerPawn'StarterPlatformGameContent.Archetypes.PlayerPawn'
//What default weapon archetype to spawn for the player
DefaultWeaponArchetype=SPG_Weapon'StarterPlatformGameContent.Archetypes.LinkGunWeapon'
UDK預設角色和武器
角色,武器庫管理,武器庫。
一個角色可以擁有不同的武器,就是武器庫。不同類型的武器産生的作用不同,武器庫管理就“管理”着它們的不同。
遊戲開始時生成角色,當把武器附加給角色後添加武器管理。代碼的執行順序:
在Info中生成Pawn,完成Pawn中SkeletalMeshComponent的初使化,如果Pawn有定義動畫資源,動畫也在這時初使化。在Info中有定義武器庫,當把武器庫添加給Pawn時,武器類執行附加武器到Socket。
程式初使化流程:在Info類中生成Pawn,同時Pawn類元件初使化(動畫);當Pawn初使化完成後Info類把武器庫加給Pawn,在Weapon類中執行武器附加到Pawn的Socket。
SpawnDefaultPawnFor();PostInitAnimTree();AddDefaultInventory();ClientGivenTo()。
控制類和相機
在控制類中定義相機類,SPG_Camera類重寫UpdateViewTarget,設定視點和取景朝向(旋轉)。視點POV.Location始終對準Target(這裡的Target是Controller占有的那個Pawn),朝向是Pawn的位置減視點位置的向量。這樣相機就會保持和Pawn固定的偏移量“盯着”Pawn。
角色和控制類
在控制類有Input類和控制類有占有Pawn的情況下,控制類中的PlayerTick()就會不斷調用。SPG_GameInfo的Input類是預設的PlayerInput,在GameInfo中有函數SpawnDefaultPawnFor(),在Info中有定義Controller和Pawn,SPG_PlayerController類中沒有重寫PlayerTick()函數,在預設的Controller中PlayerTick()就會調用,函數體中處理Pawn運動的PlayerMove(DeltaTime)函數也就被調用了。在預設的Controller類中PlayerMove()具體代碼寫在狀态statePlayerWalking中,SPG_PlayerController.uc重寫了statePlayerWalking,處理Pawn運動的實作就是SPG_PlayerController中的statePlayerWalking,在Controller中state PlayerWalking同時也是Pawn預設的狀态。預設Controller的代碼如下:
event PlayerTick(floatDeltaTime )
{
if( !bShortConnectTimeOut )
{
bShortConnectTimeOut =true;
ServerShortTimeout();
}
if(Pawn != AcknowledgedPawn )
{
if( Role < ROLE_Authority )
{
// make sure old pawn controller is right
if ( (AcknowledgedPawn !=None)&& (AcknowledgedPawn.Controller == self))
AcknowledgedPawn.Controller=None;
}
AcknowledgePossession(Pawn);
}
PlayerInput.PlayerInput(DeltaTime);
if( bUpdatePosition )
{
ClientUpdatePosition();
}
PlayerMove(DeltaTime);
AdjustFOV(DeltaTime);
}
function PlayerMove(floatDeltaTime);
SPG_PlayerController中的statePlayerWalking:
預設情況下UDK的坐标系如下圖:玩家的出生點位置,在預設的UTGame中第一人稱相機取景點在Pawn的“眼睛”位置。在這個平台資源包遊戲中,Pawn生成後的朝向是朝向世界坐标的Y軸(生成是是按PlayerStart的Rotation)。按預設情況來看,相機要放到如下圖位置,按照視點偏移後在Yaw方向上要旋轉90度。
關于Pawn的加速度計算:預設的UTGame中,從Input得到的aStrafe值實作了角色的左右移動,這裡用相機的Y軸表示角色的加速度(移動速度方向和大小的向量),aStrafe的值用來驅動角色朝向(DesiredRotation),移動,移動速度快慢和加速度(NewAccel)大小。
//Grab the camera view point as we want to have movement aligned to the camera
PlayerCamera.GetCameraViewPoint(CameraLocation,CameraRotation);
//`log([email protected]@ CameraRotation.Yaw);
// Getthe individual axes of the rotation
GetAxes(CameraRotation, X, Y,Z);
//`log([email protected]@ Z);
//`log("aStrafe"@PlayerInput.aStrafe);
//Update acceleration
NewAccel = PlayerInput.aStrafe * Y;
//NewAccel.Z= 0;
NewAccel = Pawn.AccelRate * Normal(NewAccel);
// Setthe desired rotation
DesiredRotation= Rotator(NewAccel);
//Update rotation
OldRotation = Rotation;
UpdateRotation(DeltaTime);
SPG_PlayerController重寫函數UpdateRotation(DeltaTime), PlayerInput.aLookUp在預設的UTGame中表示準星在螢幕上下移動的值,綜合DesiredRotation 得到Pawn面部的最新朝向(Yaw)和瞄準朝向(Pitch)的DeltaRot。
SPG_PlayerPawn中重寫Pawn的FaceRotation(),通過Controller傳入的DeltaRot,完成Pawn的SetRotation()。
附加内容:
UDK的武器
開火就是打出一個子彈,子彈類型不唯一它們有各自的屬性,比如:不同的開火狀态不同的開火類型不同的射彈類型不同的開火頻率不同的子彈擴散不同的傷害力不同的推力不同的傷害類型等,,,,,,這些屬性一般對應的就是所謂的“武器管理”
UDK默的的開火模式:FireModeNum(0代表滑鼠左鍵,1代表滑鼠右鍵)
UDK開火類型:數組一一對應(比如說左鍵是0,所有下标為0的數組都代表左鍵開火)
enumEWeaponFireType
{
EWFT_InstantHit, //立即型(不需要生成射彈,類似于雷射,一點就中。UTGame中的鍊槍)
EWFT_Projectile, //射彈型(生成射彈,射彈碰到目标後産生傷害。UTGame中的火箭彈和LinkenPlasma)
EWFT_Custom, //自定義類型
EWFT_None //沒有類型
};
var byteCurrentFireMode; //目前的開火模式
var Array<Name> FiringStatesArray; //開火狀态
var Array<EWeaponFireType> WeaponFireTypes; //開火類型
var Array< class<Projectile> > WeaponProjectiles; //射彈類型
var() Array<float> FireInterval; //開火頻率(每秒發射多少子彈)
var() Array<float> Spread; //子彈擴散(散彈)
var() Array<float> InstantHitDamage; //射彈即時傷害力
var() Array<float> InstantHitMomentum;//射彈即時推力(動能,慣性和作用物間的品質有關)
var Array< class<DamageType> > InstantHitDamageTypes; //傷害類型(可能是持續傷害和瞬間傷害之類)
打出一個子彈,需要有槍口火焰,子彈生成的位置,子彈生成後朝哪個方向飛出,,,,,類似于這種行為的可以看成是武器,也就是武器庫。執行這些邏輯的代碼一般在Weapon類中完成。
武器開火
SPG_Weapon類中的ProjectileFire()函數
射彈生成的位置是擷取Socket的Location,射彈生成的方向是Socket的方向或Pawn的朝向。Pawn的朝向是FaceRotaion()函數計算。當把武器附加到Pawn的Socket上的時候适當地調節武器的朝向和瞄準方向,函數是Weapon類中的GetAdjustedAim(),和一個動态瞄準GetAdjustedAimFor()。
(第一人稱射擊遊戲,滑鼠不停瞄準移動速度較快,動态朝向可以提高瞄準目标的精确度)
simulatedfunction Rotator GetAdjustedAim(vectorStartFireLoc )
{
localrotator R;
//Start the chain, see Pawn.GetAdjustedAimFor()
if(Instigator !=None )
{
R =Instigator.GetAdjustedAimFor(Self,StartFireLoc );
}
returnAddSpread(R);
}
子彈從生成位置生成後,就按獲得的朝向方向進入速度的初使化,這個過程就交給C++了,在US腳本中傳入射彈朝向,初使化射彈就是開火的最後一個函數了:
// Initializethe projectile
SpawnedProjectile.Init(Vector(SpawnRotation));
射彈的生成由開火模式調用相應的射彈類型,
functionclass<Projectile> GetProjectileClass()
{
return(CurrentFireMode < Projectiles.length) ? Projectiles[CurrentFireMode] :None;
}
動态水面和材質
打開RealTime和FireFrame,水面是一個流體表面類和一個“水表面模拟器”,加上模拟水表面鏡面反射的靜态網格(采集反射貼圖供水面材質使用)。
材質部分:無法過多地解釋,有相當水準的人可以自行檢視官方的資源包。
動态水面渲染為了減少程式的計算量,同時對渲染優化考慮,材質不使用光照,反射效果采集在一張貼圖上。
材質節點比較多,但結構比較明顯。下面控制UV橫向豎向移動旋轉處理出動态法線貼圖作為水面的流水效果,這些計算方式都是二進制運算的組合(有圖形程式設計Shader概念或對三維材質渲染有一定功力的人相對容易了解)。有了動态的法線後根據一些Mask取出相應的圖像通道加以處理用作自發光和透明。