linefx y por qué es tan importante?Imagina que, antes de aplicar cualquier efecto, Kara Effector escanea tu script y crea un gran archivador. Cada línea de diálogo se convierte en una carpeta detallada con toda su información: texto, tiempos, tamaño, sílabas, etc.
linefx es el archivador completo. Es una tabla que contiene todas las carpetas (líneas de diálogo del script) que pueden ser procesadas. linefx[11] es la undécima línea de tu script (asumiendo que es un diálogo), linefx[12] la duodécima, y así sucesivamente.l (o line) es la carpeta que tienes abierta ahora mismo. Es la línea del lote seleccionado que se está procesando en este instante.l_i es el número de la carpeta que tienes abierta en relación con tu selección. Te dice si estás en la carpeta 1, 2, 3, etc., de las que elegiste procesar.El poder de linefx es que, mientras estás trabajando en la carpeta actual (l), puedes echar un vistazo a cualquier otra carpeta del archivador usando su número de línea original (ii). Esto rompe el aislamiento de procesar una línea a la vez y permite que los efectos de una línea reaccionen o dependan de las propiedades de otras.
Para manipular las líneas de diálogo, el Effector crea una base de datos interna (linefx) y luego itera sobre tu selección. Comprender la diferencia entre el contador de este bucle (l_i) y el número de línea original en la tabla linefx (ii) es fundamental.
| Variable | ¿Qué es? | Ejemplo de Uso |
|---|---|---|
linefx |
La base de datos completa. Es una tabla que contiene todos los objetos de línea de diálogo del script. Se genera una sola vez al inicio. | l = linefx[ii] (Así es como el Effector asigna la línea actual l internamente). Rara vez la usarás directamente. |
l (o line) |
El objeto que representa la línea actual que se está procesando en el bucle. Contiene todas sus propiedades (tiempos, texto, dimensiones, etc.). | l.start_time para obtener el tiempo de inicio de la línea actual. |
l_i |
El contador del lote actual. Es la posición de la línea dentro del grupo que se está procesando. Siempre va de 1 a l_n. |
Si procesas 5 líneas, l_i tomará los valores 1, 2, 3, 4, y 5 sucesivamente. |
l_n |
El número total de líneas en el lote que se está procesando. Su valor es constante durante todo el bucle. | Si procesas 5 líneas, l_n siempre será 5. |
ii |
El índice de la línea actual dentro de la tabla linefx. Es la "llave" que necesitas para acceder a cualquier línea en el archivador. |
linefx[ii - 1] te da acceso al objeto de la línea de diálogo anterior en el script. |
linefx[ii]Cada elemento de la tabla linefx es un objeto de línea completo. Puedes acceder a las mismas propiedades que usas con l, pero referenciando a otra línea mediante su índice ii.
linefx[ii].start_time, linefx[ii].end_time, linefx[ii].durationlinefx[ii].left, linefx[ii].center, linefx[ii].width, linefx[ii].top, linefx[ii].middle, linefx[ii].heightlinefx[ii].text_stripped, linefx[ii].syl (tabla de sílabas), linefx[ii].char (tabla de caracteres)linefx[ii].styleref.name, linefx[ii].styleref.color1, etc.linefxLa navegación se hace combinando linefx, l_i y ii.
Esto es útil para efectos de cadena o dominó.
Código: linefx[ii - 1]
¡Seguridad primero! Si estás en la primera línea del lote (l_i es 1), puede que no quieras que interactúe con la línea anterior si no fue seleccionada. La condición debe hacerse sobre el contador del lote.
-- En la casilla "Line Start Time"
return l_i > 1 and linefx[ii - 1].end_time or l.start_time
Perfecto para efectos que se anticipan a lo que viene.
Código: linefx[ii + 1]
¡Seguridad primero! Similarmente, comprueba si no eres la última línea del lote (l_i < l_n).
-- En la casilla "Pos 'x'"
if l_i < l_n then
return linefx[ii + 1].center
else
return syl.center
end
Útil para establecer un punto de referencia global. Nota: Esto es avanzado, ya que requiere conocer los índices ii de la primera y última línea del lote. Para un principiante, es más fácil usar el método del Ejemplo 3.
if l_i == 1 then ....if l_i == l_n then ....Objetivo: Cada línea comienza su animación justo cuando la línea anterior del lote termina por completo.
Line Start Time-- Si no es la primera línea del lote (l_i > 1), toma el tiempo final de la línea anterior.
-- Si es la primera línea, usa el tiempo de inicio normal de la línea.
return l_i > 1 and linefx[ii - 1].end_time or l.start_time
l_i > 1: La condición de seguridad para la primera línea del lote seleccionado.linefx[ii - 1].end_time: Accedemos al archivador, pedimos la carpeta anterior a la actual (ii - 1), y leemos su end_time. Esto asume que las líneas procesadas son consecutivas en el script.or l.start_time: Es el else. Si la condición es falsa, se ejecuta esto.Objetivo: El final de cada línea se mueve suavemente para alinearse con el principio de la siguiente línea del lote.
Pos "x" y Pos "y"Pos "x":-- Si hay una línea siguiente en el lote, el destino final (move_x2) será su 'left'.
-- Si no, el destino final será su propia posición 'right'.
return syl.center, (l_i < l_n and linefx[ii + 1].left or l.right)
Pos "y":-- Similar al anterior, pero para la coordenada Y.
return syl.middle, (l_i < l_n and linefx[ii + 1].middle or l.middle)
Times Move-- La animación de movimiento ocurre durante el último 20% de la duración de la sílaba.
return syl.dur * 0.8, syl.dur
\move(x1, y1, x2, y2, t1, t2).l_i < l_n: La condición de seguridad para la última línea del lote.linefx[ii + 1].left, es decir, la posición izquierda de la línea físicamente siguiente en el script.Objetivo: Todas las sílabas de todas las líneas seleccionadas tienen el mismo ancho que la sílaba más ancha de todo el script.
Variables [fx]:-- Este bucle es costoso, así que lo calculamos UNA SOLA VEZ usando remember
function find_max_width()
local max_w = 0
-- Recorremos TODAS las líneas de diálogo del script
for i = 1, #linefx do
if linefx[i] then -- Comprobación de seguridad
-- Recorremos TODAS las sílabas de cada línea
for k = 1, linefx[i].syl.n do
local current_syl = linefx[i].syl[k]
if current_syl.width > max_w then
max_w = current_syl.width
end
end
end
end
return max_w
end
max_syl_width = j == 1 and l_i == 1 and remember("max_w", find_max_width()) or recall.max_w
Return [fx]:-- Usamos \fscx para escalar cada sílaba
-- El factor es el ancho máximo dividido por el ancho actual de la sílaba
local scale_factor = 100 * var.max_syl_width / syl.width
return "{\\fscx" .. scale_factor .. "}" .. syl.text
find_max_width itera sobre linefx (todas las líneas de diálogo). Esto es crucial para un valor verdaderamente global.j == 1 and l_i == 1) y guardamos el resultado.Return, para cada sílaba, calculamos el factor de escala y lo aplicamos.Objetivo: Cada sílaba se mueve a la posición donde estaba la misma sílaba en la línea anterior.
Pos "x" y Pos "y"Pos "x":-- Posición inicial: centro de la sílaba actual
-- Posición final: centro de la sílaba 'syl.i' de la línea anterior
return syl.center, (l_i > 1 and linefx[ii - 1].syl[syl.i] and linefx[ii - 1].syl[syl.i].center or syl.center)
Pos "y":return syl.middle, (l_i > 1 and linefx[ii - 1].syl[syl.i] and linefx[ii - 1].syl[syl.i].middle or syl.middle)
l_i > 1: Comprobamos que no sea la primera línea del lote.linefx[ii - 1].syl[syl.i]: Comprobación de seguridad. Verifica que la línea anterior exista y que tenga una sílaba en el índice syl.i. Si alguna falla, la sílaba se queda en su sitio.linefx[ii - 1].syl[syl.i].center: Accedemos al archivador (linefx), a la carpeta anterior en el script ([ii - 1]), a su lista de sílabas (.syl), a la sílaba con el mismo índice que la actual ([syl.i]), y finalmente a su propiedad .center.if l_i > 1 then ... y if l_i < l_n then ....remember para cálculos globales. Si necesitas una propiedad que depende de un bucle sobre linefx (como el ancho máximo del Ejemplo 3), haz el cálculo solo una vez y guárdalo con remember para no ralentizar el script.aegisub.debug.out. Si algo no funciona, puedes imprimir los valores en la ventana de depuración (Automation -> Log Window).
_ = aegisub.debug.out("Lote " .. l_i .. " (original: " .. ii .. "), Ancho: " .. l.width .. "\\n")linefx es una tabla de líneas indexada por su número de aparición en el script. Para acceder a las sílabas de una línea específica, debes usar linefx[ii].syl[k].Dominar linefx te permite pasar de crear efectos aislados a diseñar coreografías complejas que abarcan múltiples líneas, todo desde la comodidad de la GUI de Kara Effector.