x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Store Blueprint actor in a TArray C++

I am trying to create an Inventory system in c++ which allows me to store a blueprint derived from a base class of APickup(C++ Class). My problem is I am struggling to find a way to Check if the pickup blueprint is a derivative of APickup. Here is my attempted code.

//BASECHARACTER.CPP

 void ABaseCharacter::Interact()
 {
     if (LastSeenInteractable) // Current linetrace hit (Working)
     {
         if (Inventory) //Check to see if the Character has an Inventory
         {
                     // Chek to see if the item is derived from APickup and assign it to 
         if (APickup* PickupToAdd = Cast<APickup>(LastSeenInteractable))
         {
             Inventory->AddToInventory(PickupToAdd);
         }
         }
         LastSeenInteractable->Interact_Implementation();
     }
 }


 //INVENTORY.CPP
 void UCustomInventory::AddToInventory(APickup* PickupToAdd)
 {
         PickupArray.Add(PickupToAdd);
 }
 
 //INVENTORY.H
 TArray<class APickup*> PickupArray;


Does this seem right? I've logged a loop of the array and it does indeed add something to it, but this would just be a pointer to the initial object from my understanding. I have tried a few things but I'm unable to spawn the object from the array that I have created, Any help would be greatly appreciated. Specifically an explanation of how to store the blueprint that is picked up in an array. Thanks in advance.

EDIT: Ok this works but I want to be able to destroy the actor on pickup and respawn it when the player uses my EquipPickup function. If i set the item to be destroyed on pick up after adding it to the array I will be left with a null pointer so really I want to move or copy the actor in to the array so I can bring it in to other levels.

Product Version: UE 4.13
Tags:
more ▼

asked Sep 09 '16 at 11:33 AM in C++ Programming

avatar image

PaulFisherDev
3 1 2 4

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

A pointer, by definition, is used to avoid making extraneous copies of an object. If you wanted to store a copy, your array would need to be:

 TArray<class APickup> PickupArray;

Which would store an entire copy of the object, rather than just a pointer to it. That said, I don't think you really want to destroy the object/store a copy. If I understand you correctly, you just want to hide it after it's been picked up. In which case you could just call

 PickupToAdd->SetActorHiddenInGame(true);

That way you aren't duplicating Actor objects (which is pretty expensive and honestly I'm not sure if that would work), you still only store pointers in your array, and as long as your array is a UPROPERTY then it should all transfer between levels seamlessly.

more ▼

answered Sep 09 '16 at 05:30 PM

avatar image

ExtraLifeMatt
1.6k 34 14 48

avatar image PaulFisherDev Sep 09 '16 at 06:22 PM

Hi thanks for your response.

I had a play around with my code and found a way of doing what I wanted. I did try to store a copy in the array but I couldn't get the object Stored in the array from the pointer. Maybe I just spent too long on it. I did however use the for my array and then used what was stored in the array to spawn a new actor to the socket on the player.

I did it this way because I wanted to be able to have lets say 100 of the same object. Surely having all those objects stored in memory would become an issue?

My current setup works as intended but I'm currently unable to store the parameters of the object collected and spawn the new one with the same ones. Any insight? Thanks again.

avatar image ExtraLifeMatt Sep 09 '16 at 06:26 PM

You could always have some light weight structure that describes the object (name, stats, or whatever else could be different between objects), rather than the actual object itself. Then when you need to, you instantiate the full object, set the values using your light weight structure, and go from there.

avatar image PaulFisherDev Sep 09 '16 at 06:33 PM

Yeah just been trying to read up on that now. Too be honest I am completely lost on where to start with it. Like where to declare said struct and how to instantiate the full object and set the values. Don't suppose you could soon feed me an example?

avatar image ExtraLifeMatt Sep 09 '16 at 06:53 PM

You can declare the struct where ever you declare APickup, assuming your pickups all inherit from APickup, you could do something like

 USTRUCT()
 struct FItemInfo
 {
  GENERATED_USTRUCT_BODY()
 
   TSubClassOf<APickup> ItemClass;
   // Whatever else you need to store to 
 }
 
 // Your inventory would then have
 TArray<FItemInfo> MyInventory;
 
 Then you could have some method in your Inventory called something like:
 
 APickup* UCustomInventory::InstantiatePickup(FItemInfo& InItemInfo)
 {
     APickup* Item = NewObject<APickup>(InItemInfo.ItemClass);
    // Set any other properties you need to on "Item"
    return Item;
 }
avatar image PaulFisherDev Sep 09 '16 at 07:17 PM

Yeah my APickup class is my abstract class that all pickups are derived from.

So I could store what material, value and mesh the item has in the struct, before I call the destroy function? I always thought a STRUCT was just a class but its members just defaulted to public instead of private?

So I would store my item structs in the array if I understand correctly? Would you know the difference between:

GetWorld()->SpawnActor(PickupToEquip);

and

APickup* Item = NewObject(InItemInfo.ItemClass);

(Besides the obvious params; Mainly difference between spawning and and calling NewObject)

avatar image ExtraLifeMatt Sep 09 '16 at 07:27 PM

A struct is just an object, just like a class. Just make sure you are only storing what you need to. For example if you have a flashlight class (AFlashlight) that inherits from APickup, and all flashlights use the same mesh, etc. Then just storing the class type is enough.

And yea, since you are using Actors instead of UObjects you would need to use SpawnActor, but you can use it the same way:

GetWorld()->SpawnActor(InItemInfo.ItemClass)

avatar image PaulFisherDev Sep 09 '16 at 07:36 PM

Ah I think I get it. I will put sometime into it and if I can't get it working I will be back to pick your brain. Thanks for your help and time Matt!

avatar image PaulFisherDev Sep 10 '16 at 02:05 AM

Just wanted to report back and say I got it working in the end. Had a slight hiccup where I put my function to store the items info in my constructor. Didn't realise it would never be called on the blueprint. Solved it in the end by moving it to BeginPlay. Thanks again for your help buddy!

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question