学习 U++ Day01

基础部分01

debug文本输出

	if (GEngine)
    {
        GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("游戏开始了")); //输出到屏幕上
    }
	UE_LOG(LogTemp, Warning, TEXT("游戏开始了"));

PS. 调试工具的使用,一定注意这个GEngine使用的时候一定要包含这个“GEgine.h”头文件

void AItem::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime); // 两帧之间的距离值

}

PS.重点谈及这个Tick函数的使用,deltatime是两帧之间的时间差,30帧/s要比60帧/s的值要大,因此可以用来控制一个玩家在一秒内移动的距离固定。一帧时间差距大则移动的距离就长,相反就短。

	FString Name = GetName(); // 返回对象的名字
	FString Message = FString::Printf(TEXT("两帧时间差:%f"),DeltaTime); // Printf格式化的一种方式
	//UE_LOG(LogTemp,Warning,TEXT("两帧时间差:%f"),DeltaTime); // 控制台打印
	UE_LOG(LogTemp,Warning,TEXT("%s"),*Name);
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, Message); // 屏幕上打印
	}

Fstring使用

PS. 使用 %s 参数包含 FStrings 时,必须使用 * 运算符返回 %s 参数所需的 TCHAR * 。

在Unreal Engine中,当你需要将FString转换为const TCHAR*类型时,你应该在FString变量前加上 * 。这通常在以下情况下需要:

  1. 当你需要将FString作为参数传递给期望const TCHAR*类型参数的函数时,如UE_LOG。
  2. 当你需要将FString与TEXT宏(它生成const TCHAR类型的字符串)一起使用时。
    例如,以下代码将FString转换为const TCHAR
    ,然后将其传递给UE_LOG函数:
FString MyString = "Hello, world!";
UE_LOG(LogTemp, Warning, TEXT("%s"), *MyString);

debug球体、线或者点

#define THIRTY 30
// 定义一个宏用来绘制调试球体
#define DRAW_SPHERE(Location) if (GetWorld()) DrawDebugSphere(GetWorld(),Location,25.f,12,FColor::Red,true);

PS.用宏进行一个绘制球体的预先定义,以后在进行调用时候更加简单。如果希望在其他的类中也能用这个宏呢?采用的办法是将宏定义在项目的.h文件中,然后其他类进行包含即可

	// 绘制一条黑色的调试线在当前物体的正前方向上
	// 获取当前物体的位置和前方向
	FVector StartLocation = GetActorLocation();
	FVector ForwardVector = GetActorForwardVector();
	// 计算结束位置,这里我们让线尽可能长,例如10000单位长度
	FVector EndLocation = StartLocation + ForwardVector * 10000;
	// 绘制黑色的调试线
	DrawDebugLine(GetWorld(), StartLocation, EndLocation, FColor::Black, true, 1.f);
// 绘制调试球体
#define DRAW_SPHERE(Location) if (GetWorld()) DrawDebugSphere(GetWorld(),Location,25.f,12,FColor::Red,true)
// 绘制调试线
#define DRAW_LINE(StartLocation,EndLocation) if (GetWorld()) DrawDebugLine(GetWorld(), StartLocation, EndLocation, FColor::Black, true, 1.f);
// 绘制调试点
#define DRAW_POINT(Location) if(GetWorld()) DrawDebugPoint(GetWorld(),Location,5,FColor::Blue,true,-1.f);
// 绘制向量
#define DRAW_VECTOR(StartLocation, EndLocation) \
if(GetWorld()) \
{ \
    DrawDebugLine(GetWorld(), StartLocation, EndLocation, FColor::Red, true, 1.f); \
    DrawDebugPoint(GetWorld(), EndLocation, 5, FColor::Black, true, -1.f); \
}

PS.所有的宏的定义如上所示。为了更好地进行模块化管理,可以通过另外新建立一个头文件,将所有的宏都放在这个宏文件中即可

公开变量到蓝图

