【问题标题】:Crash when trying to change the TargetArmLength (Unreal Engine C++)尝试更改 TargetArmLength 时崩溃(虚幻引擎 C++)
【发布时间】:2021-11-04 10:29:18
【问题描述】:

每当我尝试更改 SpringArmComponent->TargetArmLength 时,它都会崩溃, 即使我这样做:UE_LOG(LogTemp, Warning, TEXT("%f"), SpringArmComponent->TargetArmLength);

我做错了什么?

它在ZoomIn()ZoomOut() 函数中崩溃,但它在构造函数中有效。如果我只做SpringArmComponent->TargetArmLength 它不会崩溃,但如果我尝试记录它就会崩溃。

.h 文件片段:

class UCameraComponent;
class USpringArmComponent;

UCLASS()
class WELT_API ATPWBaseCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true"))
    UCameraComponent* CameraComponent;

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true"))
    USpringArmComponent* SpringArmComponent;

public:
    // Sets default values for this character's properties
    ATPWBaseCharacter(const FObjectInitializer& ObjInit);

protected:
    virtual void BeginPlay() override;

public: 
    virtual void Tick(float DeltaTime) override;

    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

    UFUNCTION(BlueprintCallable, Category = "Movement")
    bool IsRunning() const;

private:
    bool WantsToRun = false;
    bool IsMovingForward = false;

    void MoveForward(float Amount);
    void MoveRight(float Amount);

    void OnStartRunning();
    void OnStopRunning();

    void LookUp(float Amount);
    void TurnAround(float Amount);
    
    void ChangeCameraLen(bool bAmount);

public:
    UFUNCTION(BlueprintCallable, Category = "Movement")
    void ZoomIn();
    UFUNCTION(BlueprintCallable, Category = "Movement")
    void ZoomOut();
};

.cpp 文件片段:

ATPWBaseCharacter::ATPWBaseCharacter(const FObjectInitializer& ObjInit) : 
    Super(ObjInit.SetDefaultSubobjectClass<UTPWCharacterMovementComponent>(ACharacter::CharacterMovementComponentName))
{
    PrimaryActorTick.bCanEverTick = true;

    SpringArmComponent = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComponent"));
    SpringArmComponent->SetupAttachment(GetRootComponent());
    // SpringArmComponent->SocketOffset.Set(0, 0, 80);
    SpringArmComponent->TargetArmLength = 400.0f;
    SpringArmComponent->bUsePawnControlRotation = true;

    CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));
    CameraComponent->SetupAttachment(SpringArmComponent, USpringArmComponent::SocketName);
    CameraComponent->bUsePawnControlRotation = false;

    bUseControllerRotationPitch = false;
    bUseControllerRotationYaw = false;
    bUseControllerRotationRoll = false;
}
void ATPWBaseCharacter::BeginPlay()
{
    Super::BeginPlay();
}
void ATPWBaseCharacter::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    // AddActorLocalRotation(QuatRotation, false, 0, ETeleportType::None);
    FRotator NewRotationVector = FRotator(0.0f, GetVelocity().Rotation().Yaw, 0.0f);    // pitch, yaw, roll
    if (!NewRotationVector.IsZero())
    {
        FRotator NewRotation = FRotator(NewRotationVector);
        FQuat QuatRotation = FQuat(NewRotation);
        SetActorRotation(QuatRotation, ETeleportType::None);
    }
}
void ATPWBaseCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

    PlayerInputComponent->BindAxis("MoveForward", this, &ATPWBaseCharacter::MoveForward);
    PlayerInputComponent->BindAxis("MoveRight", this, &ATPWBaseCharacter::MoveRight);
    PlayerInputComponent->BindAxis("LookUp", this, &ATPWBaseCharacter::LookUp);
    PlayerInputComponent->BindAxis("TurnAround", this, &ATPWBaseCharacter::TurnAround);

    PlayerInputComponent->BindAction("WheelUp", IE_Pressed, this, &ATPWBaseCharacter::ZoomIn);
    PlayerInputComponent->BindAction("WheelDown", IE_Pressed, this, &ATPWBaseCharacter::ZoomOut);

    PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ATPWBaseCharacter::Jump);
    PlayerInputComponent->BindAction("Run", IE_Pressed, this, &ATPWBaseCharacter::OnStartRunning);
    PlayerInputComponent->BindAction("Run", IE_Released, this, &ATPWBaseCharacter::OnStopRunning);
}

