【UE4】Enregistrement du problème de montage NextSection

Cet article utilise UE4.26 et le système GAS pour enregistrer un problème avec le Montage Next Section.

1. Contexte du problème et performances

1.1 Contexte du problème

  Dans UE4, vous devez parfois modifier la relation de connexion de Section pendant la lecture de Montage (pour la signification et l'utilisation de Montage et Section, veuillez vous référer ici ). Par exemple, parfois vous souhaitez suivre le 1er paragraphe jusqu'au 2ème paragraphe, et parfois vous souhaitez suivre le 3ème paragraphe.segment, vous pouvez utiliser pour UGameplayAbility::MontageSetNextSectionNamedéfinir le segment suivant du premier segment, et vous pouvez ensuite obtenir l'effet de continuer la lecture directement à partir du segment après la fin du premier segment.

  Si vous ne voulez pas que le segment en cours termine la lecture, mais passe directement au segment suivant, du point de vue de l'interface, il n'y a pas d'interface avec une fonction telle que " JumpToNextSection ", seulement une interface telle que " MontageJumpToSection ", une interface telle que " GetNextSection

1.2 Manifestation du problème

  La performance du problème peut être résumée en une phrase : incompatible FAnimMontageInstance::GetNextSection()avec FAnimMontageInstance::GetNextSectionIDles résultats.

FName FAnimMontageInstance::GetNextSection() const
{
    
    
	if (Montage)
	{
    
    
		float CurrentPosition;
		const int32 CurrentSectionIndex = Montage->GetAnimCompositeSectionIndexFromPos(Position, CurrentPosition);
		if (Montage->IsValidSectionIndex(CurrentSectionIndex))
		{
    
    
			FCompositeSection& CurrentSection = Montage->GetAnimCompositeSection(CurrentSectionIndex);
			return CurrentSection.NextSectionName;
		}
	}
	return NAME_None;
}

int32 FAnimMontageInstance::GetNextSectionID(int32 const & CurrentSectionID) const
{
    
    
	return NextSections.IsValidIndex(CurrentSectionID) ? NextSections[CurrentSectionID] : INDEX_NONE;
}

  Les deux fonctions sont présentées ci-dessus :

  1. GetNextSectionLa Section actuelle est calculée via Position, puis la NextSection est obtenue via la variable FCompositeSectiondu type NextSectionName.
  2. Au lieu de cela GetNextSectionID, l'ID de NextSection est obtenu via le tableau NextSection et l'ID de la section actuelle.

  Après avoir obtenu l'ID de NextSection via la deuxième méthode, vous pouvez obtenir le nom de NextSection :

FName FAnimMontageInstance::GetSectionNameFromID(int32 const & SectionID) const
{
    
    
	if (Montage && Montage->IsValidSectionIndex(SectionID))
	{
    
    
		FCompositeSection const & CurrentSection = Montage->GetAnimCompositeSection(SectionID);
		return CurrentSection.SectionName;
	}
	return NAME_None;
}

  À en juger par les noms de fonctions, la différence entre les deux ne devrait être que le nom et l'ID de retour (lorsque l'ID de section actuel est passé en paramètre à ) GetNextSectionID, mais parce que deux manières complètement différentes sont utilisées pour obtenir la NextSection (l'une est FCompositeSectionmembre variable, l'autre est NextSectionsun tableau), les résultats réels peuvent varier.

1.3 Récurrence du problème

  Configurez un montage comme indiqué ci-dessous :
Insérer la description de l'image ici

  Il y a quatre sections, et la section suivante de chaque section est la section suivante.
  Chaque segment est configuré avec une notification d'animation "PrintString", qui est utilisée pour générer une chaîne configurée. Chaque segment est configuré avec les "2", "3" et "4" correspondants.
  Lancez le jeu et jouez à ce montage. Vous pouvez voir que quatre sont sortis dans l'ordre, pas de problème :

