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