第一个完整UE项目总结

C++委托蓝图注册

//声明委托  必须声明多播委托
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FRefresh);  

//声明委托字段
{
	UPROPERTY(BlueprintAssignable)
	FRefresh dTest;
}

 蓝图使用

C++方法蓝图调用

UFUNCTION(BlueprintCallable)
	FString GetTitle();

资产文件

类被自动生成出来后把cpp文件删掉,不然会导致资产文件不能识别头文件,仅识别cpp文件然后导致资产加载失败。配了半天,资产加载失败,也是很奔溃的,但是只要我们把cpp文件删掉,重写编译即可。

USTRUCT(BlueprintType)
struct FStateData
{
	GENERATED_BODY()
public:
	/**
    * @brief id
    */
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	uint8 uiStateID;

};
/**
 * 
 */
UCLASS()
class M1_API UD_State : public UPrimaryDataAsset
{
	GENERATED_BODY()
public:
	/**
	 * @brief 状态合集
	 */
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TArray<FStateData> aStates;
	
};

配置表

配置表单行资源的结构体要继承FTableRowBase类

USTRUCT(BlueprintType)
struct FHospitalData :public FTableRowBase
{
	GENERATED_BODY()
	/**
	* @brief 单位ID
	*/
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	uint8 uiUnitID;
};

//加载配置表
UDataTable* const table = LoadObject<UDataTable>(nullptr,*sATPath);
table->GetAllRows<FAssetsTable>("hhhh",OUT outHDarr);//第一个参数只在获取失败的时候用于打印报错,更利于定位问题

添加组件,移除组件,获取组件,查找actor

//添加组件并把组件显示在编辑器里
{
UInitStart* init=NewObject<UInitStart>(this,TEXT("init"));
this->AddInstanceComponent(init);
init->RegisterComponent();
this->AttachToComponent(RootComponent,FAttachmentTransformRules::SnapToTargetIncludingScale);
break;	
}
//移除组件 在ue4里没有移除组件这个功能,应该是不允许任何组件在没有父物体的时候存在
//在蓝图里不允许组件后面连线销毁自身,会提示不应该被销毁。不惯着,去c++里销毁
{
    DestroyComponent();
}
//当你已经获取Actor的时候可以这样获取
//用被注释的方法不能正确获取到组件(UE5不可以)
{
    line =(USplineComponent*)GetComponentByClass(USplineComponent::StaticClass());
    
    //line =reinterpret_cast<USplineComponent*>(GetComponentByClass(TSubclassOf<USplineComponent>()));
}
//根据类获取对象
{
    ahha = (Ahha*)(UGameplayStatics::GetActorOfClass(GetWorld(),Ahha::StaticClass()));
}

动态加载基于AActor蓝图类并实例化(2023/1/3增)

路径可以直接右击资源点击复制资源引用,如果是蓝图在后缀上加上_C

如:WidgetBlueprint'/Game/UI/SelectTool.SelectTool'   Path=WidgetBlueprint'/Game/UI/SelectTool.SelectTool_C'

UClass* tempa= LoadClass<AActor>(nullptr,path);//加载
if(tempa) GetWorld()->SpawnActor(tempa);       //动态生成

蓝图引用传递参数蓝图函数

(点击方法)

字符串比较

直接使用FString的==重载即可,这个重载会根据大小写是否敏感和字符类型选择合适的方法。下面的是宽字符比较两个字符串是否相等的方法。

//MicrosoftPlatformString.h
static FORCEINLINE int32 Strcmp( const WIDECHAR* String1, const WIDECHAR* String2 )
{
	return _tcscmp(String1, String2);
}

延时执行方法和循环执行方法

循环执行,在SetTimerManager根据参数改。

FTimerHandle mTinmeHandle;   //计时器委托句柄
GetWorld()->GetTimerManager().SetTimer(mTinmeHandle,this,&UOrientationState::Swap,5.0f,false); //一次性延时方法执行
GetWorld()->GetTimerManager().ClearTimer(mTinmeHandle);  //清理计时器句柄

3DUI

1.首先创建一个用户控件

2.创建一个蓝图继承自Actor类

3.添加控件组件,并在控件组件的控件类里设置目标用户控件

碰撞检测

碰撞检测的监听使用委托,新建一个参数匹配的委托并注册就可以了。

