Репликация инвентаря Unreal Engine 5 C++C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Репликация инвентаря Unreal Engine 5 C++

Сообщение Anonymous »

Я знаю, что существует множество систем взаимодействия с инвентарем, которые вы можете получить даже бесплатно, но я собираюсь сделать их самостоятельно, поскольку это первый раз, когда я пытаюсь воспроизвести, и я получаю проблема, которую я просто не могу решить самостоятельно. Раздражает то, что я потратил на это часы только из-за незнания, поэтому знайте, что мне нужна ваша помощь.
У меня есть персонаж по имени AOccultCharacter с сообществом ALS, пользовательским контроллером игрока и персонажем. У меня также есть класс pikcup, с которым я взаимодействую с InteractInterface.
Проблема здесь проста: инвентарь работает, у меня уже есть привязки клавиш для действий, массив инвентаря ( InventoryComponent ) и все работает на стороне сервера, я беру предмет, получаю правильные журналы отладки и отображаю инвентарь, метод уничтожения () работает на стороне клиента и даже репликацию движения.
Все начинает путаться, когда я попробуйте подключиться со стороны клиента.
Сначала у меня было такое сообщение об ошибке:
Warning: UNetDriver::ProcessRemoteFunction: No owning connection for actor BP_PickupBase_C_UAID_74563C4F12F87C3402_1553552231

Затем я использовал журнал, чтобы проверить пару вещей.
Pickup.cpp
if (PlayerCharacter)
{
UE_LOG(LogTemp, Warning, TEXT("Calling ServerTakePickup with: %s"), *PlayerCharacter->GetName());
ServerTakePickup(PlayerCharacter);
}

Это показало мне, что у обоих персонажей одинаковое имя, и я попытался изменить это, присвоив уникальное имя каждому созданному оккультному персонажу.
AOccultCharacter.cpp BeginPlay()
static int32 UniqueID = 1;
const FString UniqueName = FString::Printf(TEXT("OccultCharacter_%d"),
UniqueID++);
this->AActor::Rename(*UniqueName);

Это работало с разными именами персонажей, но возникла та же проблема.
Тогда я хотел исправить это, указав владельца классу Pickup.
void AOccultCharacter::BeginInteract()
{

PerformInteractionCheck();
if (InteractionData.CurrentInteractable)
{
if (IsValid(TargetInteractable.GetObject()))
{
TargetInteractable->BeginInteract();
if (FMath::IsNearlyZero(TargetInteractable->InteractableData.InteractionDuration, 0.1f))
{
InteractionData.CurrentInteractable->SetOwner(this);
Interact();

}
else
{
GetWorldTimerManager().SetTimer(
TimerHandleInteraction,
this,
&AOccultCharacter::Interact,
TargetInteractable->InteractableData.InteractionDuration,
false
);
}
}
}
}

Это остановило ошибку:

Предупреждение: UNetDriver::ProcessRemoteFunction: для актера BP_PickupBase_C_UAID_74563C4F12F87C3402_1553552231 нет соединения-владельца
p>

Но тем не менее, ни один предмет не был уничтожен и ни один предмет не добавлен в инвентарь, теперь я понятия не имею, что делать.
Здесь называется пикап:
APickup::Interact(AOccultCharacter PlayerCharacter)*
void APickup::Interact(AOccultCharacter* PlayerCharacter)
{

if (PlayerCharacter)
{
UE_LOG(LogTemp, Warning, TEXT("Interact called by %s"), *PlayerCharacter->GetName());

if (HasAuthority())
{
UE_LOG(LogTemp, Warning, TEXT("Has Authprity"));
TakePickup(PlayerCharacter);
}
else
{
if (!HasAuthority())
{
UE_LOG(LogTemp, Warning, TEXT("No Authority - trying to call ServerTakePickup"));
if (PlayerCharacter)
{
UE_LOG(LogTemp, Warning, TEXT("Calling ServerTakePickup with: %s"), *PlayerCharacter->GetName());
ServerTakePickup(PlayerCharacter);
}
else
{
UE_LOG(LogTemp, Warning, TEXT("PlayerCharacter is null!"));
}
}
}
}
else
{
// Log if the player character is null
UE_LOG(LogTemp, Warning, TEXT("Pickup:Interact Player Character is null!"));
}
}

Когда клиентская сторона вызывает Interact, он отправляет меня в ServerTakePickup(), и ничего не происходит. Тут даже логи вызываются, как будто всё останавливается.
void APickup::ServerTakePickup_Implementation(const AOccultCharacter* Taker)
{
UE_LOG(LogTemp, Warning, TEXT("ServerTakePickup_Implementation called with: %s"), Taker ? *Taker->GetName() : TEXT("null"));
if (!bIsPickedUp)
{
UE_LOG(LogTemp, Warning, TEXT("Is not picked up"));

bIsPickedUp = true;
MulticastOnPickup(Taker);
}
else
{
UE_LOG(LogTemp, Warning, TEXT("It has been picked up"));
}
}

bool APickup::ServerTakePickup_Validate(const AOccultCharacter* Taker)
{
UE_LOG(LogTemp, Warning, TEXT("ServerTakePickup_Validate called"));
return Taker != nullptr; // Ensure the player character is valid
}

У меня есть реплицированная true и функции под названием:
APickup::APickup()
{
PrimaryActorTick.bCanEverTick = false;
PickupMesh = CreateDefaultSubobject("Picup Mesh");
PickupMesh->SetSimulatePhysics(true);
PickupMesh->SetCollisionResponseToChannel(ECC_Pawn, ECR_Ignore);
SetRootComponent(PickupMesh);

//Replication Shit
bReplicates = true;
bIsPickedUp = false;

}

//===============================================================
// Replicaded neccessary Functions, properties and variables
//===============================================================

// Function to handle pickup logic
protected:
UFUNCTION(Server, Reliable, WithValidation)
void ServerTakePickup( const AOccultCharacter* Taker);

void ServerTakePickup_Implementation(const AOccultCharacter* Taker);
bool ServerTakePickup_Validate(const AOccultCharacter* Taker);

UFUNCTION(NetMulticast, Reliable)
void MulticastOnPickup(const AOccultCharacter* Taker);

void MulticastOnPickup_Implementation(const AOccultCharacter* Taker);
UFUNCTION()
void OnRep_PickedUp();

public:
UPROPERTY(ReplicatedUsing=OnRep_PickedUp)
bool bIsPickedUp;


Подробнее здесь: https://stackoverflow.com/questions/792 ... lication-c
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»