項目
所謂的邏輯分析
主要是Spawn函數生成一個類,需要指定生成位置,子彈類在遊戲中生成除了生成位置還要能看到它,要看到它就要粒子特效,生成的子彈類要運動,運動就要有方向和速度,
在UDK中生成子彈用的是Socket,生成的位置就是Socket在世界空間中的位置,特效產生的位置也在Socket位置,粒子系統組件就附加到Socket,武器開火有聲音,,,,
不明白爲什麼上面提到的三個東西在UDK中都好像需要在結構體中定義才能生效,好像結構體的名字都是固定好了的,要訪問它們又要通過結構體變量訪問,
所以生成子彈用到的東西不多,只是代碼有點繞。
最終實現效果(發射四個射彈)
在Editor中創建的四個Scoket
代碼部分:
ClassMyState_Test extendsPawn
placeable;
// Sounds for turret behaviors
structTurretSoundGroup
{
var()SoundCueFireSound; //開火時播放的聲音
};
//PSystems for the turret
structTurretEmitterGroup
{
var()ParticleSystemMuzzleFlashEmitter; //開火時的槍口火焰特效
var()FloatMuzzleFlashDuration; //應該是粒子系統持續時間間隔吧
structdefaultproperties
{
MuzzleFlashDuration=0.33 //結構體成員附初值
}
};
//Bone, Socket, Controller names
structTurretBoneGroup
{
var()NameFireSocket; //開火時的骨骼,插槽;在Editor中插槽的名字
var()Namefs11;
var()Namefs44;
var()Namefshh;
};
varVector FireLocation; //World position of the firing socket,定義骨骼,插槽;三維空間世界座標系中的位置變量------本例中用來生成槍口火焰和子彈的初始位置
varRotator FireRotation; //World orientation of the firing socket 定義骨骼,插槽的旋轉(方向)
varVector FireLocation11; //骨骼,插槽;三維空間世界座標系中的位置------本例中用來生成槍口火焰和子彈的初始位置
varVector FireLocation44; //定義骨骼,插槽的旋轉(方向)變量
varVector FireLocationhh;
varRotator FireRotation11;
varRotator FireRotation44;
varRotator FireRotationhh;
varParticleSystemComponentMuzzleFlashEffect; //PSys component for playing muzzleflashes
varParticleSystemComponentMuzzleFlashEffect1;//粒子系統組件,用來播放槍口火焰特效
varParticleSystemComponentMuzzleFlashEffect2;
varParticleSystemComponentMuzzleFlashEffect3;
/*Designer editable variables
* 定義在Editor(Turret欄)中可編輯的變量
* */
var(Turret)DynamicLightEnvironmentComponent LightEnvironment; //LightEnvironment for the turret
var(Turret)TurretBoneGroup TurretBones; //Bone, Socket,Controller names,訪問骨骼結構體的變量
var(Turret)class<Projectile>ProjClass; //Type of projectile the turret fires,定義射彈的類變量
var(Turret)Int RoundsPerSec; //Numberof rounds to fire per second,每秒鐘發射多少個子彈
var(Turret)TurretEmitterGroup TurretEmitters; //PSystems used bythe turret訪問粒子特效結構體的變量
var(Turret)TurretSoundGroup TurretSounds; //Sounds usedfor different turret behaviors訪問聲音結構體的變量
//遊戲開始前需要初始化的一些資源
eventPostBeginPlay()
{
Super.PostBeginPlay();
Mesh.GetSocketWorldLocationAndRotation(TurretBones.FireSocket,FireLocation,FireRotation,0); //設置槍口火焰插槽的位置和旋轉(函數的作用是對前面定義的變量FireLocation,FireRotation附值)-----Mesh =SkeletalMeshComponet
//Mesh.GetSocketWorldLocationAndRotation(TurretBones.FireSocket,FireLocation,FireRotation,0); //第一個變量類型是name,第二個是vector,第三個是rotator,第四個是int,0 == World, 1 == Local (Component)(0表示世界座標,1表示組件的相對座標,默認返回的是世界座標,如果把改成,在本例的測試中看不到子彈)
Mesh.GetSocketWorldLocationAndRotation(TurretBones.fs11,FireLocation11,FireRotation11);
Mesh.GetSocketWorldLocationAndRotation(TurretBones.fs44,FireLocation44,FireRotation44);
Mesh.GetSocketWorldLocationAndRotation(TurretBones.fshh,FireLocationhh,FireRotationhh);
//設置(粒子系統組件)模板
MuzzleFlashEffect.SetTemplate(TurretEmitters.MuzzleFlashEmitter);
MuzzleFlashEffect1.SetTemplate(TurretEmitters.MuzzleFlashEmitter);
MuzzleFlashEffect2.SetTemplate(TurretEmitters.MuzzleFlashEmitter);
MuzzleFlashEffect3.SetTemplate(TurretEmitters.MuzzleFlashEmitter);
//附加粒子系統組件到Socket
Mesh.AttachComponentToSocket(MuzzleFlashEffect,TurretBones.FireSocket);
Mesh.AttachComponentToSocket(MuzzleFlashEffect1,TurretBones.fs11);
Mesh.AttachComponentToSocket(MuzzleFlashEffect2,TurretBones.fs44);
Mesh.AttachComponentToSocket(MuzzleFlashEffect3,TurretBones.fshh);
SetPhysics(PHYS_None);
}
//TakeDamage事件,當這個Actor受到傷害時使它進入一個狀態
eventTakeDamage(intDamage, ControllerInstigatedBy,vectorHitLocation,vectorMomentum,class<DamageType>DamageType,optionalTraceHitInfoHitInfo,optionalActorDamageCauser)
{
GotoState('Defend');
}
//聲明一個狀態
stateDefend
{
functionBeginFire()
{
if(RoundsPerSec > 0)
{
SetTimer(1.0/RoundsPerSec,true,'TimedFire'); //Actor的時間函數,每過.0/RoundsPerSec的時間,運行一次TimedFire函數--True,循環計時器
}
}
//在US中,不帶參數的函數都是可以用作時間函數
functionTimedFire()
{
localProjectileProj; //定義子彈類的局部變量(子彈產生又消失,定義局部變量更合適
localProjectileProj11;
localProjectileProj44;
localProjectileProjhh;
//Spawn函數生成的子彈類附值給定義的子彈類變量,子彈在世界中生成的位置就是初使化過的骨骼插槽在世界空間中的位置變量
Proj=Spawn(ProjClass,self,,FireLocation,FireRotation,,True);
Proj11=Spawn(ProjClass,self,,FireLocation11);
Proj44=Spawn(ProjClass,self,,FireLocation44);
Projhh=Spawn(ProjClass,self,,FireLocationhh);
if(Proj !=None&& !Proj.bDeleteMe) //如果產生的子彈存在並且沒有被刪除(消失)
{
Proj.Init(Vector(FireRotation)); //對子彈進行速度的初使化(把骨骼插槽的(旋轉)朝向轉化成失量作爲它的速度方向)
//這樣骨架網格物在三維空間中移動旋轉,生成的子彈也會隨着骨架網格物移動和旋轉。因爲骨架網格物在遊戲過程中運動時,Soket會保持着和骨架網格物相對不變的移動和旋轉
/*子彈產生後,使用同一個方向射出
Proj11.Init(Vector(FireRotation));
Proj44.Init(Vector(FireRotation));
Projhh.Init(Vector(FireRotation));
*/
//子彈產生後,沿各自Socket的定義的方向射出
Proj11.Init(Vector(FireRotation11));
Proj44.Init(Vector(FireRotation44));
Projhh.Init(Vector(FireRotationhh));
}
if(TurretEmitters.MuzzleFlashEmitter!=None) //如果存在槍口火焰發射器(如果定義了粒子系統變量,並對變量附了值)
{
MuzzleFlashEffect.ActivateSystem(); //激活槍口火焰粒子特效
//SetTimer(TurretEmitters.MuzzleFlashDuration,false,'StopMuzzleFlash');
MuzzleFlashEffect1.ActivateSystem();
//SetTimer(TurretEmitters.MuzzleFlashDuration,false,'StopMuzzleFlash');
MuzzleFlashEffect2.ActivateSystem();
//SetTimer(TurretEmitters.MuzzleFlashDuration,false,'StopMuzzleFlash');
MuzzleFlashEffect3.ActivateSystem();
SetTimer(TurretEmitters.MuzzleFlashDuration,false,'StopMuzzleFlash'); //計時器函數,MuzzleFlashDuration變量定義的是粒子特效所謂的持續時間,過了那個時間後就執行StopMuzzleFlash函數關掉特效--false,非循環
}
if(TurretSounds.FireSound!=None) //如果開火的聲音存在(如果成功定義了聲音)
PlaySound(TurretSounds.FireSound); //播放音效----If後面如果沒有添加{},跟在if後面的第一名代碼就是判斷後是否要執行的語名,其它的都不屬於If語句的內容了。
}
functionStopMuzzleFlash()
{
MuzzleFlashEffect.DeactivateSystem(); //粒子特效設爲非激活狀態
MuzzleFlashEffect1.DeactivateSystem();
MuzzleFlashEffect2.DeactivateSystem();
MuzzleFlashEffect3.DeactivateSystem();
}
eventBeginState(NamePreviousStateName) //作爲Defend狀態,當進入這人狀態函數時首先要執行的代碼BeginState,不明白可參考US狀態編程
{
SetTimer(1.0,false,'BeginFire');
}
eventEndState(NameNewStateName)
{
ClearTimer('TimedFire');
}
}
defaultproperties
{
//爲了讓骨架網格物體可見,定義動態光照組件
BeginObjectClass=DynamicLightEnvironmentComponent Name=MyLightEnvironment
EndObject
LightEnvironment=MyLightEnvironment
Components.Add(MyLightEnvironment) //定義了組件,要使組件可用和生效,需要Add到Component
//定義SkeletalMesh
BeginObjectclass=SkeletalMeshComponent name=SkelMeshComp0
SkeletalMesh=SkeletalMesh'MyState_Chapter11pck.FBX_Gun_Mesh'
AnimTreeTemplate=AnimTree'MyState_Chapter11pck.FBX_Gun_Mesh_AnimTree'
PhysicsAsset=PhysicsAsset'MyState_Chapter11pck.FBX_Gun_Mesh_Physics'
//Scale3D=(X=2.0,Y=2.0,Z=5.0)
LightEnvironment=MyLightEnvironment //動態光照
EndObject
Components.Add(SkelMeshComp0)
/*粒子系統組件,本例中想實現四個射彈,所以定義了四個粒子組件分別把它們添加到Component的-3號數組中*/
BeginObjectClass=ParticleSystemComponent Name=ParticleSystemComponent0
SecondsBeforeInactive=1
EndObject
Components.Add(ParticleSystemComponent0)
MuzzleFlashEffect=ParticleSystemComponent0
BeginObjectClass=ParticleSystemComponent Name=ParticleSystemComponent1
SecondsBeforeInactive=1
EndObject
Components.Add(ParticleSystemComponent1)
MuzzleFlashEffect1=ParticleSystemComponent1
BeginObjectClass=ParticleSystemComponent Name=ParticleSystemComponent2
SecondsBeforeInactive=1
EndObject
Components.Add(ParticleSystemComponent2)
MuzzleFlashEffect2=ParticleSystemComponent2
BeginObjectClass=ParticleSystemComponent Name=ParticleSystemComponent3
SecondsBeforeInactive=1
EndObject
Components.Add(ParticleSystemComponent3)
MuzzleFlashEffect3=ParticleSystemComponent3
//把Editor中Soket的名字附值給定義的骨骼插槽結構體中的成員
TurretBones={(
FireSocket=FireLocation,
fs11 =f11,
fs44 =f44,
fshh =fhh,
)}
TurretSounds={(
FireSound=SoundCue'A_Weapon_Link.Cue.A_Weapon_Link_FireCue',
)}
//槍口火焰特效用到的粒子系統
TurretEmitters={(
MuzzleFlashEmitter=ParticleSystem'WP_Stinger.Particles.P_Stinger_3P_MF_Alt_Fire',
)}
//生成射彈用到的類(這裏用的是LinkPowerPlasma,UDK自帶的林肯槍
ProjClass=class'UTGame.UTProj_LinkPowerPlasma'
RoundsPerSec= 3
bEdShouldSnap=true
}