Friday, September 28, 2012

UDK-Toturial-CH5.UnrealScript-GameRule

1.End the game rule.
2.Simple Enemy.(Static)
3. Expand Player Pawn.
4.Expand Enemy,Bump Event

A. SettingUp GameInfo&GameType:
現在來擴展FunnyGameInfo.uc,增加PostBeginPlay():
simulated function PostBeginPlay()
{
local WeaponUpgrade WU;
super.PostBeginPlay();
GoalScore = 0;
foreach DynamicActors(class'WeaponUpgrade',WU)
GoalScore++;
}
GoalScore是被宣告在GameInfo,當分數到達時就會結束遊戲,在Deathmatch可能就是殺敵次數,在這裡宣告撿取 WeaponUpgrade總數為結束分數,當FunnyGameInfo extends UTDeathmatch,在DefaultProperties做一些設定,
bScoreDeaths=false;
這是把一般Deathmatch的Double kill的語音關掉,在撿拾WeaponUpgrade actor時並不需要這種聲音,而bScoreDeath被宣告在UTGame,目前的FunnyGameInfo.uc:
class FunnyGameInfo extends UTDeathmatch;
simulated function PostBeginPlay()
{
local WeaponUpgrade WU;
super.PostBeginPlay();
GoalScore = 0;
foreach DynamicActors(class'WeaponUpgrade',WU)
GoalScore++;
}
DefaultProperties
{
bScoreDeaths=false;
PlayerControllerClass = class'Tutorial.CustomTopDownController'
DefaultPawnClass=class'Tutorial.CustomTopDownPawn'
}

在改變WeaponUpgrade.uc裡的Touch event:
event Touch(Actor Other,PrimitiveComponent OtherComp,vector HitLocation,vector HitNormal)
{
if(Pawn(Other) != none && CustomWeapon(Pawn(Other).Weapon) != none)
{
if(Pawn(Other).Controller != none && Pawn(Other).Controller.PlayerReplicationInfo != none)
WorldInfo.Game.ScoreObjective(Pawn(Other).Controller.PlayerReplicationInfo,1);
CustomWeapon(Pawn(Other).Weapon).UpgradeWeapon();
Destroy();
}
}
PlayerReplicationInfo是每個Controller所持有的殺敵數(score),玩家再自行把分數告訴GameInfo: WorldInfo.Game.ScoreObjective(Pawn(Other).Controller.PlayerReplicationInfo,1);
“1”代表當碰到WeaponUpgrade Actor時,傳給GameInfo分數加1,執行後將所有東西撿起後結果:

B. Enemy Setting Up Basic:
產生一個SimpleEnemy.uc:
event TakeDamage(int DamageAmount,Controller EventInstigator,vector HitLocation,vector Momentum,class<DamageType> DamageType,optional TraceHitInfo HitInfo,optional Actor DamageCauser)
{
Destroy();
}
DefaultProperties
{
bBlockActors=true
bCollideActors=true

Begin Object Class=DynamicLightEnvironmentComponent Name=myLight
bEnabled=true
End Object
Components.Add(myLight)

Begin Object Class=StaticMeshComponent Name=myMesh
StaticMesh=StaticMesh'UN_SimpleMeshes.TexPropCube_Dup'
Materials(0)=Material'EditorMaterials.WidgetMaterial_X'
LightEnvironment=myLight
Scale3D=(X=0.25,Y=0.25,Z=0.25)
End Object
Components.Add(myMesh)

Begin Object Class=CylinderComponent Name=myCylinder
CollisionRadius=32.0
CollisionHeight=64.0
BlockNonZeroExtent=true
BlockZeroExtent=true
BlockActors=true
CollideActors=true
End Object
CollisionCompoent=CollisionCylinder
Components.Add(myCylinder)
}

event TakeDamage()當敵人被武器攻擊到會發生,執行下面的Destroy,Compiler後,將SimpleEnemy放置數個在場景上:

