UE4学习笔记:小白试试不用插件做一个简陋的特效

因为作业要求,老师让我们写代码(蓝图应该也允许)做一个物体爆炸的简陋特效,还不让用插件,所以只好自己来做一个low很多的。

本文是上一篇文章:UE4学习笔记:访问StaticMesh的网格顶点并画点 的后续,得到一个物体StaticMesh网格体顶点的数据之后,尝试接着做下去。

我打算模拟以下陨石坠落。

演示gif链接:(帧率有点低,是录屏软件的原因)演示

具体思路:利用刚才得到的网格体顶点数据,在每个顶点处生成小方块/圆球,同时销毁本物体。

由于之前我们把MeshData这个函数暴露给了蓝图,所以等会可以在蓝图中调用了。

UFUNCTION(BlueprintPure, Category = "Corridor", meta = (Keywords = "corridor vertex mesh meshdata", NativeBreakFunc))

TArray<FVector> MeshData(const UStaticMeshComponent* StaticMeshComponent);

注意:由于我不用描点了,现在的C++类里面只有这个函数了。
我现在的C++代码如下:

头文件:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/StaticMeshComponent.h"
#include "GetStaticMeshVertexes.generated.h"

UCLASS()
class EXPERIMENT_2_24_VER_API AGetStaticMeshVertexes : public AActor
{
     
	GENERATED_BODY()

	UFUNCTION(BlueprintPure, Category = "Corridor", meta = (Keywords = "corridor vertex mesh meshdata", NativeBreakFunc))
	TArray<FVector> MeshData(const UStaticMeshComponent* StaticMeshComponent);
	
public:	
	// Sets default values for this actor's properties
	AGetStaticMeshVertexes();
	

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;


};

CPP:

// Fill out your copyright notice in the Description page of Project Settings.


#include "GetStaticMeshVertexes.h"
#include "Components/StaticMeshComponent.h"
#include "Rendering/PositionVertexBuffer.h"
#include "Engine/StaticMesh.h"
#include "StaticMeshResources.h"





// Sets default values
AGetStaticMeshVertexes::AGetStaticMeshVertexes()
{
     
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	

}

void AGetStaticMeshVertexes::BeginPlay()
{
     
	Super::BeginPlay();
}

void AGetStaticMeshVertexes::Tick(float DeltaTime)
{
     
	Super::Tick(DeltaTime);
	
	
}

// Called when the game starts or when spawned
TArray<FVector> AGetStaticMeshVertexes::MeshData(const UStaticMeshComponent* StaticMeshComponent)
{
     
	TArray<FVector> vertices = TArray<FVector>();
	
	//~~~~~~~~~~~~~~~~~~~~
	// Many thanks to Rama for this solution! :)
	//
	// Vertex Buffer
	if (!IsValidLowLevel()) return vertices;
	if (!StaticMeshComponent) return vertices;
	if (!StaticMeshComponent->GetStaticMesh()) return vertices;
	if (!StaticMeshComponent->GetStaticMesh()->RenderData) return vertices;
	if (StaticMeshComponent->GetStaticMesh()->RenderData->LODResources.Num() > 0)
	{
     
		FPositionVertexBuffer* VertexBuffer = &StaticMeshComponent->GetStaticMesh()->RenderData->LODResources[0].VertexBuffers.PositionVertexBuffer;
		if (VertexBuffer)
		{
     
			const int32 VertexCount = VertexBuffer->GetNumVertices();
			for (int32 Index = 0; Index < VertexCount; Index++)
			{
     
				//This is in the Static Mesh Actor Class, so it is location and tranform of the SMActor
				const FVector WorldSpaceVertexLocation = GetActorLocation() + GetTransform().TransformVector(VertexBuffer->VertexPosition(Index));
				//add to output FVector array
				vertices.Add(WorldSpaceVertexLocation);
			}
		}
	}

	return vertices;
}

注意:在这之后,上篇文章中生成的StaticMeshComponent组件explode_actor会消失,所以手动再加一个即可,我还是用的那个石头(资源中搜SM_Rock即可),命名为Rock
在这里插入图片描述
UE4学习笔记:小白试试不用插件做一个简陋的特效_第1张图片

