running as if you are still holding a run button on the keyboard? Could be you need to clear inputs when unpossessing, pretty sure I had some code for that ready years ago let me take a look. * can’t find it immediately I thought it was a method called flush / clear which would be logical on an input component.
That part of controller code is a shitshow at the moment:
*Edit question, why are you not using Possess but OnPossess? What version of UE are you on?
void AController::Possess(APawn* InPawn)
{
if (!bCanPossessWithoutAuthority && !HasAuthority())
{
FMessageLog("PIE").Warning(FText::Format(
LOCTEXT("ControllerPossessAuthorityOnly", "Possess function should only be used by the network authority for {0}"),
FText::FromName(GetFName())
));
UE_LOG(LogController, Warning, TEXT("Trying to possess %s without network authority! Request will be ignored."), *GetNameSafe(InPawn));
return;
}
REDIRECT_OBJECT_TO_VLOG(InPawn, this);
APawn* CurrentPawn = GetPawn();
// A notification is required when the current assigned pawn is not possessed (i.e. pawn assigned before calling Possess)
const bool bNotificationRequired = (CurrentPawn != nullptr) && (CurrentPawn->GetController() == nullptr);
// To preserve backward compatibility we keep notifying derived classed for null pawn in case some
// overrides decided to react differently when asked to possess a null pawn.
// Default engine implementation is to unpossess the current pawn.
OnPossess(InPawn);
// Notify when pawn to possess (different than the assigned one) has been accepted by the native class or notification is explicitly required
APawn* NewPawn = GetPawn();
if ((NewPawn != CurrentPawn) || bNotificationRequired)
{
ReceivePossess(NewPawn);
OnNewPawn.Broadcast(NewPawn);
OnPossessedPawnChanged.Broadcast(bNotificationRequired ? nullptr : CurrentPawn, NewPawn);
}
TRACE_PAWN_POSSESS(this, InPawn);
}
running as if you are still holding a run button on the keyboard? Could be you need to clear inputs when unpossessing
Yes, as if he was stuck doing the last animation in which he was captured but on its own. It doesn’t respond to user input so I guess there’s no previous input to clear.
why are you not using Possess but OnPossess? What version of UE are you on?
I’m on 5.2.1. I’m using OnPossess because of the comment in header of the source code from Controller
virtual void Possess(APawn* InPawn) final; // DEPRECATED(4.22, "Possess is marked virtual final as you should now be overriding OnPossess instead")
As it did not use UnPosses on the previous pawn but it’s working as I intended, I wondered if I was doing something unnoticeable that would bite me in the future
Sounds like the state machine is stuck on the animation blueprint. Perhaps it holds state like input based movement vectors which don’t update when there is no input or controller. Does it also happen on animation montages? Otherwise I’d take a look at where it could get stuck in a state machine or if it depends on a playercontroller at some point in the logic.
One situation would be if you implement response to “on hold button / on release button” and on release is never reached because you unpossess while holding it. I believe this was an issue on 4.27 and there was some situation which caused my characters to keep on running on an axis binding, though I can’t find any code of it in my repo.
Edit you say the problem occurs when you don’t call this in your spawn method:
Looks like you may override OnPossess but should not be calling OnPossess. Call Possess instead. Reason is that you are missing out on some checks and delegate broadcasts on AController::Possess.
This makes sense because you called SetPawn before possessing, so the controller thinks the current pawn equals the new pawn.
void APlayerController::OnPossess(APawn* PawnToPossess)
{
if ( PawnToPossess != NULL &&
(PlayerState == NULL || !PlayerState->IsOnlyASpectator()) )
{
const bool bNewPawn = (GetPawn() != PawnToPossess);
///// bNewPawn will be false if you called SetPawn to PawnToPossess first.
Calling SetPawn yourself seems wrong.
*Edit calling SetPawn yourself is wrong. the comment on the declaration of this method states
"/** Setter for Pawn. Normally should only be used internally when possessing/unpossessing a Pawn. */"
This compares AController to APlayerController. AController::Possess automatically calls OnPossess when the time is right:
This makes sense because you called SetPawn before possessing, so the controller thinks the current pawn equals the new pawn.
Calling SetPawn yourself seems wrong.
Yes, exactly my point.
I’ll try go further into the source code to see what is doing when unpossesing.
I speak from the little knowledge I have but, perhaps the previous pawn should still have a controller so it finishes its animations, doesn’t lose physics, etc?
I’m not aware that it loses animations and physics by default without a controller, doesn’t make sense. Actors without the possibility of being controlled can still have physics. Please debug using the above code then we can continue from there.
First thing to debug is to set breakpoints on the Possess and inner methods and confirm that the old pawn is unpossessed properly and the new pawn is possessed properly so we can rule out any controller issues.
It behaves the same.
After spawning a new Character, the previous one stays in the last position where it was controlled by the controller in the falling animation.
All works fine for me. The only difference I can now think of is that I ported my project from UE4 to 5 and that our meshes are different. Possibly you use a different “base” for your character files… If you create a new blueprint inheriting from ACharacter, do you still have the problem on that?
I actually just reproduced your issue using one of my repos, there is a bug going on indeed. I need to figure this out. When I’m running all works fine, the character stops. But I reproduced it when falling. The character gets stuck in a falling animation and doesn’t reach the ground until I possess it.
The most logical assumption now is that the CharacterMovementComponent is told to quit on unpossess, I’m looking into it.
*Edit the CharacterMovementComponent its movement mode remains in “Falling” which seems fine at a first look. I see some oddity on ACharacter::Restart, apparently there is a need to reset jump related data when a character is possessed. Whatever it is for this looks odd:
Don’t see yet what UnPossess causes, I’m rebuilding and debugging my old repo. If VS behaves I might find something soon. I’m checking if I can see anything strange on the floor detection, movement itself or gravity values while being unpossessed.
Edit found a symptom:
ACharacter::JumpIsAllowedInternal returns true when hanging in the air bugged, but not during a normal jump.
Meanwhile, can you check the state machine what could cause a character to keep running in a direction? I believe this is a blendspace between idle and run animation taking in the actual velocity of a character, so I’m surprised to see it stand still and run. Might be a second issue after jump.
Found it, I’ll bug report it. There’s a hidden bool on the CharacterMovementComponent which allows movement when there is no controller. Why this even exist is beyond me. Tick it and your jump shouldn’t get stuck.
UCharacterMovementComponent::TickComponent
/////
// Perform input-driven move for any locally-controlled character, and also
// allow animation root motion or physics to move characters even if they have no controller
const bool bShouldPerformControlledCharMove = CharacterOwner->IsLocallyControlled()
|| (!CharacterOwner->Controller && bRunPhysicsWithNoController)
|| (!CharacterOwner->Controller && CharacterOwner->IsPlayingRootMotion());
/////
You shouldn’t need this, not a big fan of it. When something is no longer controlled it should still be allowed to move in my opinion. For example when something is slipping on ice it shouldn’t halt as if hitting a brick wall.