Camera shake not work after upgrading to 4.8

I’ve created a camera shake to simulate head bobbing in ue4.7. It works fine until upgrading to 4.8. There is no compiling error when I compile the code. It just won’t work in ue4.8. The camera of the player doesn’t shake, why? Is this a bug?

The code(From the default pawn class) header:

#pragma once

#include "GameFramework/Character.h"
#include "ThePlayerScript.generated.h"

UENUM(BlueprintType)
namespace EEyesEffects
{
	enum Type
	{
		VE_Damage UMETA(DisplayName = "Damage"),
		VE_DamageShoot UMETA(DisplayName = "Shoot Damage"),

		VE_Max UMETA(Hidden),
	};
}

/**
 *  The Main Player Script. Scripted and Designed by Dreamily Games Studio.
 */
UCLASS()
class AThePlayerScript : public ACharacter
{
	GENERATED_UCLASS_BODY()
	

protected:
	
	UCameraShake* CameraShaker;

	UPROPERTY(BlueprintReadWrite, Category = CharacterInfo)
		// Is running being allowed.
		bool EnabledRun;

	UPROPERTY(BlueprintReadOnly, Category=CharacterInfo)
		// Should change to run bobbing mode.
		bool RunModification;

	UPROPERTY(BlueprintReadWrite, Category = CharacterInfo)
		// When the bobbing stop, we do a fadeout of the bobbing animation.
		bool shouldDoBobFadeout;

	UPROPERTY(BlueprintReadWrite, Category = CharacterInfo)
		// Is bobbing enabled.
		bool EnableBobbing;

	UPROPERTY(BlueprintReadOnly, Category = CharacterInfo)
		// Whether the player is aiming.
		bool IsInAimingMode;

	UPROPERTY(BlueprintReadOnly, Category = CharacterDebugInfo)
		float moveForwardScale;

	UPROPERTY(BlueprintReadOnly, Category = CharacterDebugInfo)
		float moveRightScale;

	float BobModValue01;

	void MoveForward(float par1);
	void MoveRight(float par1);

	void MakeBob(float par1);
	void BobModFunc(float value);

	virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;

public :

	UPROPERTY(BlueprintReadWrite, Category = CharacterInfo)
		float PitchAmplitude;

	UPROPERTY(BlueprintReadWrite, Category = CharacterInfo)
		float PitchFrequency;

	UPROPERTY(BlueprintReadWrite, Category = CharacterInfo)
		float RollAmplitude;

	UPROPERTY(BlueprintReadWrite, Category = CharacterInfo)
		float RollFrequency;

	UPROPERTY(BlueprintReadWrite, Category = CharacterInfo)
		float ZAmplitude;

	UPROPERTY(BlueprintReadWrite, Category = CharacterInfo)
		float ZFrequency;

	UFUNCTION(BlueprintCallable, Category = CharacterManager)
		void EnableRunning(bool option);

	UFUNCTION(BlueprintCallable, Category = CharacterManager)
		void SetMaxWalkingSpeed(float newSpeed);

	UFUNCTION(BlueprintCallable, Category = CharacterManager)
		void SetEnableBob(bool enabled);

	void ShiftPressed();
	void ShiftReleased();
	void RTButtonPressed();
	void RTButtonReleased();
};

The code(also from default pawn class) source:

#include "TheFollower.h"
#include "ThePlayerScript.h"


AThePlayerScript::AThePlayerScript(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{
	this->EnabledRun = true;
	this->RunModification = false;
	this->shouldDoBobFadeout = false;
	this->IsInAimingMode = false;

	this->PitchAmplitude = 0.5f;
	this->PitchFrequency = 2.0f;
	this->RollAmplitude = 0.5f;
	this->RollFrequency = 6.5f;
	this->ZAmplitude = 2.0f;
	this->ZFrequency = 10.0f;

	this->CameraShaker = UCameraShake::StaticClass()->GetDefaultObject<UCameraShake>();

}

void AThePlayerScript::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
	check(InputComponent);

	InputComponent->BindAxis("MoveForward", this, &AThePlayerScript::MoveForward);
	InputComponent->BindAxis("MoveRight", this, &AThePlayerScript::MoveRight);
	InputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
	
	InputComponent->BindAction("Shift", EInputEvent::IE_Pressed, this, &AThePlayerScript::ShiftPressed);
	InputComponent->BindAction("Shift", EInputEvent::IE_Released, this, &AThePlayerScript::ShiftReleased);
	InputComponent->BindAction("RTPush", EInputEvent::IE_Pressed, this, &AThePlayerScript::RTButtonPressed);
	InputComponent->BindAction("RTPush", EInputEvent::IE_Released, this, &AThePlayerScript::RTButtonReleased);
}

