【问题标题】:UE4.9 C++ Puzzle Block AddressingUE4.9 C++ 拼图块寻址
【发布时间】:2015-09-09 15:46:59
【问题描述】:

在 UE4 中,我正在我的 Graphics 2 课程中制作 Puzzle Block 游戏。我们的教授和我们的班级正在一起学习 UE4。整个班级对 C++ 代码中的一件事感到有些困惑,我的教授说他会尝试自己找出答案,但我想我会用我在这里找到的信息开始我们的下一堂课。

好的,在 BlockGrid.cpp 文件中,这部分代码用于创建块。

void AMyProject2BlockGrid::BeginPlay()
{
   Super::BeginPlay();

   // Number of blocks
   const int32 NumBlocks = Size * Size;

   // Loop to spawn each block
   for(int32 BlockIndex=0; BlockIndex<NumBlocks; BlockIndex++)
   {
      const float XOffset = (BlockIndex/Size) * BlockSpacing; // Divide by dimension
      const float YOffset = (BlockIndex%Size) * BlockSpacing; // Modulo gives remainder

      // Make postion vector, offset from Grid location
      const FVector BlockLocation = FVector(XOffset, YOffset, 0.f) + GetActorLocation();

      // Spawn a block
      AMyProject2Block* NewBlock = GetWorld()->SpawnActor<AMyProject2Block>(BlockLocation, FRotator(0,0,0));

      // Tell the block about its owner
      if(NewBlock != NULL)
      {
          NewBlock->OwningGrid = this;
      }
   }
}

混淆始于此函数中的以下行:

AMyProject2Block* NewBlock = GetWorld()->SpawnActor<AMyProject2Block>(BlockLocation, FRotator(0,0,0));

每次看起来它都在为拼图中的每个新块重写 NewBlock。我们的问题是我们正在创建的游戏,即Lights Out game,如果 NewBlock 不断被重写,那么它如何跟踪屏幕上显示的块的信息地址?这可以通过简单地创建一个数组来存储信息来解决,但是如果信息仍然保存在某个地方,这将是低效的。那么,如果 NewBlock 被每个循环覆盖,我们如何访问块的信息,而不用创建一个数组来低效地存储数据呢?

谢谢!!!! :)

【问题讨论】:

  • 注意:我不知道 UE4 的任何细节。根据上面的代码(我猜这是其他地方的样板),世界(来自GetWorld())保持对生成的Actor的引用,所以NewBlock指针就在那里,所以OwningGrid字段可以是放。任何进一步访问世界上的 Actor 都必须通过另一种方式找到该引用。 (例如:answers.unrealengine.com/questions/16805/…)。请注意,保留指针数组并不是低效的,虽然我不知道 UE4 保留 Actor 指针的策略。

标签: c++ memory-address unreal-engine4


【解决方案1】:

@Mathew 的评论有正确的想法,当您使用 SpawnActor 时,虚幻引擎会在幕后做很多事情,但本质上是在世界中创建您的演员并管理其生命周期。 (例如,要从关卡中移除您的演员,您需要使用:

MyActor->Destroy();

而不是C++方法:

delete PtrToActor;

这会在实际删除 actor 之前将其从场景中移除、更新碰撞体积等。

对于您的代码,您当然会覆盖指向块的指针,因此块本身不会受到影响。您可以使用TActorIterator&lt;T&gt; iterable 循环遍历所有类型的参与者,这样您就不必自己存储数组。你会做这样的事情:

for (TActorIterator<AMyProject2Block> ActorItr(GetWorld()); ActorItr; ++ActorItr )
{
     AMyProject2Block* PtrToActor = *ActorItr;
}

PtrToActor 将随着循环的进行依次指向每个实例。

但是,存储您自己的单独的指针数组并不是真正的低效(而且在许多情况下是有效的)。这只是很小的内存成本(因为它只是指针)并且可能会更快,因为您不必过滤演员来找到您想要的演员。在任何一种情况下,它都非常重要,因此您应该选择感觉更合乎逻辑的那个。

在您的示例中,我会将它们保存在 2D 数据结构中,以便您可以通过它们的位置访问它们,而不仅仅是从引擎中获取它们的无序列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多