当前位置: 首页 > article >正文

学习虚幻C++开发日志——基础案例(持续更新中)

官方文档:虚幻引擎C++编程教程 | 虚幻引擎 5.5 文档 | Epic Developer Community | Epic Developer Community

1.物体上下起伏并旋转 

1.1第一种写法

创建一个继承于Actor的类,并为新的Actor命名为FloatingActor,然后点击Create Class

重新加载代码文件

在Games->(用户自定义工程文件名)->Source->FloatingActor.h

在头文件添加代码

public:	
	// 设置构造默认函数
	AFloatingActor();

	UPROPERTY(VisibleAnywhere)
//使用继承于UObject的指针UStaticMeshComponent*
	UStaticMeshComponent* VisualMesh;

在源文件:

//设置默认值
AFloatingActor::AFloatingActor()
{
	//将设置为每帧调用Tick()。如果你不需要它,你可以关闭它来提高性能。
	PrimaryActorTick.bCanEverTick = true;

    //创建Object,可在蓝图details查看
	VisualMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
	VisualMesh->SetupAttachment(RootComponent);//根组件
	//根组件另一种写法:RootComponent = VisualMesh;
	
	//不推荐此写法
	//静态网格体Copy Reference:/Script/Engine.StaticMesh'/Game/StarterContent/Shapes/Shape_Cone.Shape_Cone'
	static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Cone.Shape_Cone"));

    //判断是否初始化成功
	if (CubeVisualAsset.Succeeded())
	{
		VisualMesh->SetStaticMesh(CubeVisualAsset.Object);
		VisualMesh->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
	}
}


void AFloatingActor::BeginPlay()
{
	Super::BeginPlay();
	//注意BeginPlay一定要调用Super::BeginPlay()
}


//调用每一帧
void AFloatingActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

    //初始化
	FVector NewLocation = GetActorLocation();
	FRotator NewRotation = GetActorRotation();
	float RunningTime = GetGameTimeSinceCreation();//得到在世界的时间从创建开始
	float DeltaHeight = (FMath::Sin(RunningTime + DeltaTime) - FMath::Sin(RunningTime));  //设置高度变化呈现正弦曲线变化
    float DeltaRotation = DeltaTime * 20.0f;	//Rotate by 20 degrees per second旋转变化	
    
    NewLocation.Z += DeltaHeight * 20.0f;       //高度变化,系数放大20倍
	NewRotation.Yaw += DeltaRotation;

	SetActorLocationAndRotation(NewLocation, NewRotation);
}

思路:在默认构造函数初始化网格体,运用引擎内置函数SetStaticMesh和SetRelativeLocation。在Tick时间函数内先初始化状态信息,并运用数学函数改变状态数值,最后用SetActorLocationAndRotation函数实现Actor位置变化。

1.2第二种写法(初始化网格体)

在上述头文件添加新的代码 :

public:
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Name")
	UStaticMesh* NewMesh;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FloatingActor")
	float FloatSpeed = 20.0f;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FloatingActor")
	float RotationSpeed = 20.0f;	

此写法是运用宏从而在蓝图进行快速修改 

从而不需要前一种方法默认构造函数的指定网格体的写法:

	//静态网格体Copy Reference:/Script/Engine.StaticMesh'/Game/StarterContent/Shapes/Shape_Cone.Shape_Cone'
	static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Cone.Shape_Cone"));

在源文件的BeginPlay()函数处代码:

void AFloatingActor::BeginPlay()
{
	Super::BeginPlay();
	//注意BeginPlay一定要调用Super::BeginPlay()

    //将原默认构造函数的判断放在这里
	if (NewMesh)
	{
		VisualMesh->SetStaticMesh(NewMesh);
		VisualMesh->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
	}
}

2.相机自动切换

2.1第一种自定义相机切换

创建一个继承于Actor的类,并为新的Actor命名为LearnGameCamera,然后点击Create Class

重新加载代码文件

在Games->(用户自定义工程文件名)->Source->LearnGameCamera.h

在头文件添加代码

protected:
	UPROPERTY(EditAnywhere, Category = "learn")
	AActor* CameraOne;

	UPROPERTY(EditAnywhere, Category = "learn")
	AActor* CameraTwo;

	float TimeToNextCameraChange=0.f;

使用宏可以在details进行相机绑定

在源文件的Tick()函数处代码(引用帧参数):

// Called every frame
void ALearnGameCamera::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	const float TimeBetweenCameraChanges = 2.0f;//硬编码写法
	const float SmoothBlendTime = 0.75f;// 视图混合平滑切换时间
	TimeToNextCameraChange -= DeltaTime;

	if (TimeToNextCameraChange <= 0.0f) 
	{
		TimeToNextCameraChange += TimeBetweenCameraChanges;

		//查找本地玩家控制的Actor
		APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0);
		if (OurPlayerController)
		{
            //视角不是摄像机1的视角且摄像机1不是空指针
			if((OurPlayerController->GetViewTarget()!=CameraOne)&&(CameraOne!=nullptr))
			{
				//立即切换到摄像机1
				OurPlayerController->SetViewTarget(CameraOne);
			}
			else if ((OurPlayerController->GetViewTarget() != CameraTwo) && (CameraTwo != nullptr))
			{
				//平滑切换到摄像机2
				OurPlayerController->SetViewTargetWithBlend(CameraTwo, SmoothBlendTime);
			}
		}
	}
}


http://www.kler.cn/a/375278.html

相关文章:

  • 某集团GIF动态验证码识别
  • 亚远景-SO 21434标准下的汽车网络安全:风险评估与管理的关键实践
  • 记录一个SVR学习
  • Java 优化springboot jar 内存 年轻代和老年代的比例 减少垃圾清理耗时 如调整 -XX:NewRatio
  • 鸿蒙Next之包体积极限优化
  • GitCode 光引计划投稿|JavaVision:引领全能视觉智能识别新纪元
  • SpringSecurity框架(入门)
  • PostgreSQL的奥秘:表结构、TOAST与大对象
  • 网络一些相关术语
  • axios 如何取消请求
  • 移植 AWTK 到 纯血鸿蒙(HarmonyOS NEXT)系统 (0) - 序
  • IP 欺骗以及其他常见网络攻击手段(附hping3的实际应用)
  • Qml-Gif的显示
  • 13 实战:使用Python和Pygame实现视频运动估计播放器
  • 二维legendre多项式
  • Oracle 第10章:触发器
  • 关于校验码的算法
  • 《向量数据库指南》——解锁GenAI生态系统新纪元
  • 面试题整理 2
  • 金蝶云星空与致远OA集成:简化审批流程,提升效率,确保数据一致性
  • SpringBoot实现zip压缩包下载
  • sprintf函数使用指南
  • 0.STM32F1移植到F0的各种经验总结
  • html中cookie如何存储
  • ChatGPT-o1在辅助论文参考文献写作中的表现如何?有哪些提升?
  • 整车功能架构 --- 智能座舱