【UE4】Notificación de animación

AnimNotifyEste artículo resume el análisis del código fuente y el resumen de problemas de las notificaciones de animación (estado de notificación de animación AnimNotifyState)    en UE4 .

1. Introducción a las notificaciones animadas

   Las notificaciones de animación son notificaciones que se configuran principalmente en animación ( Animation) o montaje de animación ( ) en UE4 . La notificación se activa cuando se ejecuta la animación. AnimMontageHay dos tipos de notificaciones:

  1. AnimNotify(notificación animada) – sin duración; solo Notifymétodo; ver detallesAnimNotify.h
  2. AnimNotifyState(Estado de notificación de animación): tiene una duración ( ) TotalDuration; tiene NotifyBegin,, método; consulte para obtener más detallesNotifyTickNotifyEndAnimNotifyState.h

  Para AnimNotifyState, la descripción oficial dice:

  • Se garantiza que comenzará desde Notificar evento de inicio
  • Se garantiza que finalizará a partir del evento Notificar fin
  • Se garantiza que el tick de notificación se encuentre entre los eventos de inicio de notificación y fin de notificación.
  • No se puede garantizar el orden de Anim Notify (normal o estatal) . Si dos AnimNotifyStates están conectados de extremo a extremo, no hay garantía de que el final de la notificación anterior sea anterior al comienzo de la siguiente. Aquí solo se deben realizar operaciones separadas que no estén relacionadas con otras notificaciones. original:

No se garantiza el orden entre diferentes Notificaciones Anim (normales o estatales).
Si coloca dos estados de Notificación Anim uno al lado del otro, no se garantiza que el primero termine antes de que comience el siguiente.
Utilice esto únicamente para acciones individuales que no dependan de otras Notificaciones.

  Es decir, los dos AnimNotifyStates, A y B, no pueden garantizar que el orden de ejecución sea:

A.Comienzo --> A.Fin --> B.Comienzo --> B.Fin

  En cambio podría ser:

A.Comienzo --> B.Comienzo --> A.Fin --> B.Fin

Además, vale la pena señalar:

  1. Las notificaciones de animación se ejecutarán de forma predeterminada en DedicateServer, el terminal de control principal y el segmento de simulación. Si no desea ejecutarlo en DS, puede desmarcar la opción a continuación en las opciones.
    Insertar descripción de la imagen aquí

  2. Para notificaciones en el mismo montaje o animación, el puntero es el mismo , por lo que si se almacenan datos en la notificación y dos roles idénticos liberan el mismo montaje al mismo tiempo, dos notificaciones modificarán el mismo dato;

  3. Varias notificaciones del mismo tipo en el mismo montaje tienen punteros diferentes. Lo que sale de GetName() es xxx_C_1, xxx_C_2 así

2. Activación de notificaciones animadas

  La activación de los métodos anteriores de notificación de animación se activa principalmente UAnimInstance::TriggerAnimNotifiesdesde (hay otros que se analizarán más adelante).

2.1 TriggerAnimNotifica análisis del código fuente

  En Tick, ( tipo) AnimInstanceagregará las notificaciones de animación (AnimNotify, AnimNotifyState) de este cuadro y luego ejecutará todas las notificaciones de animación de este cuadro en TriggerAnimNotifies. El orden de ejecución es:NotifyQueueAnimNotifiesFAnimNotifyQueue

  1. todos AnimNotify_Notify
  2. Todos los anteriores siguen ahí, pero este marco ya no AnimNotifyStateestá.NotifyEnd
  3. El marco anterior no está allí, se agregó recientemente en este marco AnimNotifyState.NotifyBegin
  4. AnimNotifyStateTodo este cuadro NotifyTick(es decir, el mismo cuadro de Begin marcará)

  Para AnimNotify, solo existe Notify, por lo que es relativamente simple y no se discutirá. A continuación, nos AnimNotifyStatecentraremos en el análisis:
   AnimNotifyStateel núcleo del disparador consta de cuatro matrices:

  1. ActiveAnimNotifyState: Graba el fotograma anterior en Activo AnimNotifyState(denominado Acto)
  2. NotifyQueue.AnimNotifies: Graba todas las notificaciones en este montaje de fotograma (incluidos Notify y NotifyState)
  3. NewActiveAnimNotifyState(Parcial): Calcula cuáles son los nuevos NotifyStates (NewAct para abreviar) de este frame hasta 1 y 2
  4. NotifyStateBeginEvent(Parcial): solo se usa para activar un nuevo NotifyStateNotifyBegin
2.2 TriggerAnimNotifica el análisis completo del proceso
1. Crear NewActiveAnimNotifyState
// Array that will replace the 'ActiveAnimNotifyState' at the end of this function. 
TArray<FAnimNotifyEvent> NewActiveAnimNotifyState; 
NewActiveAnimNotifyState.Reserve(NotifyQueue.AnimNotifies.Num());
2.El paso más crítico

  Elimina ActiveAnimNotifyStatelos que todavía están en este cuadro, y los restantes son los que estaban en el cuadro anterior y no están en este cuadro, y se usan para activadores posteriores; pon los NotifyEndque
  no están en el cuadro anterior y están en este marco, NotifyStateBeginEventy se utilizan en el futuro.Disparar NotifyBegin,
  desencadenar todo AnimNotify;

