Binary ‘==’: no operator found? FTransform == FTransform

I am already trying some code which is not working, correct me what I am doing wrong? please check the blueprint version of this code and correct me if I am doing wrong something.

Severity Code Description File
Error C2678 binary ‘==’: no operator found which takes a left-hand operand of type ‘const FTransform’ (or there is no acceptable Conversion] Array.h

My Code

ItemGroupRef->GetAllTransforms(Available);
RandomLocation(Available, Location); 
if (UsedLocations.Find(Location) == -1) //issue happening here
{
   //Some codes
}

blueprint example"

i don’t know why the native bp code for this logic is using 89 switch cases :smiley:

int32 Index;
if (StrArr.Find(TEXT("Hello"), Index))
{
    // Index == 3
}

Hi, You think your answer makes sense if you compare it to what I am doing?

FTransform does not have a == operator:

\UE_4.27\Engine\Source\Runtime\Core\Public\Math\TransformNonVectorized.h

For some reason it is commented out. You can do your own comparisons on the Location / Rotation / Scale structs within the transform struct.

bool operator==(const FTransform& Other) const
{
  return (
    Rotation == Other.Rotation
    && Translation == Other.Translation 
    && Scale3D == Other.Scale3D;  
  );

}
2 Likes

So this limitation is only for C++?
What about blueprint, the branch is not using the == ?

I believe there is some “magic” going on behind the scenes for blueprint types to automate operators. It is a limitation in c++ however. c++ types must have operators defined if you want to use the operators.

If you find a missing operator in c++ you’d have to modify engine source to implement it. An alternative is to implement your own library using static methods to implement the logic.

1 Like

please guide me how to add static method to make it work for my logic.
I am afraid if I modify the engine code, it will recompile the whole engine takes 6hrs.

Yes you should probably not work on engine source, waste of time.
Since you shouldn’t need it for blueprints you should just be fine with a simple library:

YourUtils.h
#pragma once

#include "Math/TransformNonVectorized.h"


class FYourUtils {

public:

	static bool IsEqual_Transform(const FTransform& A, const FTransform& B);

};

YourUtils.cpp

#include "YourUtils.h"

bool FYourUtils::IsEqual_Transform(const FTransform& A, const FTransform& B) {
  return (
    A.Rotation == B.Rotation
    && A.Translation == B.Translation 
    && A.Scale3D == B.Scale3D
  );  
}
2 Likes

Thank you very much Sir for solving this strange issue, extremely appreciated :slight_smile:

Sir one more question, where I will find this Utils.h and Utils.cpp to write this code in it?

You make them in your /Source/ folder of your project and compile it with Visual Studio as usual.

1 Like

You should never compare FVectors and FRotators with ==, because sometimes the engine approximates the float values and it would return false (the most common case, for example, is when you set 90° and it shows 89.99999° or similar values, don’t know why but it happens very frequently to me both in FVectors and FRotators)

The recommended way to compare two transforms is to use UKismetMath::NearlyEqual_TransformTransform

This function also exists for vector and rotators and allows you to pass the tolerance for each value as parameter

1 Like

That is true. Unsure why the engine turns exact 90 into something else but I’ve seen it happen on the editor. Magic float precision. The == operator is however implemented on FVector and FRotator like this:

FORCEINLINE bool FVector::operator==(const FVector& V) const
{
	return X==V.X && Y==V.Y && Z==V.Z;
}

FORCEINLINE bool FRotator::operator==( const FRotator& R ) const
{
	return Pitch==R.Pitch && Yaw==R.Yaw && Roll==R.Roll;
}

You can use the kismet library to get the precision right with blueprints. All it does is call 3 methods on FTransform accessible in c++, which in turn call similar methods on the vectors:

FTransform::AreRotationsEqual(A, B, RotationTolerance) &&
FTransform::AreTranslationsEqual(A, B, LocationTolerance) &&
FTransform::AreScale3DsEqual(A, B, Scale3DTolerance);
2 Likes

Ok I created an empty class MyUtils using the editor and can’t access TransformNonVectorized

Severity Code Description Project
Error (active) E0265 member FTransform::Rotation (declared at line 42 of Public\Math/TransformVectorized.h) is inaccessible MyGame 11

MyUtils.h

#pragma once
#include "CoreMinimal.h"
#include "Math/TransformNonVectorized.h"

class MyGame_API MyUtils
{
public:
	static bool IsEqual_Transform(const TArray<FTransform>& A, const FTransform& B);
};

MyUtils.cpp

#include "MyUtils.h"

bool MyUtils::IsEqual_Transform(const TArray<FTransform>& A, const FTransform& B))
{
	return (
		A.Rotation == B.Rotation
		&& A.Translation == B.Translation
		&& A.Scale3D == B.Scale3D
		);
}

this is where it takes me along with compile time error. Array.h

just my guess

"Location_"

is not a integer or has other things besides integers there for you are trying to convert something to an integer number like a float maybe or evens something else.

FTransform is a float ? and “-1” is an integer number.

1 Like

Location is of type FTransform
in this post the full snippet can be found Snippet

Transform composed of Scale, Rotation (as a quaternion), and Translation.

Transforms can be used to convert from one space to another, for example by transforming positions and directions from local space to world space.

So it’s based on float values if I’m not mistaken, to convert possition from local to world and those values are based on floats.

== may not work with floats, I never tried using floats with it and -1 looks like an integer.

one click search says.

https://www.cs.technion.ac.il/users/yechiel/c++-faq/floating-point-arith.html
Because floating point arithmetic is different from real number arithmetic.

Bottom line: Never use == to compare two floating point numbers.

Here’s a simple example:

So my hunch turned right. == is for exact float match in your case, probally why. But it’s not usable in this case.

1 Like

I am not comparing two floating points , I have the stored locations in data table
image_2022-08-15_230640340

I am looping through these filxed locations, if a location/row is duplicated , I remove it by -1 to randomize it again. these are spawn locations.
these are assigned in getalltransforms function