2015-09-09 2 views
0

Dans UE4, je travaille sur un jeu Puzzle Block dans ma classe Graphics 2. Notre professeur et notre classe apprennent ensemble sur UE4. Notre classe dans son ensemble est un peu confuse à propos d'une chose dans le code C++ et mon professeur a dit qu'il essaierait de trouver la réponse lui-même, mais je me suis dit que je commencerais notre prochain cours avec les informations que je trouve ici. Ok, dans le fichier BlockGrid.cpp, cette section de code est utilisée pour créer les blocs.UE4.9 C++ Puzzle Block Addressing

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; 
     } 
    } 
} 

La confusion commence par la ligne suivante dans cette fonction:

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

A chaque fois on dirait qu'il est en train de réécrire newblock pour chaque nouveau bloc dans le puzzle. Notre problème concerne le jeu que nous sommes en train de créer, c'est-à-dire Lights Out game, si NewBlock est en cours de réécriture, alors comment est-ce qu'il garde la trace des adresses pour les informations qui sont affichées à l'écran? Cela pourrait être résolu en créant simplement un tableau pour stocker l'information, mais si l'information est toujours conservée quelque part, ce serait inefficace. Alors, comment pouvons-nous accéder à l'information pour les blocs si NewBlock est écrasé avec chaque boucle sans faire un tableau pour stocker inefficacement les données?

MERCI !!!! :)

+0

Note: Je ne connais pas de détails sur UE4. Basé sur le code ci-dessus (que j'imagine que c'est d'ailleurs), le monde (de 'GetWorld()') garde une référence à l'acteur engendré, ainsi le pointeur 'NewBlock' est là juste le champ' OwningGrid' peut être mis en place. Tout autre accès aux Acteurs dans le monde devrait trouver cette référence par un autre moyen. (Voir, par exemple: https://answers.unrealengine.com/questions/16805/c-find-specific-actor-in-scene.html).Notez que garder un tableau de pointeurs n'est pas inefficace, bien que je ne connaisse pas la politique de l'UE4 pour garder les pointeurs Actor. –

Répondre

0

@ Le commentaire de Mathew a la bonne idée, quand vous utilisez SpawnActor, Unreal fait tout un tas de choses dans les coulisses, mais crée essentiellement votre acteur dans le monde et gère sa durée de vie. (Par exemple, pour retirer votre acteur du niveau, vous devez utiliser:

MyActor->Destroy(); 

plutôt que la méthode C++:

delete PtrToActor; 

Cela gère le retirer de la scène, la mise à jour des volumes de collision, etc. Avant de supprimer l'acteur

Pour votre code, vous écrasez bien sûr le pointeur sur votre bloc, de sorte que le bloc lui-même reste intact Vous pouvez utiliser le TActorIterator<T> iterable pour faire défiler tous les acteurs d'un type qui enregistrerait vous devez stocker un n vous-même. Vous feriez quelque chose comme ceci:

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

Où ici le PtrToActor pointera vers chaque instance à son tour que les progrès de la boucle.

Cependant, il n'est pas vraiment inefficace (et dans de nombreux cas, efficace) de stocker votre propre tableau de pointeurs. Ce n'est qu'un petit coût de mémoire (puisqu'il ne s'agit que de pointeurs) et peut être plus rapide car vous n'avez pas besoin de filtrer les acteurs pour trouver celui que vous voulez. Dans les deux cas, c'est beaucoup d'une grandeur, donc vous devriez choisir celui qui vous semble le plus logique. Dans votre exemple, je les garderais dans une structure de données 2D afin que vous puissiez y accéder via leur position plutôt que d'en obtenir une liste non-ordonnée du moteur.