// AnimNotifyState freshly added that need their 'NotifyBegin' event called. 
TArray<const FAnimNotifyEvent *> NotifyStateBeginEvent; 
 
for (int32 Index=0; Index<NotifyQueue.AnimNotifies.Num(); Index++) 
{
    
     
    if(const FAnimNotifyEvent* AnimNotifyEvent = NotifyQueue.AnimNotifies[Index].GetNotify()) 
    {
    
    
        // AnimNotifyState 
        if (AnimNotifyEvent->NotifyStateClass) 
        {
    
     
            if (!ActiveAnimNotifyState.RemoveSingleSwap(*AnimNotifyEvent, false)) 
            {
    
    
                // Queue up calls to 'NotifyBegin', so they happen after 'NotifyEnd'. 
                NotifyStateBeginEvent.Add(AnimNotifyEvent);
            }
            NewActiveAnimNotifyState.Add(*AnimNotifyEvent);
            continue;
        }
 
        // Trigger non 'state' AnimNotifies 
        TriggerSingleAnimNotify(AnimNotifyEvent);
    }
}
3. Activar todos los NotifyEnds en Act
// Send end notification to AnimNotifyState not active anymore. 
for (int32 Index = 0; Index < ActiveAnimNotifyState.Num(); ++Index) 
{
    
     
    const FAnimNotifyEvent& AnimNotifyEvent = ActiveAnimNotifyState[Index]; 
    if (AnimNotifyEvent.NotifyStateClass && ShouldTriggerAnimNotifyState(AnimNotifyEvent.NotifyStateClass)) 
    {
    
     
        TRACE_ANIM_NOTIFY(this, AnimNotifyEvent, End); 
        AnimNotifyEvent.NotifyStateClass->NotifyEnd(
        	SkelMeshComp, 
        	Cast<UAnimSequenceBase>(AnimNotifyEvent.NotifyStateClass->GetOuter())); 
    } 
    // blabla ActiveAnimNotifyState 是否已经失效检查
}
4. Activar todos los NotifyBegin en NotifyStateBeginEvent
// Call 'NotifyBegin' event on freshly added AnimNotifyState. 
for (const FAnimNotifyEvent* AnimNotifyEvent : NotifyStateBeginEvent) 
{
    
     
    if (ShouldTriggerAnimNotifyState(AnimNotifyEvent->NotifyStateClass)) 
    {
    
     
        TRACE_ANIM_NOTIFY(this, *AnimNotifyEvent, Begin); 
        AnimNotifyEvent->NotifyStateClass->NotifyBegin(
        	SkelMeshComp, 
        	Cast<UAnimSequenceBase>(AnimNotifyEvent->NotifyStateClass->GetOuter()), 
        	AnimNotifyEvent->GetDuration()); 
    } 
}
5. Mover temperatura
// Switch our arrays. 
ActiveAnimNotifyState = MoveTemp(NewActiveAnimNotifyState);

  Dé NewAct a Act, porque Act es una variable miembro y NewAct es una variable local.

6. Activar todos los NotifyTicks en la ley
// Tick currently active AnimNotifyState 
for(const FAnimNotifyEvent& AnimNotifyEvent : ActiveAnimNotifyState) 
{
    
     
    if (ShouldTriggerAnimNotifyState(AnimNotifyEvent.NotifyStateClass)) 
    {
    
     
        TRACE_ANIM_NOTIFY(this, AnimNotifyEvent, Tick); 
        AnimNotifyEvent.NotifyStateClass->NotifyTick(
        	SkelMeshComp, 
        	Cast<UAnimSequenceBase>(AnimNotifyEvent.NotifyStateClass->GetOuter()), 
        	DeltaSeconds); 
    }
}

Además, vale la pena señalar:

  1. Dado que NotifyEndel método para juzgar si se debe activar es juzgar si el cuadro anterior de una notificación todavía está allí y este cuadro no está allí , no se activará cuando se parezca al último cuadro de la notificación, NotifyEndes decir, dos notificaciones conectadas. De extremo a extremo definitivamente Los siguientes comienzan primero y los que están delante del siguiente cuadro terminan. Ni siquiera necesitan estar conectados de extremo a extremo, pero el principio y el final están en el mismo cuadro (como se muestra De manera similar, los siguientes comienzan primero y los que están delante del siguiente cuadro finalizan.
    Insertar descripción de la imagen aquí

3. Resumen de problemas con las notificaciones animadas

  Ver detalles

Supongo que te gusta

Origin blog.csdn.net/Bob__yuan/article/details/115520679
Recomendado
Clasificación