8:《地牢守卫者》代码分析:AntInventoryManager,AntWeapon,AntProjectile
Posted on 2012-02-28 18:14 neocsl 阅读(299) 评论(0) 编辑 收藏 举报AntInventoryManager是装备管理栏,在这里管理武器创建工作。
先处理一个函数OwnerDied(),这是处理玩家死亡时,手上的武器是否存在。将他写空将不会让手上的武器消失。
记着在AntPlayerController中的possess处调用了AntPlayer(pawn).CreateInventoryManagerFromTemplate();来将武器栏创建给pawn
这里将声明其函数该函数的返回类型为Inventory
function Inventory CreateInventoryFromTemplate(Actor InventoryActorTemplate,bool bDoNotActive)
{
local Inventory Inv;
if(InventoryActorTemplate!=none)
{
Inv=Inventory(spawn(InventoryActorTemplate.class,Owner,,,,InventoryActorTemplate,true));
if(Inv!=none)
{
if(!Inv.AddInventory(InventoryActorTemplate,bDoNotActive))
{
Inv.Destory();
Inv=none;
}
}
else
`log('Can't spawn Inv');
}
return Inv; //没有太多复杂的地方,就是将代码写的更健壮
}
defaultProperties
{
PendingFire(0)=0
PendingFire(1)=0
}
接下来创建武器类Weapon,武器类有一个连接函数,将武器和pawn及相应的骨骼插槽进行连接
首先生成一些变量
var name AttachWeaponSocket;
var AntProjectile Projectile;
var vector ProjectileSpawnLocation;
var name MuzzleFlashSocket;
以上变量都能见名知意。
simulated function AttachWeaponTo(SkeletalMeshComponent SkelComp,optional name SocketName)
{
local AntPawn P;
p=AntPawn(Instigator); //武器所属的一个引用
Mesh.SetLightEnvironment(p.LightEnvironment);
Mesh.SetShadowParent(P.Mesh); //Mesh是枪的骨骼,他将以角色的光照和阴影为父系
if(Socket!='none')
{
SetBase(P,,P.Mesh,SocketName);
P.Mesh.AttachComponentToSocket(Mesh,SocketName); //参数Mesh是枪的,将其连接到插槽上
}
SetBase(P);
SetHidden(false); //如果没有激活,不将其弄消失
}
同样有链接就有取消连接
simulated function DetachWeapon()
{
super.DetachWeapon();
SetHidden(true);
Mesh.SetShadowParent(none);
Insitgator.Mesh.DetachComponent(Mesh);
}
前面的连接函数是在Activate中被进行调用的,该函数可以初始化枪的底层系统。
function Acitvate()
{
super.Activate();
AttachWeaponTo(instigator.Mesh,AttachWeaponSocket);
}
和Activate对应的是PutDownWeapon
function PutDownWeapon()
{
super.PutDownWeapon();
DetachWeapon();
}
以下是最为关键的内容,定义发射。
有两种标准的函数可以控制发出射弹,其中之一是
simulated function projectile projectilefire()
simulated function CustomFire()
这里使用customFire
simulated function CusomFire()
{
local AntProjectile theProjectile;
local rotator SpawnRotation;
loca vector SpawnLocation;
SpawnLocation+=vector(ProjectileSpawnLocation>>spawnRotation); //将生成的射弹位置以SpawnRotation为参考系
SpawnRotation=AntPawn(instigator).Rotation; //获取玩家的转向
//变量的引用类,自己的actor
theProjectile=Spawn(ProjectileTemplate.class,self,spawnLocation,SpawnRotation,ProjectileTemplate,true);
theProjectile.Init(vector(SpawnRotation)); //还记着怎么找初始化吗 spawn(enemy.location,location);
}
weapon类中有以下几个重要属性
WeaponFireTypes[0]=EWFT_Custom
FiringStatesArray[0]=WeaponFiring
FireInterval[0]=0.25
最后一个类是Projectile,该类描述了射弹。
Weapon中调用了Projectile的Init函数,该函数生成了射弹,同时内不能定义DamageRadius,DamageType,Damage,MomentumTransfer,Inistigator能一些变量
var float ProjDamage;
var float ProjDamageRadius;
var float ProjMomentumTransfer;
var class<DamageType> ProjDamageType;
可以利用自定义的变量在这里覆盖
function Init(vector Direction)
{
Damage=ProjDamage;
DamageRadius=ProjDamageRadius;
MomentumTransfer=ProjMomentumTransfer;
DamageType=ProjDamageType;
super.Init(Direction0);
}
还有两个变量可以重载Speed,MaxSpeed这两个变量在PostBeginPlay中进行重载
var float Projspeed;
var float ProjMaxSpeed;
var float LifeSpan; //当然是一个重要的参数
simulated event PostBeginPlay()
{
speed=projSpeed;
MaxSpeed=ProjMaxSpeed;
super.PostBeginPlay();
///以下内容在将Emitter综合之后再添加
}
一下是处理伤害和可以生成贴花的地方
simulated function ProcessTouch(actor other,vector Hitlocation,vector hitnormal)
{
if(other!=instigator)
Explode(Hitlocation,hitnormal);
}
simulated function Explode(vector HitLocation,vector HitNormal)
{
local vector DownHitLocation,DownHitNormal;
super.Explode(HitLocation,HitNormal);
//可以再次创建贴花
}
至此,武器系统告一段落。下一节我将进行ManaToken的研究。