//.h文件
UFUNCTION()  //一定要加
void OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent,AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);

//.cpp
void AHospitalActor::OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	UE_LOG(LogTemp,Warning,TEXT("碰撞检测,物体名称:%S"),OtherActor->GetName());
}
//BeginPlay里注册
reinterpret_cast<UStaticMeshComponent*>(this->GetComponentByClass(UStaticMeshComponent::StaticClass()))->OnComponentBeginOverlap.AddDynamic(this,&AHospitalActor::OnComponentBeginOverlap);

 

C++接口

最近看到DX12库文件里有一个接口的实现方案,这样实现和在一个正常类里声明虚函数差不多。

THIS_                   INTERFACE FAR* This   //combaseapi.h

//d3dcommon.h  接口声明
typedef interface ID3DInclude ID3DInclude;

DECLARE_INTERFACE(ID3DInclude)
{
    STDMETHOD(Open)(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) PURE;
    STDMETHOD(Close)(THIS_ LPCVOID pData) PURE;
};

//接口实现
class Dx12ShaderInclude : public ID3DInclude
{
	public:
		Dx12ShaderInclude();
		virtual ~Dx12ShaderInclude();
		STDMETHOD(Open)(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID* ppData, UINT* pBytes);
		STDMETHOD(Close)(THIS_ LPCVOID pData);
	private:
		MMap<MString, MString> m_FileMap;
};

路径动画(样条线)

准备工作:给Aector加样条线组件(spline)

//.h
UCLASS()
class SIYIDA_API ARouteActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ARouteActor();
	USplineComponent* m_Line;
	/**
	 * @brief 获取当前位置
	 * @param temp 时间*速度
	 * @param v3 返回位置
	 * @param reverse 是否反向
	 */
	void GetPosition(float temp,FVector& v3,bool reverse);
	//获取旋转
	FRotator GetRotate(float temp);
	//是否完成
	bool IsFinish(float temp);
	
	UPROPERTY(EditAnywhere)
	float f_Length;  //样条线长度
    float temp;
protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

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

};
//.cpp
void ARouteActor::GetPosition(float temp,FVector& v3,bool reverse)
{
	if(reverse) temp=f_Length-temp;
	v3 = m_Line->GetLocationAtDistanceAlongSpline(temp, ESplineCoordinateSpace::World);
}

FRotator ARouteActor::GetRotate(float temp)
{
	return m_Line->GetRotationAtDistanceAlongSpline(temp, ESplineCoordinateSpace::Local);
}

bool ARouteActor::IsFinish(float temp)
{
	return (temp / f_Length) < 1.0f;
}

射线检测

float UCarrierComponent::Detection()
{
	FHitResult  hitResult(ForceInit);

	FVector beginPos = GetOwner()->GetActorLocation();
	FVector posEnd = beginPos -GetOwner()->GetActorUpVector()*1000.f;
	GetWorld()->LineTraceSingleByChannel(hitResult, beginPos, posEnd, ECC_WorldStatic);
	return hitResult.Distance;
}

加载并实例化物体

static AActor* LoadAndInstance(UObject* obj, FString path)
{
		UClass* tempa= LoadClass<AActor>(nullptr,path.operator*());
		if(tempa!=nullptr&&obj!=nullptr)
			return  obj->GetWorld()->SpawnActor(tempa);
		return nullptr;
}

UI-列出视图

item

必须要继承用户列表条目接口,才可以在列表里设置子项目。

列表

这是一个被封装的刷新函数

1.清除列表

2.遍历数组,并中断数组的目标元素--结构体

3.创建item

4.构建item的数据(一个普通类,里面有数据字段)

5.添加到列表里

bug(待解决)

每一个item都可以被点击,然后item里有一个文本的数字会增加。当item数量多了后往后面滑动,前面的item数据会被刷掉。

解决方案(2023/1/16)

在ItemData里多记录一个字段,当数据被点击操作改变的时候,把改变的数据也记录下来。

Unity与UE对比

这两个引擎的操作上没什么太大的区别,基本上unity上的大部分使用经验都可以在ue里使用,如果只使用蓝图不使用c++去做内容,甚至感觉ue还更简单一些,我基本能用c++去完成绝不使用蓝图的情况下

posted @   过往云烟吧  阅读(645)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示