接着我们来到内容浏览器,找到创建的C++类,并扩展他的蓝图类。
UE4学习笔记:小白试试不用插件做一个简陋的特效_第2张图片
此蓝图类现在在我创建的新的Blueprint文件夹中:
在这里插入图片描述
接着在此文件夹内再创建一个空的蓝图类,我个人是命名为Cubes。
在这里插入图片描述
打开这个蓝图类,我们先来编辑这个类
在Viewport,中,为他添加StaticMesh和材质
UE4学习笔记:小白试试不用插件做一个简陋的特效_第3张图片
然后尺寸可以改小一点,我是0.2
UE4学习笔记:小白试试不用插件做一个简陋的特效_第4张图片
在这里插入图片描述
记得打开物理模拟

保存之后,我们双击刚才C++扩展的那个蓝图类,开始写蓝图代码,我们先添加一个函数,我把他命名为Explode:
UE4学习笔记:小白试试不用插件做一个简陋的特效_第5张图片

双击这个函数开始编辑,先加入以下蓝图,调用MeshData函数,得到一个存放顶点的数组,并将它初始化
UE4学习笔记:小白试试不用插件做一个简陋的特效_第6张图片
再利用循环,用蓝图中的生成方法,在每个顶点处生成刚才创建的Cubes类,循环结束后销毁本物体
UE4学习笔记:小白试试不用插件做一个简陋的特效_第7张图片
因为模拟陨石,所以感觉用重力的话有点假,所以我给他自己设一个看起来比较快的速度:

我们来到事件图表中,添加以下蓝图代码:
UE4学习笔记:小白试试不用插件做一个简陋的特效_第8张图片
那个DeltaLocation顾名思义就是设定方向+速度,这个随意,因为我模拟陨石坠落,所以设置沿Z轴向下。

这样我们的石头就可以下落了。

此时别忘了给它加一个胶囊体!(别的也行,就是待会要碰撞)
在这里插入图片描述
还有在场景中,我们的石头的下方,也要放一个Box Trigger或其他碰撞体,我是放在了这个桌子里:
UE4学习笔记:小白试试不用插件做一个简陋的特效_第9张图片
选中你拖到场景中的已实例化的石头蓝图类:
UE4学习笔记:小白试试不用插件做一个简陋的特效_第10张图片

接下来我们打开关卡蓝图:
UE4学习笔记:小白试试不用插件做一个简陋的特效_第11张图片
单击右键,这时由于我们刚才选中了我们的石头类,就会出现以下选项:
UE4学习笔记:小白试试不用插件做一个简陋的特效_第12张图片
我们使用这个Add On Actor Begin Overlap,是一个事件类,顾名思义就是当我们石头类的碰撞体和别的碰撞体重合时,会调用这里面的事件。
UE4学习笔记:小白试试不用插件做一个简陋的特效_第13张图片

等会我们还要用到这个,也可以一起创建,之后就会出现一个对石头类的引用:
在这里插入图片描述
下面蓝图的功能很好看出,就是当碰撞时调用我们刚写好的Explode函数,让石头“爆炸”。
UE4学习笔记:小白试试不用插件做一个简陋的特效_第14张图片
接下来我们搞点粒子特效,我们可以创建一个空物体附着在石头类上,方便指定特效发生的位置:
在这里插入图片描述
在Explode后面添加以下蓝图,生成指定特效:
UE4学习笔记:小白试试不用插件做一个简陋的特效_第15张图片
(这个P_Explosion是初学者包中自带的,你要用的话需要先导入初学者包)
然后下面自己设置范围尺寸啥的,不过多赘述。

为了更真实,可以把初学者包中的火焰特效附着到我们的石头上:
在这里插入图片描述
UE4学习笔记:小白试试不用插件做一个简陋的特效_第16张图片
这样它就燃烧起来了。

最后别忘了这个火焰特效也要销毁:
UE4学习笔记:小白试试不用插件做一个简陋的特效_第17张图片
这样就做好了

完整蓝图:
UE4学习笔记:小白试试不用插件做一个简陋的特效_第18张图片

UE4学习笔记:小白试试不用插件做一个简陋的特效_第19张图片

本人接触UE4也没多久,也是小白,如果可以有优化的地方欢迎指出,也欢迎交流学习UE4。

你可能感兴趣的:(笔记)