Changing Component Position smoothly (iron sight)

Hey,
I’m trying to change a skeletal mesh component position (Relative) by mouse click (Smoothly).
I already tried many ways but any of them have their own issues…
Like this one :

if (isAim == true) {

float PistolY =FMath::FInterpTo(Pistol_Glock->RelativeLocation.Y, 3.5f, DeltaTime, 5.0f);
float PistolX = FMath::FInterpTo(Pistol_Glock->RelativeLocation.X, +53.5f, DeltaTime, 5.0f);
float PistolZ = FMath::FInterpTo(Pistol_Glock->RelativeLocation.Y, -513.5f, DeltaTime, 5.0f);
Pistol_Glock->SetRelativeLocation (FVector(PistolX,PistolY,PistolZ));
}

This one works smooth but when it reaches the target position it just keep shaking (don’t if it’s the tick function that causing it or what)
And this one :
void AFPSCharacter::OnAim() {

Pistol_Glock->SetRelativeLocation(FVector(80.0f, 3.5f, -17.0f));
isAim = true;

}
void AFPSCharacter::ReleaseAim() {

Pistol_Glock->SetRelativeLocation(FVector(85.0, 20.0, -20.0));
isAim = false;

}

This one works exactly the way it have to but problem is that it moves fast and as i said i’m trying to move the gun smoothly (For an Iron sight).

Is it possible to move the gun with any of this codes or maybe changing them a bit ?,I’m new to UE4 and just switched from UNITY (almost two weeks of learning) and sadly i can rarely find any tutorial for this game engine.

The shaking is probably because you aren’t stopping the interp when you get to the end. FInterpTo takes current and end points, right? So when current is nearly equal to end, you need to stop interpolating and set the relative location to the end location explicitly (no interp) so it’s in the right spot at the end. If you just stop interpolating the end position will be inconsistent so you need to set the end location once at the end of the interp.

By the way, there’s a VInterpTo so you can interp the whole vector instead of one component at a time.

Thanks for the answer !

I just checked the code and i was using “Pistol_Glock->RelativeLocation.Y” as Pistol.Z position and i think it was the reason behind that creepy shaking !
And it even solved the issue with the gun movement start position which was starting to move to aim position with a position a bit higher than the gun normal position.

I tried as you said too with this :

if (FVector(PistolX, PistolY, PistolZ) != FVector(+63.5f, 3.5f, -17.5f))

Not sure if i did exactly as you said or it stopped shaking or changing that Z pose did the job but it works great right now even without checking for current and end points !
Here is the new code i’m using :

if (isAim == true) {

	float PistolY = FMath::FInterpTo(Pistol_Glock->RelativeLocation.Y, 3.5f, DeltaTime, 8.0f);
	float PistolX = FMath::FInterpTo(Pistol_Glock->RelativeLocation.X, +63.5f, DeltaTime, 8.0f);
	float PistolZ = FMath::FInterpTo(Pistol_Glock->RelativeLocation.Z, -17.5f, DeltaTime, 8.0f);

	//if (FVector(PistolX, PistolY, PistolZ) != FVector(+63.5f, 3.5f, -17.5f)) {
		Pistol_Glock->SetRelativeLocation(FVector(PistolX, PistolY, PistolZ));
//	}
}

Looks like after two days i found a simple working solution.Gonna check that VInterpTo as well.

Thank again.

Cool! Three things.

First, Pistol_Glock->RelativeLocation is an FVector so you don’t need to interp the components separately. FMath::VinterpTo will do all the components for you.

Second, you don’t want to see if the values are equal, you want to see if they are nearly equal. Sometimes the interp won’t hit the end result exactly. So you want to use FVector::Equals(). The second parameter allows you to specify how close they should be to count as equal. I’d say somewhere between 0.1 and 0.01 would be a good tolerance but you will see what works and doesn’t. Checking for exact equality may work sometimes but it’s not a safe bet in the long run.

Third, to save processing, you want to check to see if the current and end are nearly equal and only do the interp if they aren’t. Doing the interp and then checking for near-equality wastes CPU since you don’t use the result of the interp unless the condition is true. There are even faster ways but there’s no point in making it over-complicated at this point.

I’ve Wrote the code with VinterpTo this time as you said and it looks better right now and works as good the old one !

if (isAim == true) {

	if (!(Pistol_Glock->GetComponentLocation().Equals(GlockAimSphere->GetComponentLocation(), 0.05f))) {
	Pistol_Glock->SetRelativeLocation(FMath::VInterpTo(Pistol_Glock->RelativeLocation, GlockAimSphere->RelativeLocation, DeltaTime, 8.0f));
	}

	if((Pistol_Glock->GetComponentLocation().Equals(GlockAimSphere->GetComponentLocation(), 0.05f))) {
		GEngine->AddOnScreenDebugMessage(-1, 0.2, FColor::Red, (TEXT("Reached")),true);
	}
}

I just added a sphere component for the aim position so i don’t need to keep changing the vectors and compiling the code to see the weapon is at the place i want it to be or not.
And about the Vector equals i’m not sure if i did this true or not but i will working on it.

Thanks again for your answers and your time.