• 16092001(镜头粒子)


    【目标】

    镜头粒子的实现

    【思路】

    1 之前的实验

    ue3DevelopmentSrcExampleGameClassesExamplePlayerCamera.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)

    看不到

    放到ue3DevelopmentSrcExampleGameClassesExampleSkeletalMeshActor.uc

    可以看到



    EmitterCameraLensEffectBase


    3 UDN中描述

    http://udn.epicgames.com/Three/CameraTechnicalGuideCH.html

    镜头特效

    镜头特效是粒子特效,可以将其用于玩家的相机的镜头。这些镜头特效可以用于创建诸如相机镜头中下的雨滴、血溅、镜头上的污物或灰尘等等这一类的效果。这个 camera 类会包含可以使用这些特效类型的函数。

    要了解有关粒子系统和特效的更多信息,请参阅ParticleSystemReference(粒子系统参考)

    镜头特效属性

      • CameraLensEffects – 当前应用于相机的所有粒子特效的数组。

    镜头特效函数

    • FindCameraLensEffect [LensEffectEmitterClass] – 会搜索当前应用于相机的镜头特效并返回任何与之匹配的类型。
      • LensEffectEmitterType – 要搜索的镜头特效的类。
    • AddCameraLensEffect [LensEffectEmitterClass] – 会将指定类型的新镜头特效应用于相机中。
      • LensEffectEmitterClass – 要应用到相机中的镜头特效的类。
    • RemoveCameraLensEffect [Emitter] – 从相机中删除一个镜头特效。
      • Emitter – 要从相机中删除的镜头特效。
    • ClearCameraLensEffects – 删除当前应用于相机中的所有镜头特效。



    4 在Notify_CameraEffect中 资源新建出来是空的


    修改DevelopmentSrcEngineClassesAnimNotify_CameraEffect.uc试下

    defaultproperties
    {
        CameraLensEffect=class'Engine.EmitterCameraLensEffectBase'
    }


    编译uc‘通过

    测试无效果


    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


    添加这个派生类之后就看到了



    在DevelopmentSrcEngineClassesEmitterCameraLensEffectBase.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


    DevelopmentSrcExampleGameClassesExamplePlayerCamera.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);
            }
        }
    }


    屏幕上出现了粒子,


    小结:

    • 这里是Notify触发一个Class去Spawn出一个Emitter
    • 这样做很不方便


    方案

    • 继承一个EmitterCameraLensEffectBase的派生用于Notify类型的
    • Notify中可配置特效Template,和摄像机的距离等参数
    • Spawn出来后,Notify再将参数传递给它
    • 如果是场景相关的也是配置到WorldInfo中
    • 在PlayerController的PostBeginPlay中去Spawn,不行!此时还没有Camera,添加不了特效
    • PlayerController.SpawnPlayerCamera


    问题:

    • 在PlayerController无法去传递参数
    • 原有机制的初衷应该是所有参数都在CameraLensEffectClass
    • 所以如果能做多个派生类,在资源管理器中去选择,
    • 那每新建一个不同资源,就要都要写一个uc,而且还需要编译u,
    • 为什么不能实时动态的去控制它,修改资源
    • 添加另外的接口,在Spawn的是否传入PSTemplate


    待解决

    • 删除的时机,如果是循环粒子
    • 如何切换,替换原有的,根据类型来判断?


    【步骤】

    1 修改DevelopmentSrcEngineClassesAnimNotify_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;



    DevelopmentSrcExampleGameClassesExamplePlayerController.uc

    simulated event PostBeginPlay()
    {
        local EmitterCameraLensEffectBase LensEffect;
        super.PostBeginPlay();
        if ( WorldInfo.CameraEffect != none )
        {
            LensEffect = ClientSpawnLensEffect(WorldInfo.CameraEffect);
            
            if ( LensEffect != none )
                LensEffect.SetDepthPriorityGroup(SDPG_World);
        }
    }



    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






  • 相关阅读:
    使用yarn来替代npm
    React及Nextjs相关知识点小结
    appstore-react v2.0—redux-actions和redux-saga的应用
    开机SystemServer到ActivityManagerService启动过程分析
    java 读取气象专业格式NetCDF文件
    maven项目对于maven远程仓库没有资源的解决办法
    leaflet 使用kriging.js实现前端自定义插值
    leaflet 使用高德地图实例
    uni-app上使用leaflet地图的解决方案
    MySQL创建新用户并且赋予权限
  • 原文地址:https://www.cnblogs.com/username/p/6022465.html
Copyright © 2020-2023  润新知