在Unreal Engine 4中,你可以通过以下几种方式将C++变量公开到蓝图:

  1. 使用UPROPERTY宏:你可以使用UPROPERTY宏来公开C++变量。这个宏有很多标志可以用来控制变量的行为。例如,如果你想让一个变量在蓝图中可见并且可以编辑,你可以这样做:

UPROPERTY(BlueprintReadWrite, EditAnywhere) int32 MyVariable;

  1. 使用BlueprintCallable和BlueprintPure:你可以使用这两个宏来创建可以在蓝图中调用的函数。BlueprintCallable用于那些有副作用的函数,而BlueprintPure用于那些没有副作用的函数。例如:
UFUNCTION(BlueprintCallable, Category = "MyCategory")
void MyFunction();
UFUNCTION(BlueprintPure, Category = "MyCategory")
int32 MyPureFunction() const;
  1. 使用BlueprintImplementableEvent和BlueprintNativeEvent:这两个宏可以用来创建在蓝图中可以重写的函数。BlueprintImplementableEvent只能在蓝图中重写,而BlueprintNativeEvent可以在C++和蓝图中都重写。例如:
UFUNCTION(BlueprintImplementableEvent, Category = "MyCategory")
void MyBlueprintImplementableEvent();

UFUNCTION(BlueprintNativeEvent, Category = "MyCategory")
void MyBlueprintNativeEvent();

请注意,所有这些宏都需要在类的公有部分使用,并且类需要继承自UObject或其子类。

  1. EditAnywhere:允许在属性窗口中的任何地方修改属性值。
  2. BlueprintReadOnly:允许在蓝图中读取属性,但不能修改。
  3. BlueprintReadWrite:允许在蓝图中读取和修改属性。
  4. VisibleAnywhere:在属性窗口中可见,但不能修改。
  5. VisibleDefaultsOnly:只在默认属性窗口中可见。
  6. VisibleInstanceOnly:只在实例属性窗口中可见。
  7. EditDefaultsOnly:只在默认属性窗口中可编辑。
  8. EditInstanceOnly:只在实例属性窗口中可编辑。
  9. Category=“CategoryName”:在属性窗口中,该属性将出现在指定的类别下。
  10. Meta = (ClampMin = “0.0”, ClampMax = “1.0”):为属性设置元数据,例如最小和最大值。

实例属性窗口
实例属性窗口
默认属性窗口
默认属性窗口
蓝图界面窗口
蓝图界面窗口

PS.想让一个私有变量,能够在蓝图中可读写要加上下边的代码

UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="ControlPlay",meta=(AllowPrivateAccess="true"))

函数的参数标记

Unreal中对于函数的标记如下
UFUNCTION宏用于标记C++函数,使其可以在Unreal Engine的其他部分(如蓝图)中使用。以下是一些常用的UFUNCTION标记:

  1. BlueprintCallable:这个函数可以在蓝图中被调用。
  2. BlueprintPure:这是一个没有副作用的函数,可以在蓝图中被调用。在蓝图中,这种函数的节点没有执行引脚。
  3. BlueprintImplementableEvent:这是一个在蓝图中可以被重写的函数。在C++中,这个函数没有实现。
  4. BlueprintNativeEvent:这是一个在蓝图中可以被重写的函数。在C++中,这个函数有一个默认的实现。
  5. Category=“CategoryName”:在蓝图中,这个函数将出现在指定的类别下。
  6. Server,Client,NetMulticast:这些标记用于网络复制。Server函数只在服务器上运行,Client函数只在客户端上运行,NetMulticast函数在所有连接的客户端上运行。
  7. Reliable,Unreliable:这些标记用于网络复制。Reliable函数总是被发送,而Unreliable函数只在网络带宽允许的情况下被发送。

PS.最关键的两个:BlueprintImplementableEvent:这是一个在蓝图中可以被重写的函数。在C++中,这个函数没有实现。BlueprintNativeEvent:这是一个在蓝图中可以被重写的函数。在C++中,这个函数有一个默认的实现。
针对blueprintNativeEvent的实现步骤:

  1. 在类定义中,使用UFUNCTION(BlueprintNativeEvent, Category=“YourCategory”)宏来声明你的函数。例如:
