1.CustomWeapon
2.Weapon Projectile
3.Upgradeable Weapon
4.Class Modifier
5.Show/Hide Categories
A. Simple Weapon:
處理武器的升級,在一般遊戲裡,武器可能因為得到東西而提高武器威力或攻擊速度,產生一個CustomWeapon.uc:
class CustomWeapon extends UTWeapon; var int CurrentWeaponLevel; function UpgradeWeapon() { CurrentWeaponLevel++; } DefaultProperties { } |
用來記錄武器等級,使用UDK有的RocketLauncher來當武器,產生一個CustomRocketWeapon.uc:
class CustomRifleWeapon extends CustomWeapon; DefaultProperties { AttachmentClass=class'UTGameContent.UTAttachment_ShockRifle' WeaponFireTypes(0)=EWFT_Projectile WeaponFireTypes(1)=EWFT_Projectile WeaponProjectiles(0)=class'UTProj_ShockBall' WeaponProjectiles(1)=class'UTProj_Rocket' AmmoCount=40 MaxAmmoCount=40 } |
WeaponProjectiles(0)、WeaponProjectiles(1)武器種類設定完全不一樣,在撿到武器後可以發現滑鼠左右鍵發射的東西是完全不一樣的,AttachmentClass是代表撿到武器後主角手上的武器是顯示的類別和外觀。
在地圖上放置一個UTWeaponPickupFactory
Actor|Classes|Pickups|Weapon|UTWeaponPickupFactory 將 Weapon Pickup Class選擇CustomRifleWeapon
Play in editor,會發現UTWeaponPickupFactory上面並沒有武器,但當人物走到的時候會撿到武器:
這是因為並未設定顯在上面的Mesh因此在DefaultProperties 加上
Begin Object Name=PickupMesh
SkeletalMesh=SkeletalMesh’WP_ShockRifle.Mesh.SK_WP_ShockRifle _3P’
End Object
Components.Add(PickupMesh)
Name可以自行定義,SkeletalMesh’ WP_ShockRifle.Mesh.SK_WP_ShockRifle _3P’則表示是SkeletalMesh的模型,它在的Package為WP_ShockRifle.Mesh.SK_WP_ShockRifle_3P,在ContentBrowser搜尋SK_WP_ShockRifle_3P 即可看到模型
其增加SkeletalMesh後結果:
若一個Actor不去增加Component其功能會少很多且無法顯示(SpriteCompoent、StaticComponent、SkeletalMeshComponent)。
UpgradeableWeapon:
先產生升級武器的指示物,在這裡先用方塊來代表,也可以匯入自行模型,產生一個AlexGameActor.uc:
class AlexGameActor extends Actor; DefaultProperties { } |
產生一個WeaponUpgrade.uc:
class WeaponUpgrade extends AlexGameActor placeable; DefaultProperties { } |
因為WeaponUpgrade有 extend AlexGameActor 有關鍵字placeable,因此在Actor Classes 可以看到
現在玩家當碰觸到WeaponUpgrade這Actor後必須有做出反應因此在WeaponUpgrade.uc增加function:
event Touch(Actor Other,PrimitiveComponent OtherComp,vector HitLocation,vector HitNormal)
{
if(Pawn(Other) != none && CustomWeapon(Pawn(Other).Weapon) != none)
{
CustomWeapon(Pawn(Other).Weapon).UpgradeWeapon();
Destory();
}
}
用一個Touch 的Event去呼叫兩個Actor撞再一起,先判斷Actor是否撞到Pawn(玩家),如果是的話再判斷是否拿著我們的武器(CustomWeapon),這之間要做typecasting:
第一個就是把Actor轉成Pawn,才能確定是否撞到Actor的是Pawn,再來就是Pawn(Other).Weapon,因為Actor並沒有Weapon這個值,Weapon是在Pawn,所以就是把撞到的主角(Pawn)裡面的Weapon數值是否為none,最後就是CustomWeapon(Pawn(Other).Weapon).UpgradeWeapon(),因為一直做typecast所以可以呼叫CustomWeapon.uc的UpgradeWeapon()並執行CurrentWeaponLevel++。
在DefaultProperties 新增:
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_Y'
Scale3D=(X=0.125,Y=0.125,Z=0.125)
End Object
Components.Add(myMesh)
Begin Object Class=CylinderComponent Name=myCollision
CollisionRadius=16.0
CollisionHeight=16.0
BlockNonZeroExtent=true
BlockZeroExtent=true
BlockActors=true
CollideActors=true
End Object
CollisionComponent=myCollision
Components.Add(myCollision)
bCollideActors讓Actor如果有東西跑過來去執行Touch,StaticMeshComponent是為顯示Cube(UN_SimpleMeshes.TexPropCube_Dup),Material(0)設定了材質(EditorMaterials.WidgetMaterial_Y),Scale3D則對Cube做縮放,而CylinderComponent則針對Collision的範圍作修改,同時也給予Cube CollisionComponent這個屬性
目前的WeaponUpgrade.uc:
class WeaponUpgrade extends AlexGameActor placeable; 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(); } } DefaultProperties { 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_Y' Scale3D=(X=0.125,Y=0.125,Z=0.125) End Object Components.Add(myMesh) Begin Object Class=CylinderComponent Name=myCollision CollisionRadius=16.0 CollisionHeight=16.0 BlockNonZeroExtent=true BlockZeroExtent=true BlockActors=true CollideActors=true End Object CollisionComponent=myCollision Components.Add(myCollision) } |
新增的Component一定要Add進去。
在Editor內放置WeaponUpgrade,一定要把槍撿起來,再碰WeaponUpgrade Actor發現他會被Destroy,在CustomWeapon.uc新增加log便於觀察
function UpgradeWeapon(){
CurrentWeaponLevel++;
`log(“Our CustomWeaponUpgradeLevel:” @ CurrentWeaponLevel);
}
在CustomWeapon.uc 新增:
class CustomWeapon extends UTWeapon; var int CurrentWeaponLevel; const MAX_Level = 5; function UpgradeWeapon() { if(CurrentWeaponLevel < MAX_Level) CurrentWeaponLevel++ `log("Our CustomWeaponUpgradeLevel:" @ CurrentWeaponLevel); } DefaultProperties { CurrentWeaponLevel=0 } |
不過事實上,即使吃了武器能力還沒做變化。
實作改變武器攻擊速率:
在CustomWeapon.uc宣告:
var float FireRate[MAX_LEVEL]
在DefaultProperties 設定FireRate值
FireRate(0)=1.0
FireRate(1)=0.8
FireRate(2)=0.5
FireRate(3)=0.3
FireRate(4)=0.1
在UpgradeWeapon()裡改變FireInterval:
FireInterval[0]=FireRate[CurrentWeaponLevel -1];
因為if(CurrentWeaponLevel < MAX_Level){CurrentWeaponLevel++;} ,因此要在CurrentWeaponLevel-1 才會從0開始。再來就是當拿到新的武器把firing timer rest,在UpgradeWeapon()新增:
if(IsInState('WeaponFiring')))
{
ClearTimer(nameof(RefireCheckTimer));
TimeWeaponFiring(CurrentFireMode);
}
再撿起武器時,同時把武器子彈填滿:
AddAmmo(MaxAmmoCount);
這已定義在UTWeapon.uc
完整CustomWeapon.uc
class CustomWeapon extends UTWeapon; var int CurrentWeaponLevel; const MAX_Level = 5; var float FireRate[MAX_Level]; function UpgradeWeapon() { if(CurrentWeaponLevel < MAX_Level) CurrentWeaponLevel++; FireInterval[0]=FireRate[CurrentWeaponLevel-1]; if(IsInState('WeaponFiring')) { ClearTimer(nameof(RefireCheckTimer)); TimeWeaponFiring(CurrentFireMode); } AddAmmo(MaxAmmoCount); `log("Our CustomWeaponUpgradeLevel:" @ CurrentWeaponLevel); } DefaultProperties { CurrentWeaponLevel=0 FireRate(0)=1.0 FireRate(1)=0.8 FireRate(2)=0.5 FireRate(3)=0.3 FireRate(4)=0.1 } |
每吃一個Actor,武器攻擊速率發生變化。
B. Script Usage:Class Modifiers & Some Tips
當實作一個基本的Actor 其功能,基本的category,這裡先而外創造一個GameActor.uc做說明:
顯示不出任何東西,如果將宣告var() int GravitValue 則
若想把GravityValue放置在Physics的category則宣告方式變成var(Physics) int GravityValue;
Hidecategories:
當寫好Actor給其他Level Design但又不想要給他們更改到category裡的值,設定上可以使用Hidecategories:
class GameActor extends Actor hidecategories(Mobile,Debug) placeable; var(Physics) int GravitValue; function PostBeginPlay() { super.PostBeginPlay(); } DefaultProperties { Begin Object Class=SpriteComponent Name=TextureSprite Sprite=Texture2D'EditorResources.S_NavP' End Object Components.Add(TextureSprite) } |
在extends Actor 後面加上hidecategories(Mobile,Debug) 即可,其結果
Abstract:
先看地圖上的UTWeaponPickupFactory裡的Weapon Pickup Class:
之前實作CustomWeapon 繼承UTWeapon,而CustomRifleWeapon 繼承 CustomWeapon,而在使用武器時,真正實作到功能的是CustomRifleWeapon,CustomWeapon不應該出現在Weapon pickup class以免不小心選擇到,因此在CustomWeapon.uc 增加Abstract:
class CustomWeapon extends UTWeapon
abstract;
其CustomWeapon就會被隱藏
被標示為abstract的class不能被Script spawn出來。
Native:
一般來說是完全用不到的,也不需要用在自己定義的Script裡面,通常出現在Engine source code,而一般也不能去修改,可以無視它。
Showcategories:
使用方式跟HideCategories一樣
class GameActor extends Actor
showcategories(Mobile,Debug)
placeable;
Done
File: CH4.Zip
No comments:
Post a Comment