void ATPWBaseCharacter::MoveForward(float Amount)
{
    IsMovingForward = Amount > 0.0f;
    // AddMovementInput(GetActorForwardVector(), Amount);
    if ((Controller != nullptr) && (Amount != 0.0f))
    {
        const FRotator Rotation = Controller->GetControlRotation();
        const FRotator YawRotation(0, Rotation.Yaw, 0);
        const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
        AddMovementInput(Direction, Amount);
    }
}

void ATPWBaseCharacter::MoveRight(float Amount)
{
    // AddMovementInput(GetActorRightVector(), Amount);
    if ((Controller != nullptr) && (Amount != 0.0f))

        const FRotator Rotation = Controller->GetControlRotation();
        const FRotator YawRotation(0, Rotation.Yaw, 0);
        const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
        AddMovementInput(Direction, Amount);
    }
}

void ATPWBaseCharacter::LookUp(float Amount)
{
    AddControllerPitchInput(Amount);
}

void ATPWBaseCharacter::TurnAround(float Amount)
{
    AddControllerYawInput(Amount);
}

void ATPWBaseCharacter::OnStartRunning()
{
    WantsToRun = true;
}
void ATPWBaseCharacter::OnStopRunning()
{
    WantsToRun = false;
}

void ATPWBaseCharacter::ZoomIn()
{
    // SpringArmComponent->TargetArmLength;
    UE_LOG(LogTemp, Warning, TEXT("%f"), SpringArmComponent->TargetArmLength);
    SpringArmComponent->TargetArmLength = 200.0f;
    // UE_LOG(LogTemp, Warning, TEXT("%f"), SpringArmComponent->TargetArmLength);
    // SpringArmComponent->SocketOffset = FVector(0, 0, 80);
}

void ATPWBaseCharacter::ZoomOut()
{
    // SpringArmComponent->TargetArmLength;
    UE_LOG(LogTemp, Warning, TEXT("%f"), SpringArmComponent->TargetArmLength);
    
    SpringArmComponent->SocketOffset = FVector(0, 0, 80);
}

【问题讨论】:

  • 您是否尝试过调试(使用可能作为虚幻引擎 4 的内置功能提供的调试器)代码并查看它在崩溃时会抛出什么消息?
  • @Jejo 谢谢,但如果它为空,为什么?
  • LogTemp 在哪里定义?您确定是SpringArmComponent 导致了崩溃吗,可以是LogTemp 吗?
  • @Jejo 我已经完成了这个if (SpringArmComponent-&gt;IsValidLowLevel()) { UE_LOG(LogTemp, Warning, TEXT("%f"), SpringArmComponent-&gt;TargetArmLength); } 并且它不会崩溃,因为它无效,但是为什么

标签: c++ unreal-engine4 unreal-blueprint


【解决方案1】:

您是否有可能在派生自此类的蓝图 act​​or 中运行它?如果是这样,我注意到这可能会导致组件创建出现问题,并会导致引擎崩溃并为正在正确设置的组件返回 NULL。

我建议也许尝试创建一个新的派生类,看看是否可行。我知道这是一个奇怪的建议,但它对我有用。

【讨论】:

  • 成功了!谢谢!
猜你喜欢
  • 2019-06-18
  • 2020-07-24
  • 2017-09-20
  • 2017-09-10
  • 2020-06-02
  • 1970-01-01
  • 2020-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多