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

    自定义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.效果


  • 相关阅读:
    Java的静态块与实例块(转)
    Programming Ability Test学习 1031. Hello World for U (20)
    Programming Ability Test学习 1011. World Cup Betting (20)
    Programming Ability Test学习 1027. Colors in Mars (20)
    Programming Ability Test学习 1064. Complete Binary Search Tree (30)
    Programming Ability Test学习 1008. Elevator (20)
    【maven详解-生命周期】Maven的生命周期和插件
    【maven详解-插件】maven插件学习之源码插件Source Xref
    $(document).ready(){}、$(fucntion(){})、(function(){})(jQuery)onload()的区别
    你还没真的努力过,就轻易输给了懒惰
  • 原文地址:https://www.cnblogs.com/corgi/p/5405451.html
Copyright © 2011-2022 走看看