【目标】
镜头粒子的实现
【思路】
1 之前的实验
\ue3\Development\Src\ExampleGame\Classes\ExamplePlayerCamera.uc
Begin Object Class=SpriteComponent Name=Sprite
Sprite=Texture2D‘EditorResources.S_Emitter‘
//HiddenGame=True
AlwaysLoadOnClient=False
AlwaysLoadOnServer=False
bIsScreenSizeScaled=True
ScreenSize=0.0025
SpriteCategoryName="Effects"
End Object
Components.Add(Sprite)
看不到
放到\ue3\Development\Src\ExampleGame\Classes\ExampleSkeletalMeshActor.uc
可以看到
2 EmitterCameraLensEffectBase
3 UDN中描述
http://udn.epicgames.com/Three/CameraTechnicalGuideCH.html
镜头特效是粒子特效,可以将其用于玩家的相机的镜头。这些镜头特效可以用于创建诸如相机镜头中下的雨滴、血溅、镜头上的污物或灰尘等等这一类的效果。这个 camera 类会包含可以使用这些特效类型的函数。
要了解有关粒子系统和特效的更多信息,请参阅ParticleSystemReference(粒子系统参考)。
镜头特效属性
镜头特效函数
4 在Notify_CameraEffect中 资源新建出来是空的
修改\Development\Src\Engine\Classes\AnimNotify_CameraEffect.uc试下
defaultproperties{ CameraLensEffect=class‘Engine.EmitterCameraLensEffectBase‘}
测试无效果
5 实验:UAnimNotify_CameraEffect.Notify 中
void UAnimNotify_CameraEffect::Notify( UAnimNodeSequence* NodeSeq ){ AActor* Owner = NodeSeq->SkelComponent->GetOwner(); CameraLensEffect = AEmitterCameraLensEffectBase::StaticClass();
机器人的动作上绑
跑地图测试,触发run动作,发现Spawn不了抽象类
该类的脚本
难道需要继承一个类
好吧,添加一个EmitterCameraLensEffect.uc
class EmitterCameraLensEffect extends EmitterCameraLensEffectBase native(Particle);DefaultProperties{}
编译uc
添加这个派生类之后就看到了
在\Development\Src\Engine\Classes\EmitterCameraLensEffectBase.uc中设置PSTemplate
PS_CameraEffect=ParticleSystem‘FogClouds.P_TestCloud_c‘ PS_CameraEffectNonExtremeContent=ParticleSystem‘ef_wj_016.ef_wj_016_eff01‘
测试发现,没有调用UpdateCameraLensEffects函数来更新位置
打印一些GamePlayerCamera.UpdateViewTarget的log
原因是ExamplePlayerCamera.有自己的UpdateViewTarget
\Development\Src\ExampleGame\Classes\ExamplePlayerCamera.uc添加应用LensEffect函数
`log("ExamplePlayerCamera::UpdateViewTarget 4"); UpdateCameraLensEffects( OutVT );
还需要复制UpdateCameraLensEffects
/** Update any attached camera lens effects (e.g. blood) **/simulated function UpdateCameraLensEffects( const out TViewTarget OutVT ){ local int Idx; for (Idx=0; Idx<CameraLensEffects.length; ++Idx) { if (CameraLensEffects[Idx] != None) { CameraLensEffects[Idx].UpdateLocation(OutVT.POV.Location, OutVT.POV.Rotation, OutVT.POV.FOV); } }}
屏幕上出现了粒子,
小结:
问题:
待解决
【步骤】
1 修改\Development\Src\Engine\Classes\AnimNotify_CameraEffect.uc
/** * How far in front of the camera this emitter should live, assuming an FOV of 80 degrees. * Note that the actual distance will be automatically adjusted to account for the actual FOV. */var() float DistFromCamera;/** Particle System to use */var() ParticleSystem PS_CameraEffect;...
defaultproperties{ CameraLensEffect=class‘Engine.EmitterCameraLensEffect‘ DistFromCamera=90}
2 添加AddEmitterCameraLensEffect 接口
/** * Initiates a camera lens effect of the given PSTemplate on this camera. */function EmitterCameraLensEffectBase AddEmitterCameraLensEffect( ParticleSystem LensEffectTemplate ){ local vector CamLoc; local rotator CamRot; local EmitterCameraLensEffectBase LensEffect; if (LensEffectTemplate != None) { LensEffect = Spawn( class‘EmitterCameraLensEffect‘, PCOwner.GetViewTarget() ); if (LensEffect != None) { LensEffect.SetEffectTemplate(LensEffectTemplate); GetCameraViewPoint(CamLoc, CamRot); LensEffect.UpdateLocation(CamLoc, CamRot, GetFOVAngle()); LensEffect.RegisterCamera(self); CameraLensEffects.AddItem(LensEffect); } }}
3 UAnimNotify_CameraEffect.Notify
AEmitterCameraLensEffectBase* pCameraEffect = Cast<APlayerController>(Owner->GetAPawn()->Controller)->eventClientSpawnLensEffect(PS_CameraEffect); if (pCameraEffect) { pCameraEffect->DistFromCamera = DistFromCamera; }
如果不旋转呢?
4 为EmitterCameraLensEffectBase添加两个属性
var protected transient bool bAdjustRot;var protected ESceneDepthPriorityGroup DepthPriorityGroup;
event SetEffectTemplate(ESceneDepthPriorityGroup NewDepthPriorityGroup){ ParticleSystemComponent.SetDepthPriorityGroup(NewDepthPriorityGroup);}
5 场景的配置,修改worldinfo.uc
var (Player) ParticleSystem CameraEffect;
\Development\Src\ExampleGame\Classes\ExamplePlayerController.uc
simulated event PostBeginPlay(){ local EmitterCameraLensEffectBase LensEffect; super.PostBeginPlay(); if ( WorldInfo.CameraEffect != none ) { LensEffect = ClientSpawnLensEffect(WorldInfo.CameraEffect); if ( LensEffect != none ) LensEffect.SetDepthPriorityGroup(SDPG_World); }}
6 PlayerController.SpawnPlayerCamera
// Camera Effect if ( WorldInfo.CameraEffect != none ) { `log( "Examp PC PostBeginPlay 1" ); LensEffect = ClientSpawnLensEffect(WorldInfo.CameraEffect); if ( LensEffect != none ) LensEffect.SetDepthPriorityGroup(SDPG_World); }
跑地图看不到粒子 OMG
有tick有调用FParticleDataManager.UpdateDynamicData.
修改一下调用时机,在UWorld.Tick中调用一次,就可以看到
在UWorld.SpawnPlayActor最后面调用就行了
7 UWorld添加一个接口是 用于设置镜头特效的,用于Matinee等地方触发
8 修改Emitter.uc 添加一个镜头属性
var(LensEffect) bool bLensEffect;var(LensEffect) bool bAdjustRot;var(LensEffect) float DistFromCamera;var(LensEffect) ESceneDepthPriorityGroup DPG;
void USkelControlHitPlacement::CalculateNewBoneTransforms(INT BoneIndex, USkeletalMeshComponent* SkelComp, TArray<FBoneAtom>& OutBoneTransforms)
{
check(BoneIndex != 0);
....
}
【运行】
3
原文:http://www.cnblogs.com/username/p/6022465.html