- 新建一个空插件,命名:PushCube
- 在插件PushCube中新建一个ActorComponent,命名PushCubeComponent
下面一定要选中插件
PushCubeComponent.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "PushCubeComponent.generated.h"
/**
* 向外发送立方体的组件
*/
UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
class PUSHCUBE_API UPushCubeComponent : public UActorComponent {
GENERATED_BODY()
public:
// Sets default values for this component's properties
UPushCubeComponent();
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
//必须添加标识符 Category ,否则无法作把这个插件打包
/**
* 开始往外推立方体
* bSpawnCube: true - 产生立方体,并且退出去 false - 不产生立方体
*/
UFUNCTION(BlueprintCallable, Category = "PushCube")
void startPushing(bool bSpawnCube);
//施加的力的大小
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PushCube")
float force = 500.0;
//生产的Actor
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PushCube")
TSubclassOf<class AActor> spawnedCube;
};
PushCubeComponent.cpp
// Fill out your copyright notice in the Description page of Project Settings.
/**
* 若在项目中使用这个功能,则不需要包含常用的头文件
* 如果要打包成插件的,则需要把所有引用的详细的头文件添加上,
* 那怕是常用的Actor,也需要包含相应的头文件
*/
#include "PushCubeComponent.h"
#include "DrawDebugHelpers.h"
//下面的头文件需要包含上
#include "GameFramework/Actor.h"
#include "Engine/World.h"
#include "Components/StaticMeshComponent.h"
// Sets default values for this component's properties
UPushCubeComponent::UPushCubeComponent() {
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = /*true*/false;
}
// Called when the game starts
void UPushCubeComponent::BeginPlay() {
Super::BeginPlay();
}
// Called every frame
void UPushCubeComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) {
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}
void UPushCubeComponent::startPushing(bool bSpawnCube) {
if (GetOwner()) {//宿主是否有效
FVector startLocation = GetOwner()->GetActorLocation();
FVector endLocation = startLocation + (GetOwner()->GetActorForwardVector() * 300.0);
if (bSpawnCube && spawnedCube) {//是否生产方块,并且是否指定生成的Cube
//生产方块
GetWorld()->SpawnActor<AActor>(spawnedCube, endLocation, FRotator(0.0, 0.0, 0.0));
}
//发出射线,加测前方是否有静态网格体
FHitResult hitResult;
FCollisionQueryParams queryParams;
bool bHit = GetWorld()->LineTraceSingleByChannel(hitResult, startLocation, endLocation, ECC_Visibility, queryParams);
if (bHit){//击中静态网格体
//获取根节点的静态网格体
UStaticMeshComponent* staticMeshComp = Cast<UStaticMeshComponent>(hitResult.GetActor()->GetRootComponent());
//获取静态网格体是否是移动的
bool bCubeMoveable = hitResult.GetActor()->IsRootComponentMovable();
if (staticMeshComp && bCubeMoveable){
//绘制测试线
DrawDebugLine(GetWorld(), startLocation, endLocation, FColor::Blue, false, 2.0);
//施加一个力,冲击力
/**
* 第一个参数:冲击力的方向和大小
* 第二个参数:骨骼名称
* 第三个参数:是否要瞬间改变速度
*/
staticMeshComp->AddImpulse(GetOwner()->GetActorForwardVector() * staticMeshComp->GetMass()/*获取静态网格体质量*/ * force);
}
}
}
}
- 新建一个被推送的Cube,命名:BP_TestCube
- 把这个插件放到游戏角色上
双击小白人游戏角色的蓝图
添加PushCube组件
选中属性spawned Cube
添加蓝图功能;
按1时:产生推力;按2时,产生立方体
运行
aaa