void AThePlayerScript::ShiftPressed() 
{ 
	if (this->EnabledRun)
	{
		this->RunModification = true;
		GetCharacterMovement()->MaxWalkSpeed = 600.0f;

		this->PitchAmplitude = 1.0f;
		this->PitchFrequency = 14.0f;
		this->RollAmplitude = 1.0f;
		this->RollFrequency = 9.0f;
		this->ZFrequency = 20.0f;
	}
}

void AThePlayerScript::ShiftReleased() 
{ 
	this->RunModification = false;
	GetCharacterMovement()->MaxWalkSpeed = 113.199997f;

	this->shouldDoBobFadeout = true;
}

void AThePlayerScript::RTButtonPressed()
{
	if (!this->IsInAimingMode)
	{
		this->ShiftPressed();
	}
}

void AThePlayerScript::RTButtonReleased()
{
	if (!this->IsInAimingMode)
	{
		this->ShiftReleased();
	}
}

void AThePlayerScript::MoveForward(float par1)
{
	this->moveForwardScale = par1;

	if (par1 != 0)
	{
		AddMovementInput(FRotator(0, GetControlRotation().Yaw, 0).Vector(), par1);
		if (this->RunModification)
		{
			this->MakeBob(1.0f);
		}
		else
		{
			this->MakeBob(1.0f);
		}
	}
}

void AThePlayerScript::MoveRight(float par1)
{
	this->moveRightScale = par1;

	if (par1 != 0)
	{
		AddMovementInput(GetActorRightVector(), par1);
		if (this->RunModification)
		{
			this->MakeBob(1.0f);
		}
		else
		{
			this->MakeBob(1.0f);
		}
	}
}

void AThePlayerScript::MakeBob(float par1)
{
	this->CameraShaker->bSingleInstance = true;
	this->CameraShaker->OscillationDuration = 0.5f;
	this->CameraShaker->OscillationBlendInTime = 0.1f;
	this->CameraShaker->OscillationBlendOutTime = 0.2f;
	this->CameraShaker->RotOscillation.Pitch.Amplitude = this->PitchAmplitude;
	this->CameraShaker->RotOscillation.Pitch.Frequency = this->PitchFrequency;
	this->CameraShaker->RotOscillation.Pitch.InitialOffset = EInitialOscillatorOffset::EOO_OffsetRandom;
	this->CameraShaker->RotOscillation.Yaw.Amplitude = 0.0f;
	this->CameraShaker->RotOscillation.Yaw.Frequency = 5.0f;
	this->CameraShaker->RotOscillation.Yaw.InitialOffset = EInitialOscillatorOffset::EOO_OffsetRandom;
	this->CameraShaker->RotOscillation.Roll.Amplitude = this->RollAmplitude;
	this->CameraShaker->RotOscillation.Roll.Frequency = this->RollFrequency;
	this->CameraShaker->RotOscillation.Roll.InitialOffset = EInitialOscillatorOffset::EOO_OffsetRandom;
	this->CameraShaker->LocOscillation.Z.Amplitude = this->ZAmplitude;
	this->CameraShaker->LocOscillation.Z.Frequency = this->ZFrequency;
	this->CameraShaker->LocOscillation.Z.InitialOffset = EInitialOscillatorOffset::EOO_OffsetRandom;

	if (this->EnableBobbing)
	{
		if (!GetCharacterMovement()->IsFalling())
		{
			GetWorld()->GetFirstLocalPlayerFromController()->PlayerController->ClientPlayCameraShake(this->CameraShaker->GetClass(), par1 < 0.0f ? par1 * -1.0f : par1);
		}
	}
}

