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

[UE4]自定义MovementComponent组件的更多相关文章

  1. SSIS自定义数据流组件开发(血路)

    由于特殊的原因(怎么特殊不解释),需要开发自定义数据流组件处理. 查了很多资料,用了不同的版本,发现各种各样的问题没有找到最终的解决方案. 遇到的问题如下: 用VS2015编译出来的插件,在SSDTB ...

  2. Android Studio开发基础之自定义View组件

    一般情况下,不直接使用View和ViewGroup类,而是使用使用其子类.例如要显示一张图片可以用View类的子类ImageView,开发自定义View组件可分为两个主要步骤: 一.创建一个继承自an ...

  3. 【转】Android学习基础自定义Checkbox组件

    原文网址:http://forum.maiziedu.com/thread-515-1-1.html heckbox组件是一种可同时选中多项的基础控件,即复选框,在android学习中,Checkbo ...

  4. Swift - 继承UIView实现自定义可视化组件(附记分牌样例)

    在iOS开发中,如果创建一个自定义的组件通常可以通过继承UIView来实现.下面以一个记分牌组件为例,演示了组件的创建和使用,以及枚举.协议等相关知识的学习. 效果图如下:    组件代码:Score ...

  5. vue2入坑随记(二) -- 自定义动态组件

    学习了Vue全家桶和一些UI基本够用了,但是用元素的方式使用组件还是不够灵活,比如我们需要通过js代码直接调用组件,而不是每次在页面上通过属性去控制组件的表现.下面讲一下如何定义动态组件. Vue.e ...

  6. 仿照wtform自定义Form组件

    仿照wtforms自定义Form组件 1.wtforms 点击查看源码分析及使用方法 2.自定义Form组件 #!usr/bin/env python # -*- coding:utf-8 -*- f ...

  7. Python自定义分页组件

    为了防止XSS即跨站脚本攻击,需要加上 safe # 路由 from django.conf.urls import url from django.contrib import admin from ...

  8. 自定义Form组件

    一.wtforms源码流程 1.实例化流程分析 # 源码流程 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._ ...

  9. vue里在自定义的组件上定义的事件

    事件分为原生事件和自定义事件. vue里在自定义的组件上定义的事件,都被认为是自定义事件,必须用$emit()来触发. 这也是子组件向父传值的原理. 如果想作为原生事件,需要在原生事件后面加上.nat ...

随机推荐

  1. 关于tesseract-ocr3的训练和使用

    众所周知,这是一个出色的字符识别软件.这个开源项目可以在http://code.google.com/p/tesseract-ocr/downloads/list下载. 在使用时,建议使用3而不要使用 ...

  2. AQL 对象关系图

  3. 数据转移发现font有问题

    本地正常 以为是mime.types没有 但是发现是存在的  然后根据提示百度了很久都没有解决 解决: 去字体官网下载改字体文件下来 上传到服务器 发现可以正常访问 说明不是服务器的问题 有个提示 i ...

  4. 【POJ2778】DNA Sequence(AC自动机,DP)

    题意: 生物课上我们学到,DNA序列中只有A, C, T和G四种片段. 经科学发现,DNA序列中,包含某些片段会产生不好的基因,如片段"ATC"是不好片段,则"AGATC ...

  5. WebService基本概念及原理

    一.Web Service基本概念 WebService是一种跨编程语言和跨操作系统平台的远程调用技术.Web Service也叫XML Web Service WebService是一种可以接收从I ...

  6. [转]java.lang.OutOfMemoryError:GC overhead limit exceeded

    我遇到这样的问题,本地部署时抛出异常java.lang.OutOfMemoryError:GC overhead limit exceeded导致服务起不来,查看日志发现加载了太多资源到内存,本地的性 ...

  7. android shape使用总结

    今天使用到shape,这个里面有很多属性,在这里我记录一下各个属性的使用的情况以及所代表的意思 <?xml version="1.0" encoding="utf- ...

  8. WinForm用户自定义控件,在主窗体加载时出现闪烁;调用用户控件出现闪烁,需要鼠标才能够显示

    转载自:http://www.dotblogs.com.tw/rainmaker/archive/2012/02/22/69811.aspx 解决方案: 在调用用户控件的窗体里面添加一下代码: pro ...

  9. POJ 3469 Dual Core CPU 最大流

    划分成两个集合使费用最小,可以转成最小割,既最大流. //#pragma comment(linker, "/STACK:1024000000,1024000000") #incl ...

  10. 弄个知乎的粒子动态背景_实践particles.js

    好久没登录知乎,发现他们的登录页面粒子动态效果蛮炫的,查一下代码用了Particles.js基于Canvas画布创建粒子颗粒效果. 上图 上图:   感觉有比格,就照着弄了一个,玩玩.   githu ...