zoukankan      html  css  js  c++  java
  • [UE4]自定义MovementComponent组件

    转自:http://www.cnblogs.com/corgi/p/5405451.html

    自定义Movement组件 

    目的:实现自定义轨迹如抛物线,线性,定点等运动方式,作为组件控制绑定对象的运动。

    基类:UMovementComponent

    过程:

    1.创建UCustomMovementComponenet继承UMovementComponent类,作为各种具体轨迹的父类,完成主要流程的实现。并提供接口给子类override实现具体计算过程。

    2.实现子类轨迹计算过程。这里仅提供线性移动轨迹作为示例。

    一、UCustomMovementComponent类

    /** 
     * class : UCustomMovementComponent 
     * author : Jia Zhipeng 
     * Base class of custom movement component 
     */  
    UCLASS(ClassGroup = Movement, abstract, ShowCategories = (CustomMovement))  
    class CLIENT_API UCustomMovementComponent : public UMovementComponent  
    {  
        GENERATED_UCLASS_BODY()  
      
    public:  
        /*Initialize target position, must be called before TickComponent. 
        **@param bFixedPoint : whether target position is fixed point or target component 
        */  
        UFUNCTION(BlueprintCallable, Category = CustomMovement)  
        virtual void SetTargetPosition(bool bFixedPoint, FVector PointLocation, USceneComponent* MoveTarget=nullptr);  
        //Initialize params which will be used during computation, implementation in derived class.  
        virtual void InitComputeParams() {};  
        //Computation process, must be override in derived class.  
        virtual void ComputeMovement(float DeltaTime, FVector& OutMoveDelta, FQuat& OutNewRotation) {};  
        //Update process.  
        virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;  
        //Check whether should be stopped  
        void CheckIsStop();  
      
    protected:  
        FVector GetTargetPosition();      
        FVector GetHostPosition();  
        //if bFixedPoint is true, use this location to update.  
        FVector PointLocation;  
      
        //The current target we are homing towards. Can only be set at runtime (when projectile is spawned or updating).  
        TWeakObjectPtr<USceneComponent> MoveTarget;  
      
        //If true, use fixed point to update location; else, use MoveTarget.  
        uint32 bFixedPoint:1;  
      
        //If true, stop TickComponent  
        uint32 bStop:1;       
    };  
      
    UCustomMovementComponent::UCustomMovementComponent(const FObjectInitializer& ObjectInitializer)  
        : Super(ObjectInitializer)  
    {  
        bStop = false;  
    }  
    void UCustomMovementComponent::SetTargetPosition(bool bFixedPoint, FVector PointLocation, USceneComponent* MoveTarget)  
    {  
        bStop = false;  
        this->MoveTarget = MoveTarget;  
        this->bFixedPoint = bFixedPoint;  
        this->PointLocation = PointLocation;  
        InitComputeParams();  
    }  
      
    void UCustomMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)  
    {  
        //Tick parent method first, in order to know whether UpdatedComponent is null.  
        Super::TickComponent(DeltaTime, TickType, ThisTickFunction);  
        CheckIsStop();  
        if (bStop)  
            return;  
        FVector OutMoveDelta;  
        FQuat OutNewRotation;  
    //计算Location和Rotation的变化  
        ComputeMovement(DeltaTime, OutMoveDelta, OutNewRotation);  
    //更改UpdatedComponent坐标值的调用方法  
        MoveUpdatedComponent(OutMoveDelta, OutNewRotation, true);   //whether change orientation?  
    //UMovementComponent中注释说在更改Velocity变量后需要调用该方法改变UpdatedComponent的Velocity。看源代码后发现应该是其他如物理Body等需要使用该值。  
        UpdateComponentVelocity();  
    }  
      
    void UCustomMovementComponent::CheckIsStop()  
    {  
        if (!UpdatedComponent)  
        {  
            bStop = true;  
            return;  
        }  
        //whether target is exist  
        if (!bFixedPoint && MoveTarget == nullptr)  
        {  
            bStop = true;  
            return;  
        }  
        //reach the target location then stop  
        float LocationDifference = (GetTargetPosition() - UpdatedComponent->GetComponentLocation()).Size();  
        if (LocationDifference < SMALL_NUMBER)  
        {  
            bStop = true;  
            return;  
        }  
    }  
      
    FVector UCustomMovementComponent::GetTargetPosition()  
    {  
        if (bFixedPoint)  
            return PointLocation;  
        check(MoveTarget != nullptr);  
        return MoveTarget->GetComponentLocation();  
    }  
      
    FVector UCustomMovementComponent::GetHostPosition()  
    {  
        check(UpdatedComponent);  
        return UpdatedComponent->GetComponentLocation();  
    }  

    二、ULinearMovementComponent类

    /** 
     * class : ULinearMovementComponent 
     * author : Jia Zhipeng 
     * Move from current position to target in a constant velocity. 
     */  
    UCLASS(ClassGroup = Movement, meta = (BlueprintSpawnableComponent), ShowCategories = (CustomMovement))  
    class CLIENT_API ULinearMovementComponent : public UCustomMovementComponent  
    {  
        GENERATED_UCLASS_BODY()  
    public:  
        //Linear speed.  
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = CustomMovement)  
        float Speed;  
        virtual void ComputeMovement(float DeltaTime, FVector& OutMoveDelta, FQuat& OutNewRotation) override;  
    };  
    ULinearMovementComponent::ULinearMovementComponent(const FObjectInitializer& ObjectInitializer)  
        : Super(ObjectInitializer)  
    {  
        Speed = 0;  
    }  
      
    void ULinearMovementComponent::ComputeMovement(float DeltaTime, FVector& OutMoveDelta, FQuat& OutNewRotation)  
    {  
        FVector OldVelocity = Velocity;  
        check(UpdatedComponent);  
        Velocity = (GetTargetPosition() - UpdatedComponent->GetComponentLocation()).GetSafeNormal() * Speed;  
        OutMoveDelta = Velocity * DeltaTime;  
        OutNewRotation = OldVelocity.ToOrientationQuat();//use OldVelocity.Rotation().Quarternion() before 4.11 release.  
    }  

    三、使用

    1.在蓝图中添加新创建的LinearMovementComponent组件,并设置组件的初始参数如速度。

    2.在使用该蓝图创建Actor时,设置MovementComponent的Target,SpawnActor时Initial Velocity没有用。

    4.效果

  • 相关阅读:
    Python--基本的对象类型(列表_可变的数据类型)
    Python--基本的对象类型(数字int和布尔值bool)
    Java项目目录结构
    linux- day1
    python学习笔记,视频day20-装饰器
    python学习笔记,视频day19-习题
    python学习笔记,视频day17、18-文件处理
    python学习笔记,视频day16 17-内置函数
    python学习笔记,视频day16-函数作用域,匿名函数,map,filter,reduce
    python学习笔记,视频day15-全局变量与局部变量、风湿理论、函数递归
  • 原文地址:https://www.cnblogs.com/sevenyuan/p/8444120.html
Copyright © 2011-2022 走看看