LogAbilitySystem: Error: Print String 1
LogAbilitySystem: Error: Print String 2
LogAbilitySystem: Error: Print String 3
LogAbilitySystem: Error: Print String 4

  Configurez une notification d'animation dans le premier paragraphe. Lorsque la notification est déclenchée, effectuez les opérations de " SetNextSection " et " GetNextSection " (pour tester, bien que vous puissiez sauter directement),
Insérer la description de l'image ici

  le code s'affiche comme ci-dessous :

ACharacter* const Character = Cast<ACharacter>(GetOwningActorFromActorInfo());
if (!Character)
{
    
    
	return;
}

UAbilitySystemComponent* const ASC = GetAbilitySystemComponentFromActorInfo_Checked();
if (!ASC)
{
    
    
	return;
}

UAnimInstance* const AnimInstance = Character->GetMesh()->GetAnimInstance();
if (!AnimInstance)
{
    
    
	return;
}

FAnimMontageInstance* const AnimMontageInstance = AnimInstance->GetActiveInstanceForMontage(ASC->GetCurrentMontage());
if (!AnimMontageInstance)
{
    
    
	return;
}

MontageSetNextSectionName("1", "3");

FName const CurSection = AnimMontageInstance->GetCurrentSection();
FName const NextSection1 = AnimMontageInstance->GetNextSection();
FName const NextSection2 = 
	AnimMontageInstance->GetSectionNameFromID(AnimMontageInstance->GetNextSectionID(ASC->GetCurrentMontageSectionID()));
UE_LOG(LogAbilitySystem, Error, 
	TEXT("CurSection is %s; NextSection1 is %s; NextSection2 is %s;"), 
	*CurSection.ToString(), 
	*NextSection1.ToString(), 
	*NextSection2.ToString());

  Le fait est en fait que MontageSetNextSectionName("1", "3");le paragraphe suivant après avoir défini le paragraphe « 1 » est le paragraphe « 3 » au lieu du paragraphe « 2 » par défaut.

  Les trois méthodes de MontageSetNextSectionName("1", "3");et AnimInstance->Montage_SetNextSection("1", "3", ASC->GetCurrentMontage());et AnimMontageInstance->SetNextSectionName("1", "3");sont les mêmes.

  Ensuite, obtenez NextSection de deux manières différentes, les résultats sont les suivants :

LogAbilitySystem: Error: CurSection is 1; NextSection1 is 2; NextSection2 is 3;
LogAbilitySystem: Error: Print String 1
LogAbilitySystem: Error: Print String 3
LogAbilitySystem: Error: Print String 4

  D'après les performances et la sortie réelles de l'animation, nous pouvons voir que le paramètre NextSection est efficace. La fin du paragraphe "1" est suivie du paragraphe "3", mais le paragraphe par défaut "2" est obtenu via AnimMontageInstance->GetCurrentSection().

2. Cause du problème

UGameplayAbility::MontageSetNextSectionName(FName FromSectionName, FName ToSectionName)

  La fonction ci-dessus sera éventuellement ajustée comme suit :

bool FAnimMontageInstance::SetNextSectionID(int32 const & SectionID, int32 const & NewNextSectionID)

  La fonction ci-dessus modifie uniquement les variables membres PrevSectionset NextSectionsces deux tableaux, et ne modifie pas réellement la NextSection de la Section sur le Montage, comme le montre la figure suivante :
Insérer la description de l'image ici

  Modifier cela équivaut à modifier la configuration de la ressource, et elle ne doit pas être modifiée elle-même. Par conséquent, je pense personnellement qu'il y a FAnimMontageInstance::GetNextSection()un problème avec l'écriture de cette fonction. Elle devrait renvoyer la NextSection sur l'instance de Montage au lieu de la valeur non ajustée. configuration de la ressource elle-même.

Je suppose que tu aimes

Origine blog.csdn.net/Bob__yuan/article/details/117357991
conseillé
Classement