自定义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. deeplab hole algorithm

    最近看了几篇文章,其中均用到了hole algorithm. 最早用的就是deeplab的文章了,Semantic Image Segmentation with Deep Convolutional ...

  2. leveldb 学习笔记之log结构与存取流程

    log文件的格式 log文件每一条记录由四个部分组成: CheckSum,即CRC验证码,占4个字节 记录长度,即数据部分的长度,2个字节 类型,这条记录的类型,后续讲解,1个字节 数据,就是这条记录 ...

  3. [题解]vijos 运输计划

    Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家 ...

  4. 交易B(队列)

    临近考试,又把之前的上机的题目看了一遍,自己又尝试着敲代码,发现好多之前的代码现在看来都被自己复杂化了许多,于是把现在重写的代码再贴出来. 之前的题目和代码戳这里 #include<queue& ...

  5. 阅读笔记Multi-task Learning for Stock Selection [NIPS1996]

    Multi-task Learning for Stock Selection  Joumana Ghosn and Yoshua Bengio 摘要 用人工神经网络预测未来回报以便于做出对应的金融决 ...

  6. vs2015 现用插件

    1.abphelper abp app自动生成接口和input output 2.ankhsvn svn插件 3.c#outline2015 大括号折叠 4.codemaid 格式化 5.go to ...

  7. List集合基于某个字段排序

    using System; using System.Collections.Generic; namespace ConsoleApplication1 { class Product { publ ...

  8. iOS所有的子视图

    for (id view in [self.view subviews]) { if ([view isEqual:[UITextField class]]) { NSLog(@"你想要?& ...

  9. java中super的两种用法

    通过用static来定义方法或成员,为我们编程提供了某种便利,从某种程度上可以说它类似于C语言中的全局函数和全局变量.但是,并不是说有了这种便利,你便可以随处使用,如果那样的话,你便需要认真考虑一下自 ...

  10. Twitter Bootstrap

    Twitter Bootstrap是一个HTML/CSS/JS框架,适用于移动设备优先的响应式网页开发.主要涉及: HTML:为已有的H5标签扩展了自定义属性 data-* CSS : Reset + ...