之前FunnyGameInfo 改成以當WeaponUpgrade Actor全部撿到後分數增加,即完成遊戲,現在把規則改成將SimpleEnemy Actor摧毀後才達成遊戲結束,現在更改FunnyGameInfo.uc PostBeginPlay():
simulated function PostBeginPlay()
{
local SimpleEnemy SE;
super.PostBeginPlay();
GoalScore=0;
foreach DynamicActors(class'SimpleEnemy',SE)
GoalScore++;
}
現在遊戲目標變成是SimpleEnemy Actor數目為分數目標,現在更改WeaponUpgrade 裡的Touch(),因為之前有在這進行分數變動,改成:
event Touch(Actor Other,PrimitiveComponent OtherComp,vector HitLocation,vector HitNormal)
{
if(Pawn(Other) != none && CustomWeapon(Pawn(Other).Weapon) != none)
{
CustomWeapon(Pawn(Other).Weapon).UpgradeWeapon();
Destroy();
}
}
在TestEnemy.uc,增加分數變動的程式碼,這裡利用了TakeDamage event去做分數變動:
event TakeDamage(int DamageAmount,Controller EventInstigator,vector HitLocation,vector Momentum,class<DamageType> DamageType,optional TraceHitInfo HitInfo,optional Actor DamageCauser)
{
if(EventInstigator != none && EventInstigator.PlayerReplicationInfo != none)
WorldInfo.Game.ScoreObjective(EventInstigator.PlayerReplicationInfo,1);
Destroy();
}
最後再做點修改,把預設武器設定成null,因此在FunnyGameInfo.uc裡的DefaultProperties增加:
DefaultInventory(0)=None
Compiler後,有個問題但撿起武器後摧毀SimpleEnemy actor遊戲也會出現結束畫面

浮空的手臂

撿起武器後正常。
C. Expand CustomPawn:
之前處理Camera時已經實做過Pawn,Pawn處理Camera問題和人物Mesh物提,而Controller處理了當用戶端輸入時,值得轉換問題,現在把剛剛一個懸空的手臂的小問題解決掉,由FunnyGameInfo得知DefaultPawn使用的是CutomTopDownPawn,進行修改 PostBeginPlay():
simulated function PostBeginPlay()
{
super.PostBeginPlay();
if(ArmsMesh[0] != none)
ArmsMesh[0].SetHidden(true);
if(ArmsMesh[1] != none)
ArmsMesh[1].SetHidden(true);
}
ArmsMesh定義在UTPawn.uc裡面的var UDKSkeletalMeshComponent[2];,其結果

處理掉手臂問題,這問題源自於UTPawn.uc:

***************勿修改*****************

Begin Object Class=UDKSkeletalMeshComponent Name=FirstPersonArms
PhysicsAsset=None
FOV=55
Animations=MeshSequenceA
DepthPriorityGroup=SDPG_Foreground
bUpdateSkelWhenNotRendered=false
bIgnoreControllersWhenNotRendered=true
bOnlyOwnerSee=true
bOverrideAttachmentOwnerVisibility=true
bAcceptsDynamicDecals=FALSE
AbsoluteTranslation=false
AbsoluteRotation=true
AbsoluteScale=true
bSyncActorLocationToRootRigidBody=false
CastShadow=false
TickGroup=TG_DuringASyncWork
End Object
ArmsMesh[0]=FirstPersonArms
不管繼承了UTDeathmatch、UTPlayerController、UTPawn若不做DefaultProperties修改和Function 的Override 基本上都會照UDK預設功能和SkeletalMeshComponent、、等一樣,用UnCodeX 去觀察原生Code是很重要的一件事。
D.Expand SimeEnemy:
敵人在這,玩家去碰觸時並不會對玩家造成任何傷害,因此修改SimpleEnemy.uc,增加對玩家傷害的變數:
var float BumpDamage;
在DefaultProperties給予值:
BumpDamage=5.0
再CustomTopDownPawn.uc增加 Bump Event:
event Bump(Actor Other,PrimitiveComponent OtherComp,none,vector HitNormal)
{
`log("Bump by Enemys");
if(SimpleEnemy(Other) != none)
TakeDamage(SimpleEnemy(Other).BumpDamage,none,Location,vect(0,0,0),class'UTDmgType_LinkPlasma');
}
Compiler後,人物去撞擊後,人物會迅速扣血而死:


不過為了避免被連續撞擊,在CustomTopDownPawn.uc新增變數:
var bool bInvulnerable;
var float InvulnerableTime;
在DefaultProperties新增初始值:
InvulnerableTime=0.6
改變 Bump Event:
event Bump(Actor Other,PrimitiveComponent OtherComp,vector HitNormal)
{
`log("Bump by Enemys");
if(SimpleEnemy(Other) != none && !bInvulnerable)
{
bInvulnerable=true;
SetTimer(InvulnerableTime,false,'EndInvulnerable');
TakeDamage(SimpleEnemy(Other).BumpDamage,none,Location,vect(0,0,0),class'UTDmgType_LinkPlasma');
}
}
增加Function EndInvulnerable():
function EndInvulnerable()
{
bInvulnerable=false
}
Compiler後碰觸後不會馬上死亡。
Done

File:CH5.ZIP

No comments:

Post a Comment