C++ enlightenment regarding the build 1808360?

Hi,

I just updated a lot of parts in my current game code to the new build and I would like some information regarding certain changes.

  • Why is the boolean “bHiddenEd” making a compilation error (Undeclared identifier) while the boolean exists inside the AActor class and should be available inside its children classes ? I have two classes inheriting from AActor and in both I get an error in the constructor about this boolean. The boolean is public like some other, so I don’t see why I can’t modify it.

  • Regarding the changes made with the Character class, there is no more CalcCamera, instead there is a Camera component. However I don’t see any setting enabled/updated to let the Character class know that the player will see through this Camera. Is this because the engine automatically put the view of the player inside the first camera linked to the character class ? If yes, this should be added in the comments of the constructor because nothing is explained about that.

  • GetControlAcceleration() was a function available in the PlayerController class, the function doesn’t exist anymore. I wasn’t able to find something similar. What is the equivalent now ?

That’s all I have for now. :slight_smile:

Some answers :

  • 1] I don’t know why I had this problem (probably because I had some other compilation errors at the same time, adding this one to the list). Now it’s compiling normally.

  • 2] This is explained inside the release notes : “Actors now search for an attached camera component when being viewed thru (controlled by bFindCameraComponentWhenViewTarget), allowing easy camera customization per pawn in Blueprints”. However I still think this behavior should be explained inside the comments of the templates because this is not obvious since it’s you who create the object.

  • 3] I’m still searching…

RE: (2), which template are you working from? We tried to make the comments in the constructor clear about what is happening but would be glad to further clarify them.

You can still implement CalcCamera by the way, we’ve just made the default implementation look for a camera component and use that instead (gated by bFindCameraComponentWhenViewTarget).

Cheers,
Michael Noland

  1. Movement input is now accumulated on the PawnMovementComponent instead of the PlayerController. Look at APawn::AddMovementInput() for an example of where it is accumulated, by calling MovementComponent->AddInputVector().

The accumulated input can read in the MovementComponent by using GetInputVector().

@Michael : Regarding the template : I’m using the ThirdPerson C++ Template and currently the comments doesn’t explain how the camera is used by the code, only how to setup it.

@anonymous_user_61c4011f : Thanks ! GetInputVector() was what I was looking for ! :slight_smile:


I have new questions however :

  • What is the purpose of CalcCamera and FaceRotation now ? Since the camera is an actor that is attached to the Controller, CalcCamera is not used anymore right ? Is the function still existing because it wasn’t yet removed ? Same question for FaceRotation, I have overridden the function ACharacter::FaceRotation() and from my tests this function is never called by any code.

  • The current way of rotating the Character (or Pawn) without using the Controller rotation doesn’t feel right to me. It can only be enabled by using a boolean. So the code is totally hidden. The problem is that the current way of rotating the Character is by using the raw direction from the gamepad/keyboard input. This is a bit ugly because the rotation is not smooth. So I was trying to override some functions but it looks like the Character Rotation is directly done inside the PlayerController::ProcessPlayerInput() function. Since it’s totally hidden I can’t guess what happen and use a custom lerp with a custom speed instead of using the current behavior. Would it be possible to get more information about this function ?

I’m bumping this because I would really like some answers. :slight_smile:

RE: FaceRotation:
This should get called by the PlayerController whenever UpdateRotation() is called, which normally happens whenever the PlayerController possesses the Pawn. For AI, it happens when the AI has a FocalPoint. In both instances the SetControlRotation is called on the controller first, and then FaceRotation is called with the same rotation.

RE: Rotating Character:
Can you give more details about what you mean? If you are talking about the bUseControllerRotation[Pitch/Yaw/Roll], those are there just to make it easy to avoid using portions of the rotation in FaceRotation. You are free to not call the base Pawn implementation and implement FaceRotation() as you like instead.

Michael can chime in about the camera flow, but I think you can do any sort of lerping you want in either the camera (which updates the rotation sent to the control rotation and then FaceRotation), or you can do it on your own in FaceRotation as well.

I’m talking about the behavior of “bOrientToMovement” in the case of a Character controlled by the player, not an AI.

I overridden both UpdateRotation() and FaceRotation(). My own UpdateRotation() that doesn’t call a “Super::UpdateRotation()” also don’t call FaceRotation().

Still, in this configuration, my Character is able to turn based on the Controller/PlayerInput rotation. For me it’s the proof that I don’t have any control on it whatever I could try. So I would like to know in which function and how the character rotation is done, to be able to override it properly.

OK, gotcha.

PhysicsRotation() is called each tick on the character movement component. Setting bOrientToMovement to true causes the desired rotation to be set to the result of ComputeOrientToMovementRotation(). Then the components of the rotation are updated based on the result of FMath::FixedTurn(), using GetDeltaRotation() to find the rotation rate based on delta time. So you have quite a few options depending on what you want to change, and where you want to change it (either override it completely, or just GetDeltaRotation, or ComputeOrientToMovementRotation, etc).

This code snippet might make it more clear:

FRotator UCharacterMovementComponent::GetDeltaRotation(float DeltaTime)
{
	return (RotationRate * DeltaTime);
}

FRotator UCharacterMovementComponent::ComputeOrientToMovementRotation(const FRotator& CurrentRotation, float DeltaTime, FRotator& DeltaRotation)
{
	// Do nothing if not accelerating.
	if (Acceleration.SizeSquared() < KINDA_SMALL_NUMBER)
	{
		return CurrentRotation;
	}

	// Rotate toward direction of acceleration.
	return Acceleration.SafeNormal().Rotation();
}

void UCharacterMovementComponent::PhysicsRotation(float DeltaTime)
{
	const FRotator CurrentRotation = CharacterOwner->GetActorRotation();
	FRotator DeltaRot = GetDeltaRotation(DeltaTime);
	FRotator DesiredRotation = CurrentRotation;

	if (bOrientToMovement)
	{
		DesiredRotation = ComputeOrientToMovementRotation(CurrentRotation, DeltaTime, DeltaRot);
	}
	else if (bUseControllerDesiredRotation)
	{
		DesiredRotation = CharacterOwner->Controller->GetDesiredRotation();
	}
	else
	{
		return;
	}

	// [Some code to zero pitch/roll when walking or falling]

	// Accumulate a desired new rotation.
	FRotator NewRotation = CurrentRotation;	

	//YAW
	if( DesiredRotation.Yaw != CurrentRotation.Yaw )
	{
		NewRotation.Yaw = FMath::FixedTurn(CurrentRotation.Yaw, DesiredRotation.Yaw, DeltaRot.Yaw);
	}

	// [Similar code for Pitch/Roll]

	// Set the new rotation.
	if( !NewRotation.Equals(CurrentRotation.GetDenormalized(), 0.01f) )
	{
		MoveUpdatedComponent( FVector::ZeroVector, NewRotation, 0, true );
	}
}