UFUNCTION(BlueprintNativeEvent, Category="NativeImp")
void OutTest();
  1. 在类定义中,添加一个名为FunctionName_Implementation()的函数,其中FunctionName是你在步骤1中声明的函数名。例如:
virtual void OutTest_Implementation();
  1. 在你的.cpp文件中,实现FunctionName_Implementation()函数。这个函数将作为默认的实现,如果在蓝图中没有覆盖这个函数,那么就会调用这个默认实现。
void AItem::OutTest_Implementation()
{
    // 默认实现
}

在蓝图中使用BlueprintNativeEvent的步骤如下:

  1. 在蓝图编辑器中,右键点击并选择“添加覆盖函数”。
  2. 在弹出的列表中,选择你在C++中定义的BlueprintNativeEvent函数。
  3. 在新创建的函数节点中,添加你的蓝图逻辑。

注意,如果你在蓝图中覆盖了BlueprintNativeEvent函数,那么C++中的FunctionName_Implementation()函数将不会被调用,除非你在蓝图中显式地调用它。


模板函数

希望:输入的不仅有参数,还有类型
具体实现步骤:

  1. 声明模板函数:
	template<typename T>
	T max(T a,T b);
  1. 实现模板函数
template <typename T>
T AItem::max(T a, T b)
{
	return a>b?a:b;
}
  1. 调用模板函数
max<float>(5.f,6.2f)
StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMeshComponent"));

组件

actor可以添加组件,默认的actor有一个场景组件。

在Unreal Engine中,最常用的组件包括以下几种:

  1. UStaticMeshComponent:这是用于显示静态3D模型的组件。

  2. USkeletalMeshComponent:这是用于显示和控制带有骨骼动画的3D模型的组件。

  3. UCameraComponent:这是用于创建和控制游戏中的摄像机的组件。

  4. UCharacterMovementComponent:这是用于控制角色移动的组件,包括跑步、跳跃、游泳等。

  5. UParticleSystemComponent:这是用于创建和控制粒子系统的组件,如火、烟、雾等效果。

  6. UAudioComponent:这是用于播放和控制游戏中的音频的组件。

  7. UBoxComponent、USphereComponent、UCapsuleComponent:这些是用于创建和控制碰撞体的组件。

  8. USceneComponent:这是所有组件的基类,它包含了位置、旋转和缩放等基本属性。

  9. UInputComponent:这是用于处理用户输入的组件,如键盘、鼠标和触摸输入。

  10. UWidgetComponent:这是用于在3D空间中显示2D UI元素的组件。

使用C++创建组件的步骤

  1. 声明
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
	UStaticMeshComponent* StaticMeshComponent;
  1. 初始化,在构造函数
	 //创建静态网格体组件并附着在默认的场景组件上
StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMeshComponent"));
RootComponent = StaticMeshComponent;

一些题目考察

根据你昨天做的笔记,我为你出了以下几个题目,希望能帮助你复习:

  • 什么是GEngine,它的作用是什么?它需要包含哪个头文件?
  • Tick函数的参数deltatime表示什么?它可以用来做什么?
  • 如果要将FString转换为const TCHAR*类型,应该在FString变量前加上什么运算符?¹[1]
  • 宏定义可以用来做什么?宏定义应该放在哪个文件中?
  • UPROPERTY宏有哪些常用的标志?它们的含义是什么?
  • BlueprintPure和BlueprintCallable有什么区别?
  • BlueprintImplementableEvent和BlueprintNativeEvent有什么区别?如果要在C++中实现一个BlueprintNativeEvent函数,应该怎么做?
  • 什么是actor?actor可以添加哪些组件?举例说明。
  • UCharacterMovementComponent、UParticleSystemComponent、UBoxComponent等组件的作用是什么?
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值