Island Escape: "==" is not working

Hello,

I am trying to create a separate code where if the “ExactWeightOnly” is turned on, the weight must be exactly what is floated, otherwise the door will react to the trigger.

I went through this as carefully as I can to try to locate the problem, it is the “==” operators that seem to be the problem. I the bool works, the other code “>” or “<” works (this is dealing with not needing an exact weight). But nothing happens with “==”.

Here is my code:

void UOpenDoor::AutoDoorSequencer(float DeltaTime)
{
	ExactWeightOnly;
	if (!ExactWeightOnly)
	{
		if (!OpenDoorTrigger) {return;}
		if (OpenTotalMassOfActors() > MassPressureForDoor)// if accumalitive weight is this, not just player.
		{
			OpenDoor(DeltaTime);// passing in DeltaTime, which is framerate. 

			DoorLastOpened = GetWorld()->GetTimeSeconds();// will start a timer counting when the door opens.
			 											  //DoorLastOpened = when the door was opened
		}		
		else// if not on the trigger
		{
		    // Minus the GetTimeSeconds (is current time) by DoorLastOpen, and then check to
			// see if the remainder is greater than doorclosedelay. If so, close it. 
			if (GetWorld()->GetTimeSeconds() - DoorLastOpened > DoorCloseDelay)
			{
				CloseDoor(DeltaTime);								
			}
	    }
	}
	else
	{
		if (!OpenDoorTrigger){return;}
		if (OpenTotalMassOfActors() == MassPressureForDoor)
		{
			OpenDoor(DeltaTime);
			
			DoorLastOpened = GetWorld()->GetTimeSeconds();
		}		
		else
		{
			if (OpenTotalMassOfActors() > MassPressureForDoor || OpenTotalMassOfActors() < MassPressureForDoor)// greater or less than equal?
			{
				if (GetWorld()->GetTimeSeconds() - DoorLastOpened > DoorCloseDelay)
				{
					CloseDoor(DeltaTime);					
				}	
			}
	    }
	}
}

Besides the equal sign, everything is working. If I switch the roles of the “ExactWeightOnly” bool, so that when on it compares using “>” instead of “==” it works. Thus I find when the “==” does the code stop working.

Or maybe there is an issue within the EU editor that I am not aware of. Maybe my objects are not interacting correctly? Somehow the weight of the object is not exact despite what is typed in. No clue.

1 Like

What is ExactWeightOnly? A bool or a function? If it a function, you need the () at the end. What are you trying to do with ExactWeightOnly; line?

1 Like

ExactWieghtOnly is a bool. It is exposed to the UE editor as a tick box, so that if it is ticked, the exact weight will be used from the float “MassPressureForDoor”, where as if it is not ticked, the weight will be the amount you need to exceed for the doors to open.

Ok, now I understand what you want to do. What I don’t understand is that line:

About your question. It is a bad idea to try to use == to compare two floats, because floats are not an exact number, there are internal precision errors, so will never be equal. The best way to compare is something like (FMath::Abs(a - b) < c) . c must be a small number, the error you define that doesn’t affect the dynamic of your game (1e-7, 1e-8… or 0.1 if you have large numbers).

I hope this helps you. Good luck in your game!

1 Like

Would I want to compare two integers then? Or can one compare an int and a float?

You can compare two integers without problem. The problem are the floats: 1.f can be
1.000000001 or 0.999999999 in the computer memory, but 1 integer is always 1. That is the reason why to compare two floats the method is subtract the two, and compare the result to a calculated error.

If you are using mass numbers like hundreds, the error can be 0.1 or similar. If you are using tens, perhaps the error can be 0.01 or 0.001 …

If you want to compare an int to a float, first you have to convert one of those to the other type. If you convert the int to a float, you will have the same problem. If you convert a float to an int, you are loosing info.

1 Like

Just to make sure I understand clearly, could you give me an example what this usage would look like? If you do, let us use weight since we are talking about it, how that might work if we subtract as you say, and then compare it to c. The weight I was checking against was 50Kg in most cases.

That does make some sense. It seems better to use int’s or just floats in many cases, but if you do combine, it seems better to change an int to a float rather than the other way around.

The Code I found is FMath::IsNearlyEqual (Double, double, Error) or FMath::IsNearlyZero(Double, Double, Error). How would I use this in a condition or as a condition?

Perfect! If you look at the description, it returns a bool. Basically it is a function that do the float comparation with the error you define. Taking your example and in this game, if you have all the objects that a player can take with a mass of 40Kg, 50Kg or more (take always the smallest one to compare), I think the error can be 0.1. So, you can use something like:

bool bIsExactWeight = FMath:IsNearlyEqual(OpenTotalMassOfActors(), MassPressureForDoor, 0.1f);

I am guessing that OpenTotalMassOfActors() return the sum of all the actors placed there and MasPressureForDoor is the mass needed to open the door.

If you don’t want to define a bool, you can put

FMath:IsNearlyEqual(OpenTotalMassOfActors(), MassPressureForDoor, 0.1f)

inside the if you are making the comparison.

Be careful if you have masses similar or that its sum can be similar (Ex 50 and 50.1Kg) Then the error must be smaller.

1 Like

On a side note, here’s a useful Tom Scott

2 Likes

That worked, but with one Caveat: I had to turn on the Overlap Events on my objects !

However, I found that my character did not trigger the event unless I put the mesh into simulate physics. But then I had no control of the actor, and the camera simply fell over.

What might be the issue here?

Certainly something to think about. Floats are not simple numbers, and machines are not people. We expect one result, but in the end, we have to conform to the computer’s processing to understand the results we do get.

Well, yes, if you want to trigger an overlap event, you have to turn on the Overlap Events on your objects or they will not trigger the collider. Also, overlap events don’t work without physics on. About the camera falling, what do you mean? The character is falling though the floor, perhaps?

I was going to give you some pictures, but I found out the issue: my Camera.

It was placed under my mesh in my BP, so I relocated it, placing it under the Collisions Component where the mesh is, and everything worked fine.

One thing that tipped me off was that without the “simulate issue” I had with one of my BP details was that my player character set off the triggers when the exact weight mode was off. But when it was on it would not work.

I think that wraps everything up. This has been a very informative topic. I figured that I was missing something or not understanding something. Failing for days was becoming very grating to say the least. But I do not think it was a waste, even if it seemed like I was getting nowhere. Now I have a much better understanding about floats, particularly what I cannot do with them. And that I also need to check my Overlap Events. This was covered, but so very easy to overlook.

Programming is a nice balance to my other projects. Sometimes I feel or think myself smarter than my own good, but as soon as I begin coding, that illusion quickly dissipates. :slight_smile:

Thanks for your help @Munsa and @DanM ,

Pax

1 Like

I know the feeling… :joy:

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms