Download

Blend Space problems

Hello I have just uploaded a video showing the issue I am having,
https://www.youtube.com/watch?v=JIVEGy98jag&feature=youtu.be

I have a third person shooter project, I use blend space to mix the different running animations and the aim look and down. I copied the logic from the shooter game example.
In the video I start off by showing the different animations in the Running blend space: Run forwards, Run Backwards, Strafe Left/Right (during the animations the character is always facing forward). The I show the other blend space i have for aiming: Aim up/forwards/down.
Then I go into the animation blueprint and when I play the running blend the results are different, when the player runs to the left the character’s spine rotates 90 degress to face left, and when the player moves backward the character looks up.
Disconnecting the aiming blend space in the graph seams to resolve it but I dont know why. the variable ‘Direction’ is not being used anywhere else but its affecting the animation. Also if I disconect the variable that is feeding into the aiming blend space it is still messing up my running animation.

the code below is wht im using on my character, its just a modified version of the first person shooter template code, the variable AimUp is used to control the aiming blend space but u can see it is no way effected by direction, the variable used in the Running blend space. the MyAnimInstance.cpp/.h is straight forward, it just sets all the variables used in the AnimInstance to 0.


// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#include "ShooterTest.h"
#include "ShooterTestCharacter.h"
#include "ShooterTestProjectile.h"
#include "MyAnimInstance.h"

//////////////////////////////////////////////////////////////////////////
// AShooterTestCharacter

AShooterTestCharacter::AShooterTestCharacter(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
	// Set size for collision capsule
	CapsuleComponent->InitCapsuleSize(42.f, 96.0f);

	// set our turn rates for input
	BaseTurnRate = 45.f;
	BaseLookUpRate = 50.f;

	// Create a CameraComponent	
	FirstPersonCameraComponent = PCIP.CreateDefaultSubobject<UCameraComponent>(this, TEXT("FirstPersonCamera"));
	FirstPersonCameraComponent->AttachParent = CapsuleComponent;
	FirstPersonCameraComponent->RelativeLocation = FVector(0, 0, 64.f); // Position the camera

	// Default offset from the character location for projectiles to spawn
	GunOffset = FVector(100.0f, 30.0f, 10.0f);

	// Create a mesh component that will be used when being viewed from a '1st person' view (when controlling this pawn)
	Mesh1P = PCIP.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("CharacterMesh1P"));
	Mesh1P->SetOnlyOwnerSee(true);			// only the owning player will see this mesh
	Mesh1P->AttachParent = FirstPersonCameraComponent;
	Mesh1P->RelativeLocation = FVector(0.f, 0.f, -150.f);
	Mesh1P->bCastDynamicShadow = false;
	Mesh1P->CastShadow = false;

	// Note: The ProjectileClass and the skeletal mesh/anim blueprints for Mesh1P are set in the
	// derived blueprint asset named MyCharacter (to avoid direct content references in C++)
}

//////////////////////////////////////////////////////////////////////////
// Input

void AShooterTestCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
	// set up gameplay key bindings
	check(InputComponent);

	InputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);

	InputComponent->BindAction("Fire", IE_Pressed, this, &AShooterTestCharacter::OnFire);
	InputComponent->BindTouch(EInputEvent::IE_Pressed, this, &AShooterTestCharacter::TouchStarted);
	InputComponent->BindAxis("MoveForward", this, &AShooterTestCharacter::MoveForward);
	InputComponent->BindAxis("MoveRight", this, &AShooterTestCharacter::MoveRight);

	// We have 2 versions of the rotation bindings to handle different kinds of devices differently
	// "turn" handles devices that provide an absolute delta, such as a mouse.
	// "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick
	//InputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
	//InputComponent->BindAxis("Turn", this, &AShooterTestCharacter::TurnAtRate);
	InputComponent->BindAxis("TurnRate", this, &AShooterTestCharacter::TurnAtRate);
	//InputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
	InputComponent->BindAxis("LookUpRate", this, &AShooterTestCharacter::LookUpAtRate);
	//UMyAnimInstance * Animation = Cast<UMyAnimInstance>(Mesh->GetAnimInstance());
}

void AShooterTestCharacter::OnFire()
{
	// try and fire a projectile
	if (ProjectileClass != NULL)
	{
		const FRotator SpawnRotation = GetControlRotation();
		// MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
		const FVector SpawnLocation = GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

		UWorld* const World = GetWorld();
		if (World != NULL)
		{
			// spawn the projectile at the muzzle
			World->SpawnActor<AShooterTestProjectile>(ProjectileClass, SpawnLocation, SpawnRotation);
		}
	}

	// try and play the sound if specified
	if (FireSound != NULL)
	{
		UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
	}

	//// try and play a firing animation if specified
	//if (FireAnimation != NULL)
	//{
	//	// Get the animation object for the arms mesh
	//	UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
	//	if (AnimInstance != NULL)
	//	{
	//		AnimInstance->Montage_Play(FireAnimation, 1.f);
	//	}
	//}

}

void AShooterTestCharacter::TouchStarted(const ETouchIndex::Type FingerIndex, const FVector Location)
{
	// only fire for first finger down
	if (FingerIndex == 0)
	{
		OnFire();
	}
}

void AShooterTestCharacter::MoveForward(float Value)
{
	UMyAnimInstance * Animation = Cast<UMyAnimInstance>(Mesh->GetAnimInstance());
	if (Value != 0.0f)
	{
		// add movement in that direction
		AddMovementInput(GetActorForwardVector(), Value);
		FwdCounter = true;
		Animation->Running = true;
		Animation->Speed = 100 * Value;
		if (Animation->Speed < 0){ Animation->Speed *= -1; }
		/*FString NewString = FString::SanitizeFloat(Value);
		GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Red, NewString);*/
		//if (Value < 0){ Animation->Direction = 180 * Value; }
		//else{ Animation->Direction = 1 - Value; }
	}
	else{
		FwdCounter = false;
		if (!FwdCounter && !RhtCounter){
			Animation->Running = false;
			if (Animation->Speed > 0 && Animation->Running == false)
			{
				Animation->Speed -= 0.1 *GetWorld()->GetDeltaSeconds();
			}
		}
	}
	FwdVal = Value;
	if (RightVal == 0.0 && FwdVal < 0){ Animation->Direction = 180; }
	if (RightVal == 0.0 && FwdVal > 0){ Animation->Direction = 0; }
	if (FwdVal == 0.0){ Animation->Direction = RightVal * 90; }
	if (FwdVal != 0.0 && RightVal != 0.0){
		if (FwdVal < 0.0 && RightVal < 0.0){
			Animation->Direction = FwdVal * RightVal * 180 * -0.75;
		}
		if (FwdVal > 0.0 && RightVal > 0.0){
			Animation->Direction = FwdVal * RightVal * 180 * 0.25;
		}
		if (FwdVal < 0.0 && RightVal > 0.0){
			Animation->Direction = FwdVal * RightVal * 180 * -0.75;
		}
		if (FwdVal > 0.0 && RightVal < 0.0){
			Animation->Direction = FwdVal * RightVal * 180 * 0.25;
		}
		//Animation->Direction = FwdVal * RightVal * 180;
	}
}

void AShooterTestCharacter::MoveRight(float Value)
{
	if (Value != 0.0f)
	{
		// add movement in that direction
		AddMovementInput(GetActorRightVector(), Value);
		RhtCounter = true;
		//	GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Red, "Txt");
		UMyAnimInstance * Animation = Cast<UMyAnimInstance>(Mesh->GetAnimInstance());
		Animation->Running = true;
		//Animation->Direction = Value * 90;
		Animation->Speed = 100 * Value;
		if (Animation->Speed < 0){ Animation->Speed *= -1; }
		//FString NewString = FString::SanitizeFloat(Value);
		//GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Blue, NewString);
	}
	else{
		RhtCounter = false;
	}
	RightVal = Value;
}

void AShooterTestCharacter::TurnAtRate(float Rate)
{
	// calculate delta for this frame from the rate information
	AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds());
	//UMyAnimInstance * Animation = Cast<UMyAnimInstance>(Mesh->GetAnimInstance());
	////Animation->AimRight += Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds();
	//if (Animation->AimRight < 180 && Animation->AimRight > -180){
	//	Animation->AimRight += 0.5 * Rate * BaseTurnRate;
	//}
	//GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Red, "Txt");
}

void AShooterTestCharacter::LookUpAtRate(float Rate)
{
	// calculate delta for this frame from the rate information
	AddControllerPitchInput(Rate * BaseLookUpRate * -1 * GetWorld()->GetDeltaSeconds());
	UMyAnimInstance * Animation = Cast<UMyAnimInstance>(Mesh->GetAnimInstance());
	//Animation->AimUp += Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds();
	//if (Animation->AimUp <= 180 && Animation->AimUp >= -180){
	//Animation->AimUp += Rate * -0.5 * BaseLookUpRate;
	Animation->AimUp += Rate * BaseLookUpRate * 5 * GetWorld()->GetDeltaSeconds();
	//Mesh->Rotation
	//}
	if (Animation->AimUp > 180){ Animation->AimUp = 180; }
	if (Animation->AimUp < -180){ Animation->AimUp = -180; }
	//FString NewString = FString::SanitizeFloat(Animation->AimUp);
	//GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Red, NewString);
}