Метод, переопределенный в blueprint, не срабатывает. Как можно решить эту проблему?

У меня есть класс `Item`, который имеет следующую логику:

**.h файл:**
```cpp
#pragma once 

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

#include "Item.generated.h" 

UCLASS() 
class LEADOFF_API AItem : public AActor 
{ 
    GENERATED_BODY() 

public: 
    // Использовать предмет 
    UFUNCTION(/*BlueprintImplementableEvent*/ BlueprintNativeEvent, BlueprintCallable, Category = "Item") 
    void Use(); 

    UFUNCTION(BlueprintCallable, Category = "Item") 
    virtual void Use_Implementation(); 
}; 
```

**.cpp файл:**
```cpp
void AItem::Use_Implementation() { 
    UE_LOG(LogTemp, Warning, TEXT("Base use using")); 
} 
```

Также у меня есть наследник:

**.h файл:**
```cpp
#include "CoreMinimal.h" 
#include "Inventory/Item.h" 
#include "DroppedItem.generated.h" 

class LEADOFF_API ADroppedItem : public AItem 
{ 
    GENERATED_BODY() 

protected: 
    AItem* BodyUse; // Для использования

public: 
    void Use(); 

    virtual void Use_Implementation() override; 
}; 
```

**.cpp файл:**
```cpp
void ADroppedItem::Use_Implementation() { 
    Super::Use_Implementation(); 

    if (BodyUse) { 
        BodyUse->Use(); 
        //BodyUse(); 
        UE_LOG(LogTemp, Warning, TEXT("Good call BodyUse")); 
    } 
    else 
        UE_LOG(LogTemp, Warning, TEXT("BodyUse is nullptr")); 
} 
```

У меня также есть `InputAction`:
```cpp
UPROPERTY(EditAnywhere, Category = "EnhancedInput") 
UInputAction* UseAction; 
```

И я связываю его:
```cpp
Input->BindAction(UseAction, ETriggerEvent::Started, this, &ADroppedItem::Use);
```

Как правильно реализовать механизм использования предметов, учитывая данную структуру классов и взаимодействие с `InputAction`?
  • 5 сентября 2024 г. 11:32
Ответы на вопрос 2
Ваша проблема заключается в том, что вы используете метод `Use` в вашем классе `ADroppedItem`, но при этом он не переопределен в качестве `BlueprintImplementableEvent` в родительском классе `AItem`. Вместо этого у вас есть метод `Use_Implementation`, который был обозначен как `BlueprintNativeEvent`. 

Давайте рассмотрим, как это можно исправить, чтобы у вас была возможность правильно использовать метод в вашем `Blueprint`.

### Исправление:

1. **Переопределите метод `Use` в `ADroppedItem`** так, чтобы он вызывал базовую реализацию через `Use_Implementation`.

2. **Проверьте, что метод `BindAction` правильно связывает действие** с методом `Use`.

### Пример исправленного кода:

**В классе `ADroppedItem`:**

```cpp
// .h файл
class LEADOFF_API ADroppedItem : public AItem 
{ 
    GENERATED_BODY() 

protected: 
    AItem* BodyUse; // Для использования

public: 
    // Обратите внимание: добавляем BlueprintCallable
    UFUNCTION(BlueprintCallable, Category = "Item")
    virtual void Use() override; 

    virtual void Use_Implementation() override; 
};

// .cpp файл
void ADroppedItem::Use() {
    // Вызываем реализацию, если необходимо
    Use_Implementation();
}

void ADroppedItem::Use_Implementation() { 
    Super::Use_Implementation(); 

    if (BodyUse) { 
        BodyUse->Use(); 
        UE_LOG(LogTemp, Warning, TEXT("Good call BodyUse")); 
    } 
    else {
        UE_LOG(LogTemp, Warning, TEXT("BodyUse is nullptr")); 
    } 
}
```

### Правильная настройка связки с `InputAction`:

Убедитесь, что связывание `InputAction` происходит корректно. Например:

```cpp
// В классе, где вы можете получить доступ к входным данным
Input->BindAction(UseAction, ETriggerEvent::Started, this, &ADroppedItem::Use);
```

### Этапы проверки:

1. Убедитесь, что ваш `InputAction` настроен правильно в `Input Settings`.
2. Проверьте, не забыли ли вы добавить `BodyUse` объект в `ADroppedItem`. Это может быть сделано в `BeginPlay` или другим образом.
3. Убедитесь, что `ADroppedItem` действительно используется в игре, а не его базовый класс `AItem`.

### Причины, по которым ваш метод может не срабатывать:

- Метод `Use` в `ADroppedItem` не привязан или не вызывается.
- Убедитесь, что экземпляр `ADroppedItem` находится в вашей сцене.
- Если `BodyUse` не был инициализирован (то есть `nullptr`), метод `Use_Implementation` не вызовет `BodyUse->Use()`.

### Подведем итог:

Следуя вышеизложенным рекомендациям, вы сможете правильно реализовать механизм использования предметов в вашей игре. Переопределение метода `Use` в производном классе и вызов `Use_Implementation` позволит вам использовать наследуемую логику из базового класса, сохраняя возможность расширять ее в производных классах.
По моему, код должен иметь такой вид в .h файле родительского класса. 
UFUNCTION(BlueprintNativeEvent)
	virtual void Use();
	virtual void Use_Implementation();
Похожие вопросы