UE5.1.1C++从0开始(9.游戏材质相关)

文章讨论了一种游戏开发中的情况,其中大部分内容使用蓝图实现,尤其是材质相关部分,因为相比C++更方便。一个名为STargetDummy的C++类被用于创建立方体对象,包含静态网格组件和属性组件。当健康值改变时,会触发一个受击函数OnHealthChanged。在游戏开始时,立方体会因时间戳的即时变化而闪烁,这是一个bug。通过调整TimeToHit参数在材质内的值,问题得到了解决。
摘要由CSDN通过智能技术生成

这一个章节蓝图占大多数,毕竟是材质相关的内容,用蓝图确实会比C++方便不少,这一块唯一一个C++的内容就是新写的一个cube的类。

STargetDummy.h

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "STargetDummy.generated.h"

UCLASS()
class ACTIONROGUELIKE_API ASTargetDummy : public AActor
{
	GENERATED_BODY()
	
	UPROPERTY(VisibleAnywhere)
	class UStaticMeshComponent* StaticMeshComp;

	UPROPERTY()
	class USAttributeComponent* AttributeComp;

public:	
	// Sets default values for this actor's properties
	ASTargetDummy();

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

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;
	
    //绑定的受击函数
	UFUNCTION()
	void OnHealthChanged(AActor*InstigatorActor , USAttributeComponent* OwningComp, float NewHealth, float Delta);

};

STargetDummy.cpp

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


#include "STargetDummy.h"
#include "Components/StaticMeshComponent.h"
#include "SAttributeComponent.h"

// Sets default values
ASTargetDummy::ASTargetDummy()
{
 	// 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;

	StaticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh Comp"));

	AttributeComp = CreateDefaultSubobject<USAttributeComponent>(TEXT("Attribute Comp"));
	AttributeComp->OnHealthChanged.AddDynamic(this,&ASTargetDummy::OnHealthChanged);

}

// Called when the game starts or when spawned
void ASTargetDummy::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void ASTargetDummy::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

//函数实现
void ASTargetDummy::OnHealthChanged(AActor* InstigatorActor, USAttributeComponent* OwningComp, float NewHealth, float Delta)
{

	if (Delta<0.0f)
	{
		StaticMeshComp->SetScalarParameterValueOnMaterials("TimeToHit", GetWorld()->TimeSeconds);
	}
}


不过我有个疑问,用老师的这个方法,在刚进入游戏的时候我们的cube就会闪一下,这明显是一个bug,我在蓝图内尝试靠更改TimeToHit的值来解决这个问题,也就是在我们的自定义材质函数内修改值来解决bug,问题也解决了。

对不起,我的回答中有误。在UE5.1.1中,uperarm_r的旋转坐标是由四个值构成的,分别是Roll、Pitch、Yaw和W。因此,需要将mediapipe的坐标系转换为UE5.1.1的左手坐标系,然后计算uperarm_r的四元数值,最后将四元数值赋给uperarm_r的旋转坐标。 具体的计算方法如下: 1. 将mediapipe的坐标系转换为UE5.1.1的左手坐标系。具体来说,需要将y坐标和z坐标取负,即将(0.546142, 0.315784, -0.148612)转换为(0.546142, -0.315784, 0.148612)。 2. 计算uperarm_r的旋转四元数值。具体来说,可以使用UE5.1.1中的FQuat::FindBetweenVectors函数来计算uperarm_r的方向向量和转换后的坐标的四元数值。具体的计算方法如下: ``` FVector ShoulderPos(0.546142, -0.315784, 0.148612); // 转换后的坐标 FVector UperarmDir(1.0f, 0.0f, 0.0f); // uperarm_r的方向向量 FQuat UperarmQuat = FQuat::FindBetweenVectors(UperarmDir, ShoulderPos.GetSafeNormal()); ``` 3. 将计算得到的uperarm_r的四元数值赋给uperarm_r的旋转坐标。具体来说,需要使用UE5.1.1中的USkeletalMeshComponent::SetBoneRotationByName函数来设置uperarm_r的旋转坐标。具体的代码如下: ``` USkeletalMeshComponent* SkeletalMeshComponent; // 需要替换成实际的SkeletalMeshComponent SkeletalMeshComponent->SetBoneRotationByName(TEXT("uperarm_r"), UperarmQuat, EBoneSpaces::WorldSpace); ``` 需要注意的是,以上计算过程中需要考虑坐标系的转换和旋转角度的顺序等因素,因此具体的计算方法可能会有所不同。建议在实际使用过程中,根据具体的需求和场景进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楚江_wog1st

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值