Почему я не могу вызвать onFire (); - PullRequest
0 голосов
/ 30 января 2020

Я пытаюсь реализовать стрельбу из оружия в моей игре!

Моя цепочка наследования выглядит следующим образом:

ACharacter -> AMainCharacter

AActor -> AWeapon -> ALaserGun

Я пытаюсь вызвать функцию в классе ALaserGun, но по какой-то причине Weapon не относится к типу ALaserGun. Как я могу использовать SpawnActor<>() для создания актера того же типа, что и WeaponAtSpawnClass, если я устанавливаю WeaponAtSpawnClass в проекте? Прямо сейчас я порождаю AWeapon актера. Я хочу породить ребенка AWeapon с OnFire(). Тип Weapon, являющийся классом, хранящимся в WeaponAtSpawnClass.

Некоторые отмеченные мной причины могут вызывать проблему:

Weapon в MainCharacter.h имеет введите AWeapon*

SpawnActor<>() в качестве основного символа. cpp использует AWeapon в качестве порожденного типа.

Должен ли я изменить AWeapon в этих выражениях на что-то другое?

Вот мой код:

MainCharacter.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MainCharacter.generated.h"

class AWeapon;

UCLASS()
class TEST_API AMainCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    AWeapon* Weapon;

    UPROPERTY(EditAnywhere)
    TSubclassOf<AWeapon> WeaponAtSpawnClass;

    void OnFire();

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

public: 
    // Called to bind functionality to input
    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

MainCharacter. cpp

#include "MainCharacter.h"
#include "Weapon.h"

// Called when the game starts or when spawned
void AMainCharacter::BeginPlay()
{
    Super::BeginPlay();
    Weapon = GetWorld()->SpawnActor<AWeapon>(WeaponAtSpawnClass);
}

void AMainCharacter::OnFire()
{
    Weapon->OnFire();
}

// Called to bind functionality to input
void AMainCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

    PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &AMainCharacter::OnFire);
}

Weapon.h

#pragma once

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

UCLASS()
class TEST_API AWeapon : public AActor
{
    GENERATED_BODY()

};

В оружии нет кода. cpp

LaserGun.h

#pragma once

#include "CoreMinimal.h"
#include "Weapon.h"
#include "LaserGun.generated.h"

UCLASS()
class TEST_API ALaserGun : public AWeapon
{
    GENERATED_BODY()

public:

    void OnFire();
};

LaserGun. cpp

#include "LaserGun.h"

void ALaserGun::OnFire()
{
    UE_LOG(LogTemp, Warning, TEXT("Gun fired"))
}

1 Ответ

3 голосов
/ 30 января 2020

AWeapon* Weapon; объявляет указатель на любой AWeapon. Откуда компилятору знать, что он указывает на экземпляр класса, у которого есть какой-то определенный c метод?

Конечно, вы можете начать приводить Weapon к ALaserGun, но это приведет к бардак. Лучшая альтернатива - объявить метод в интерфейсе AWeapon:

UCLASS()
class TEST_API AWeapon : public AActor
{
    GENERATED_BODY()
 public:  
    virtual OnFire() = 0;
};

И для хорошего стиля объявить, что вы переопределите этот метод:

UCLASS()
class TEST_API ALaserGun : public AWeapon
{
    GENERATED_BODY()

public:
    void OnFire() override;
};

Именование имеет Конечно, до вас, например, если не каждое оружие может стрелять, назовите метод OnAttack или что-то еще, затем вызовите OnFire из OnAttack или что-то в этом роде.

...