void AThePlayerScript::EnableRunning(bool option)
{
	this->EnabledRun = option;
}

void AThePlayerScript::SetMaxWalkingSpeed(float newSpeed)
{
	GetCharacterMovement()->MaxWalkSpeed = newSpeed;
}

void AThePlayerScript::SetEnableBob(bool enabled)
{
	this->EnableBobbing = enabled;
}

Anyone here to help me???

Raising the intensity of the shake animation can help you notice if shake animation is being played or not. Oscillation duration 0.5f seems rather short, so you might not notice the effect at all due to fade-in and fade-out modifiers.

If that doesn’t help, it might be due to bugs with components created in C++ (have spent a fair amount of hair pulling due to this) and the easiest solution is to leave the component initialization to Blueprint editor.

.h file:

/** Optional shake class for afterburner */
UPROPERTY(Category = Spaceship, EditAnywhere)
TSubclassOf<class UCameraShake> AfterburnerShake;

.cpp file:

void AOrbitalKnightsPawn::OnAfterburnerPress()
{
	IsAfterburner = true;

	if (AfterburnerShake)
	{
		GetNetOwningPlayer()->PlayerController->ClientPlayCameraShake(AfterburnerShake, 1.0f /*raise this to 20 for debug*/);
	}
}

Blueprint editor:

Nah it doesn’t work. Increasing the intensity of the shake doesn’t work. I don’t want to create the camera shake outside c++. As there are many connections connected to my c++ camera shake. If I create a new one using blueprint it will be a big operation. Are there any other ways to solve this? Thanks.

You can still create a custom Camera shake blueprint in the editor and load it by class name. If you don’t want to touch editor at all, then you’ll have to extend the UCameraShake class and get its static class instance.

Ok, I’ll try out the blueprint camera shake. Thanks for your help bro

Having the same problem here after upgrading to 4.8.

We need this to work in c++ though, cuz we don’t really use BP. Will this be fixed in the next patch?

Hey xXTrollBrosXx-

After a bit of tested I was able to fix the issue with the head bob (camera shake) in the case of your code. In your MakeBob() function you make changes to the CameraShaker object you’ve created but then when you call ClientPlayCameraShake() you pass in the class that CameraShaker belongs to rather than the object you’ve made changes to. To fix this you can change the object declaration on line 29 of the header from UCameraShake* CameraShaker; to be a sublcass of UCameraShake:

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = CharacterInfo)
    TSubclassOf <UCameraShake> CameraShaker;

Doing this and marking the UPROPERTY as EditAnywhere and BlueprintReadWrite will allow you to create a blueprint of type CameraShake where you can set your custom settings (rather than in your class) and then set that blueprint as the value for the CameraShaker in your character. This means lines 13-18 of your constructor as well as lines 115-130 of the MakeBob function can be removed since all of these values are set in the blueprint. This also means that line 20 in the constructor can be removed since CameraShaker is no longer an object. Because CameraShaker is a class now, line 136 in the MakeBob function would change as well. Rather than using this->CameraShaker->GetClass() which would try to find the class that the CameraShaker object belongs to, you would simply use CameraShaker as a class.

In the editor you then create a blueprint (MyCameraShakeDefaults) who’s parent is the default CameraShake class and set the values you want there. In the character blueprint, which now has CameraShaker exposed as a property, you can assign MyCameraShakeDefaults as its value. Then when you call the SetEnableBob function it will use use the values set in MyCameraShakeDefaults.

Cheers

Sorry i was on a trip. I just tested your way. Here’s the problem: I can’t set the properties of my Camera Shake blueprint in the event graph. I can only set the default properties in the class default panel. Apologize for replying you so late.

Are you referring to the blueprint based off of the Camera Shake class? Setting its default values (rather than in the event graph) is the method that I used. By setting the default values of this blueprint and using it as the CameraShaker reference in your character, the call to MakeBob() will use the default values set in the blueprint.