How can I use this in TArray ?
hi,
i dont know what you want to do exactly but to create a TArray simply do this:
TArray< AActor* > MyActorArray;
This would give you an array which stores Actorobject-References inside. so replace AActor with some class you want to store objects of or values like int32⌠.
What you can do with MyActorArray is documented here: UE4-Documentation
best regards
I want to find element with specific property .
At c#
MyClass result = list.Find(x => x.Id == âxyâ);
I need c++ version of this.
You want to make a Predicate to check for x.id == âxyâ and pass that into FindByPredicate on your TArray.
Could you do 1 example for me? I tried it but I couldnât do
not having foreach like in c# i can tell you something similar if you dont want to use the functions your array provides you already.
MyClass result;
for(int i = 0; i < myArray.ArrayMax;i++)
{
//use â.â if you are using objects or "->"if you are using references
if (myArray[i].Id == "xy")
{
result = myArray[i];
break;
}
}
havnt tested that yet, but maybe it will do the magic
Given TArray< FYourType > MyArray;
FYourType* FoundEntry = MyArray.FindByPredicate([](const FYourType& InItem)
{
return InItem.Id == "xy";
});
if(FoundEntry)
{
// ...
}
Thatâs using a lambda, but the predicate can be any kind of callable type.
You can also use C++11 range-based-for (which is basically C# foreach) with our containers.
for(const auto& Item : MyArray)
{
// ...
}
ABaseEffect* APlayerCharacter::GetPlayerEffectByID(int32 ID){
TArray Effects;
ABaseEffect** eff = Effects.FindByPredicate([](ABaseEffect*& InItem)
{
return InItem->ID == ID;
});
return *eff;
}
Error 4 error C3493: âIDâ cannot be implicitly captured because no default capture mode has been specified C:\Users\AhmetFaruk\Desktop\TenekurOffline\Source\TenekurOffline\Character\PlayerCharacter.cpp 959 1 TenekurOffline
How can I fix it ?
ah, i wasnt aware of that, thanks for that
Youâll need to capture the variable you want to compare against, since itâs just an int32, you can just do this via value:
ABaseEffect** eff = Effects.FindByPredicate([ID](ABaseEffect*& InItem) { return InItem->ID == ID; });
Youâll probably want to read up on lambdas in C++ if youâre planning on making use of them.
This doesnât seem to work for TArray of UObjects or Structs in 4.14.
I am using it with UObjects*. Can you show your implementation?
You may also need to override an operator. But first show your code or at least what you want to do
Thanks for checking
here is the struct definition:
USTRUCT(BlueprintType)
struct FStaffUnitDef
{
GENERATED_USTRUCT_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
EStaffUnitTypes UnitType = EStaffUnitTypes::SU_Combat;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float StaffLimit = 25;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<FStaffMemberDef> StaffList;
};
The structis used in an array:
FStaffUnitDef CombatUnit;
FStaffUnitDef DevelopmentUnit;
FStaffUnitDef ConstructionUnit;
FStaffUnitDef SupportUnit;
FStaffUnitDef IntelUnit;
FStaffUnitDef MedicalUnit;
FStaffUnitDef BriggUnit;
FStaffUnitDef WaitingRoomUnit;
FStaffUnitDef SickBayUnit;
CombatUnit.UnitType = EStaffUnitTypes::SU_Combat;
CombatUnit.StaffLimit = 25;
StaffUnitList.Add(CombatUnit);
DevelopmentUnit.UnitType = EStaffUnitTypes::SU_Development;
DevelopmentUnit.StaffLimit = 50;
StaffUnitList.Add(DevelopmentUnit);
ConstructionUnit.UnitType = EStaffUnitTypes::SU_Construction;
ConstructionUnit.StaffLimit = 25;
StaffUnitList.Add(ConstructionUnit);
// ... and so on...
Here is the function that shall find a specific unit:
.h:
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Data")
FStaffUnitDef* GetUnit(EStaffUnitTypes type);
.cpp:
FStaffUnitDef* UMotherbaseClass::GetUnit(EStaffUnitTypes type)
{
return (StaffUnitList.FindByPredicate([&]( FStaffUnitDef staffunit) { return staffunit.UnitType == type; }));
}
On compile, I get the error message:
Inappropriate â*â on variable of type âFStaffUnitDefâ, cannot have an exposed pointer to this type.
So this is where I am stuck
How can I get an item of an array that I can work with (no read only copy).
As the array struct ('FStaffUnitDef) contains an array itself, I want to be able to edit it.
Any help is appreciated
Hey there,
FindByPredicate is returning a pointer-to-pointer, so you would need to dereference this one to get your object. Jamie Dale did that above on Jan 16. Here is another example:
FString Name;
TArray<AActor*> myArray;
AActor* DesiredElement = *(myArray.FindByPredicate(
[&](AActor* Actor)
{
return Actor->GetName() == Name;
}
));
or this using a struct:
float SomeValue;
TArray<FCharacterStat> myArray;
FCharacterStat& DesiredElement = *(myArray.FindByPredicate(
[&](FCharacterStat Stat)
{
return Stat.Value== SomeValue;
}
));
I changed my code, so now it compiles.
FStaffUnitDef UMotherbaseClass::GetUnit(EStaffUnitTypes type)
{
FStaffUnitDef& Result = *(StaffUnitList.FindByPredicate(
[&](FStaffUnitDef unit)
{
return unit.UnitType == type;
}
));
return Result;
}
However, when I access the result, I somehow cannot modify itâŚ
Only when I use the commented-out hardcoded call, a staff member is added.
void UMotherbaseClass::AddStaffMember(EStaffUnitTypes unit, FStaffMemberDef data)
{
GetUnit(unit).StaffList.Add(data);
//StaffUnitList[0].StaffList.Add(data);
return;
}
What am I still doing wrong?
Your problem lies probably here:
FStaffUnitDef UMotherbaseClass::GetUnit(EStaffUnitTypes type)
Your function returns an object by value and not by reference - a typical error I often do myself ;). So returning this struct will break the reference to the object inside the list. It has the same values but the object is a different one.
What you need to do is returning a pointer or a reference to this listelement. F.e. like this:
FStaffUnitDef* UMotherbaseClass::GetUnit(EStaffUnitTypes type)
{
FStaffUnitDef** Result = StaffUnitList.FindByPredicate(
[&](FStaffUnitDef unit)
{
return unit.UnitType == type;
}
);
return *Result;
}