Hi all,
I’m trying to figure out a twin stick control scheme, and I want the players upper torso to move independently from the lower torso. I have my aim offsets working, my aim offset on both axes takes a value of -0.5 to 0.5 on both axes. For now in my code, I’m manually setting the pitch to 0.
Here’s what my code looks like -
FRotator ADerelictCharacter::GetAimOffsets() const
{
if (Controller)
{
ADerelictPlayerController* PC = Cast<ADerelictPlayerController>(GetController());
FRotator currentRotation = GetActorRotation();
FVector target = PC->GetMouseLocationInWorldSpace();
FVector start = GetActorLocation();
FVector direction = -(target - start);
FRotator targetRot = FRotationMatrix::MakeFromX(direction).Rotator();
const FVector RotationDir = targetRot.Vector();
const FVector LocalDir = ActorToWorld().InverseTransformVectorNoScale(RotationDir);
const FRotator LocalRotation = LocalDir.Rotation();
return FRotator(currentRotation.Pitch, -(LocalRotation.Yaw + currentRotation.Yaw), currentRotation.Roll);
}
return FRotator::ZeroRotator;
}
This works -
http://giant.gfycat.com/UnfitUnlinedCaudata.gif
Here, not so much…
http://giant.gfycat.com/WeeCompetentBobolink.gif
Thanks for any / all help!
I started working on the other code I’m going to need to make this control scheme work. I implemented code so that my pawn is always rotating towards my mouse cursor.
When he had a yaw of > 90 degrees or < -90 degrees the aim offset stopped working and he just kind of snapped between two angles for any degrees between there.
I started checking in my getaimoffset function for the actors current rotation like so -
FRotator ADerelictCharacter::GetAimOffsets() const
{
if (Controller)
{
ADerelictPlayerController* PC = Cast<ADerelictPlayerController>(GetController());
FRotator currentRotation = GetActorRotation();
FVector target = PC->GetMouseLocationInWorldSpace();
FVector start = GetActorLocation();
FVector direction = -(target - start);
FRotator targetRot = FRotationMatrix::MakeFromX(direction).Rotator();
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Yaw " + FString::SanitizeFloat(currentRotation.Yaw)));
const FVector RotationDir = targetRot.Vector();
const FVector LocalDir = ActorToWorld().InverseTransformVectorNoScale(RotationDir);
FRotator LocalRotation = LocalDir.Rotation();
if (currentRotation.Yaw > 90 || currentRotation.Yaw < -90) {
return FRotator(currentRotation.Pitch, (LocalRotation.Yaw + currentRotation.Yaw), currentRotation.Roll);
}
else {
return FRotator(currentRotation.Pitch, -(LocalRotation.Yaw + currentRotation.Yaw), currentRotation.Roll);
}
}
return FRotator::ZeroRotator;
}
I get decent results with this solution - but still not optimal. I’m still encountering deadzones where the character just snaps to an angle - which is to be expected the way I’m handling this. As soon as the pawn’s rotation reaches a certain value, I invert the offset, which isn’t correct. I’m missing something when calculating the offset, I’m pretty sure.
Any ideas?
http://giant.gfycat.com/ImaginaryFirsthandBlackrhino.gif