samp.directory
← Scripts y librerías

by-not/samp-cameditor

Filterscript para SA-MP que permite crear y editar cámaras cinematográficas in-game (posición, mira e interpolación) en modo Normal o Secuencial (vuelo + waypoints), con guardado de proyectos, preview y exportación automática a código Pawn.

Herramienta★ 1actualizado ago 2026MITPawn
Abrir en GitHub

README.md


Tabla de contenidos


Características

  • Dos tipos de proyecto:
    • Normal: cámaras independientes, cada una editada a mano con un gizmo 3D (objeto arrastrable), igual que el clásico cameraeditor.pwn.
    • Secuencial: vuelas libremente por el mapa marcando waypoints (A→B→C→D...) que luego se reproducen en orden con interpolación y tiempos configurables.
  • Modo de vuelo propio con aceleración progresiva, boost y velocidad ajustable en caliente (sin necesidad de un vehículo ni de EditObject).
  • Persistencia en disco: cada proyecto se guarda como archivo de texto en scriptfiles/cameditor/ y puede recargarse después desde el menú.
  • Preview in-game de las secuencias, con soporte de loop (finito o infinito).
  • Exportación a Pawn: genera automáticamente el código (InterpolateCameraPos, InterpolateCameraLookAt, timers encadenados, etc.) para integrar la cámara final en tu gamemode.
  • Todo se maneja con diálogos nativos de SA-MP (DIALOG_STYLE_TABLIST_HEADERS, DIALOG_STYLE_LIST, DIALOG_STYLE_INPUT, DIALOG_STYLE_MSGBOX) y comandos de chat.

Requisitos e instalación

  1. Copia CamEditor.pwn a la carpeta filterscripts/ de tu servidor SA-MP.

  2. Compílalo con el compilador Pawn de tu servidor (usa #include <a_samp>, no requiere includes externos ni streamer).

  3. Agrega el filterscript a tu server.cfg:

    filterscripts CamEditor
    
  4. Reinicia el servidor. En la consola aparecerá el banner de CamEditor y se creará automáticamente la carpeta scriptfiles/cameditor/ junto con el índice de proyectos (_index.txt) si no existen.

No se requieren plugins ni includes de terceros; todo el código usa exclusivamente funciones nativas de a_samp.

Conceptos básicos

ConceptoDescripción
ProyectoUn archivo guardado (.ncam para Normal, .cam para Secuencial) identificado por un nombre único.
Cámara (Normal)Punto de posición + punto de mira, con interpolación opcional hacia una segunda posición/mira.
Waypoint (Secuencial)Un punto de posición + mira capturado mientras vuelas en modo grabación.
Tramo / SegmentoEl trayecto entre dos waypoints consecutivos; cada uno puede tener tiempos de movimiento/rotación propios o heredar los globales del proyecto.
GizmoObjeto 3D que representa visualmente una posición o mira editable arrastrándolo con EditPlayerObject.

Cada jugador tiene su propia sesión: puede tener un único proyecto abierto a la vez (Normal o Secuencial), y sus datos se autoguardan al desconectarse o al cerrar el proyecto desde el menú.


Modo Normal

Pensado para cámaras estáticas o con una única interpolación (por ejemplo, una cámara de introducción, un cutscene corto, una vista de una base, etc.). Cada cámara se compone de:

  • Posición (gizmo azul, objeto 367) y punto de mira (gizmo, objeto 1318).
  • Opcionalmente, una posición interpolada y/o mira interpolada (gizmos secundarios en rojo) hacia donde la cámara se moverá con InterpolateCameraPos / InterpolateCameraLookAt.
  • Un tiempo de posición y tiempo de mira (en segundos, 1–600) que controla la duración de esa interpolación.

Modos de interpolación disponibles (/camint):

ModoEfecto
Sin interpolarCámara fija: solo se usa posición + mira base.
Interpolar posiciónLa cámara se desplaza desde la posición base hacia la posición interpolada.
Interpolar miradaEl punto de mira se desplaza desde la mira base hacia la mira interpolada.
Interpolar ambasSe interpolan posición y mira simultáneamente.

Comandos del modo Normal

Requieren tener un proyecto Normal abierto (/cameditor → Nuevo proyecto → Normal, o cargar uno existente).

ComandoDescripción
/newcamCrea una nueva cámara en tu posición y mirada actuales.
/camint [id]Abre el diálogo para elegir el modo de interpolación de la cámara id.
/editcam [id]Activa el editor de objetos (EditPlayerObject) sobre el gizmo de posición de la cámara id.
/editlook [id]Igual, pero sobre el gizmo del punto de mira.
/ieditcam [id]Edita la posición interpolada (solo si la cámara interpola posición).
/ieditlook [id]Edita la mira interpolada (solo si la cámara interpola mirada).
/camtime [id] [segundos]Fija la duración de la interpolación de posición (1–600s).
/looktime [id] [segundos]Fija la duración de la interpolación de mirada (1–600s).
/playcam [id]Reproduce la cámara id en modo espectador (con interpolación, si aplica).
/stopcamSale del modo espectador y vuelve a tu posición original.
/exportcam [id]Añade al archivo de exportación el código Pawn equivalente a la cámara id.

[id] siempre se refiere al número mostrado en el menú (empieza en 1). Internamente se resta 1 para obtener el índice real.

Flujo de trabajo típico (Normal)

  1. /cameditor → Nuevo proyecto → nombre → Normal.
  2. Colócate donde quieras la cámara y ejecuta /newcam.
  3. /editcam 1 y mueve el gizmo azul a la posición deseada; confirma con el editor de objetos de SA-MP.
  4. /editlook 1 para ajustar hacia dónde mira.
  5. (Opcional) /camint 1 → elegir "Interpolar posición/mirada/ambas", luego /ieditcam 1 y/o /ieditlook 1 para definir el punto final, y /camtime//looktime para la duración.
  6. /playcam 1 para previsualizar, /stopcam para salir.
  7. /exportcam 1 para generar el código Pawn en scriptfiles/cameditor/export_<proyecto>.txt.
  8. Desde el menú del proyecto, Guardar y cerrar (o simplemente desconectarte: se autoguarda).

Modo Secuencial

Pensado para recorridos de cámara tipo flythrough: vuelas libremente, marcas puntos de paso y el sistema reproduce una interpolación continua entre cada par de waypoints consecutivos, con tiempos y easing configurables por proyecto o por tramo individual.

Controles de vuelo (grabación)

Al elegir Grabar waypoints desde el menú del proyecto secuencial, el jugador entra en modo espectador adjunto a un objeto volador:

TeclaAcción
W A S D / flechasMover la cámara (soporta diagonales).
LSHIFT (Jump)Subir.
C (Crouch)Bajar.
ESPACIO (mantener)Boost de velocidad (x2.5) mientras se mantiene pulsado.
QBajar la velocidad base (multiplicador, mínimo x0.25).
ESubir la velocidad base (multiplicador, máximo x4.0, pasos de 0.25).
Click izquierdo / LCTRL (Fire)Marcar un waypoint en la posición y mira actuales.
ENTER (Secondary Attack)Finalizar la grabación (requiere ≥2 waypoints).
Click derecho (Handbrake/Aim)Deshacer el último waypoint marcado.
NUM1 / click central (Submission)Cancelar la grabación completa.

Fuera del modo de vuelo, mientras se reproduce un preview, ESPACIO (Sprint) lo cancela y regresa la cámara al jugador.

El movimiento se procesa en OnPlayerUpdate con un throttle de 100 ms (se reemite MoveCamera() cada 100 ms mientras una tecla de dirección se mantiene presionada) y una aceleración progresiva (FLY_ACCEL_RATE = 0.03 por tick hasta 1.0), igual que el comportamiento de la beta original en la que se basa este sistema.

Ajustes de tiempo y reproducción

Desde Configurar tiempos en el menú del proyecto:

AjusteRangoDescripción
Movimiento global100–60000 msDuración por defecto del desplazamiento de cada tramo.
Rotación global100–60000 msDuración por defecto del giro de mira de cada tramo.
Delay entre tramos0–10000 msPausa entre el fin de un tramo y el inicio del siguiente.
EasingLineal / Ease-In / Ease-Out / Ease-InOutCurva de interpolación aplicada a todos los tramos (constantes CAMERA_MOVE/CAMERA_CUT de SA-MP).
Tiempos por tramo—Solo visible si hay más de 2 waypoints; permite sobrescribir movimiento/rotación de un tramo específico (0 = usar el valor global).

Desde Ajustes de loop:

  • Activar/Desactivar el loop.
  • Repeticiones: 0 = infinito, 1–99 = número de veces que se repite la secuencia completa.

Flujo de trabajo típico (Secuencial)

  1. /cameditor → Nuevo proyecto → nombre → Secuencial.
  2. En el menú del proyecto, elige Grabar waypoints: entras en modo vuelo.
  3. Vuela y marca al menos 2 puntos con click izquierdo; usa click derecho para corregir errores.
  4. ENTER para finalizar la grabación (te lleva directo al menú de tiempos).
  5. Ajusta movimiento/rotación/delay/easing globales, y si lo necesitas, sobreescribe tramos individuales.
  6. Ver preview desde el menú principal del proyecto para revisar el resultado en modo espectador.
  7. Activa loop si quieres que la secuencia se repita.
  8. Exportar a PAWN para obtener el código final.
  9. Guardar y cerrar (o desconectarte, que autoguarda).

Menú principal (/cameditor)

Comando único de entrada al sistema. Su comportamiento depende del estado actual del jugador:

  • Si está grabando waypoints: muestra un recordatorio de teclas (ENTER=finalizar, NUM1=cancelar) en vez de abrir el menú.

  • Si está en preview: cancela el preview inmediatamente.

  • En cualquier otro caso: abre el menú principal con estas opciones:

    OpciónAcción
    Nuevo proyectoPide un nombre (solo letras, números y _; el resto de caracteres se sustituye por _, máx. 31 caracteres) y luego el tipo (Normal / Secuencial).
    Proyectos NormalesLista los proyectos .ncam guardados (hasta 20) para cargarlos.
    Proyectos SecuencialesLista los proyectos .cam guardados (hasta 20) para cargarlos.
    AyudaControles de vuelo, comandos del modo Normal y explicación de los dos tipos de proyecto.

Al salir del menú de un proyecto abierto sin elegir "Guardar y cerrar" explícitamente (por ejemplo cerrando el diálogo), el script también autoguarda el proyecto antes de volver al menú principal.


Exportación a código Pawn

Ambos modos generan archivos de texto dentro de scriptfiles/cameditor/, listos para copiar y pegar en tu gamemode/filterscript final.

Modo Normal — export_<proyecto>.txt

Cada /exportcam [id] añade (modo io_append) un bloque como este:

SetPlayerCameraPos(playerid, X, Y, Z);
SetPlayerCameraLookAt(playerid, LX, LY, LZ);
// Si la cámara interpola posición:
InterpolateCameraPos(playerid, X, Y, Z, IX, IY, IZ, TIEMPO_MS, CAMERA_MOVE);
// Si la cámara interpola mirada:
InterpolateCameraLookAt(playerid, LX, LY, LZ, ILX, ILY, ILZ, TIEMPO_MS, CAMERA_MOVE);
// -----------------------------------------------------

Modo Secuencial — export_<proyecto>.txt

Sobrescribe (modo io_write) un archivo completo con una cadena de funciones public encadenadas mediante SetTimerEx, una por cada tramo:

// CamEditor v1.0 - Exportacion de proyecto secuencial: <nombre>
// Se usan timers encadenados para reproduccion secuencial.
// Llama a PlayCam_<nombre>(playerid) para iniciar la reproduccion.

forward _Cam<nombre>_Seg1(playerid);
// ... una declaracion forward por cada tramo intermedio ...

stock PlayCam_<nombre>(playerid)
{
    SetCameraBehindPlayer(playerid);
    InterpolateCameraPos(playerid, X0, Y0, Z0, X1, Y1, Z1, MOVE_MS, EASING);
    InterpolateCameraLookAt(playerid, LX0, LY0, LZ0, LX1, LY1, LZ1, ROT_MS, EASING);
    SetTimerEx("_Cam<nombre>_Seg1", DURACION + DELAY, false, "i", playerid);
}

public _Cam<nombre>_Seg1(playerid)
{
    InterpolateCameraPos(playerid, ...);
    InterpolateCameraLookAt(playerid, ...);
    SetTimerEx("_Cam<nombre>_Seg2", DURACION + DELAY, false, "i", playerid);
}
// ... una función por cada tramo, la última no encadena timer ...

El código exportado no incluye loop; el loop es solo una función del preview in-game. Si necesitas que la secuencia final se repita, deberás añadir esa lógica manualmente al integrar el código.


Formato de los archivos guardados

Todos los archivos se guardan como texto plano dentro de scriptfiles/cameditor/ (carpeta definida por SCRIPTFILES_DIR).

Índice general — _index.txt

Una línea por proyecto, con el formato:

nombre|tipo

donde tipo es 0 (Secuencial) o 1 (Normal). Se actualiza automáticamente al crear (AddToIndex) o eliminar (RemoveFromIndex) un proyecto, y se usa para poblar las listas de "Proyectos Normales/Secuenciales" del menú (máx. 20 por tipo, MAX_PROJECT_FILES).

Proyecto Secuencial — <nombre>.cam

#VERSION=1
#NAME=<nombre>
#GLOBAL_MOVE=<ms>
#GLOBAL_ROT=<ms>
#DELAY=<ms>
#LOOP=<0|1>
#LOOP_COUNT=<n>
#EASING=<0-3>
#WP_COUNT=<n>
WP,<idx>,<x>,<y>,<z>,<lx>,<ly>,<lz>
...
SEG,<idx>,<move_ms>,<rot_ms>
...
  • Una línea WP,... por waypoint (posición + mira, 4 decimales).
  • Una línea SEG,... por tramo, solo con overrides (0 = usar el valor global).

Proyecto Normal — <nombre>.ncam

#VERSION=1
#NAME=<nombre>
#CAM_COUNT=<n>
CAM,<idx>,<interp>,<posx>,<posy>,<posz>,<intposx>,<intposy>,<intposz>,<postime>,<lookx>,<looky>,<lookz>,<intlookx>,<intlooky>,<intlookz>,<looktime>
...

Una línea CAM,... por cada cámara creada (interp: 0=ninguna, 1=posición, 2=mirada, 3=ambas).


Estructura interna del script

Referencia rápida de los callbacks y bloques principales, útil para quien quiera modificar o extender el script:

Callback / bloqueResponsabilidad
OnFilterScriptInit / OnFilterScriptExitBanner de consola, creación del índice si no existe, inicialización/autoguardado de todos los jugadores conectados.
OnPlayerConnect / OnPlayerDisconnectInicializa/limpia la sesión del jugador; autoguarda al desconectar.
OnPlayerCommandTextEnrutamiento de /cameditor y todos los comandos del modo Normal.
OnDialogResponseManeja todos los diálogos (menú principal, listas, configuración de tiempos, loop, ayuda, confirmaciones de borrado, etc.) mediante los IDs DIALOG_* definidos al inicio del archivo.
OnPlayerKeyStateChangeTeclas del modo de vuelo (boost, velocidad, marcar/deshacer/finalizar/cancelar waypoint) y cancelación de preview con ESPACIO.
OnPlayerUpdateMotor de movimiento del modo vuelo (reissue de MoveCamera() cada 100 ms mientras se mantiene una dirección).
OnPlayerEditObjectConfirma o cancela el arrastre de los gizmos del modo Normal y persiste los cambios de posición/mira.
_CamEd_PlaySeg (timer encadenado)Motor de reproducción del preview Secuencial, tramo por tramo, con soporte de loop.
_CamEd_PlayNormal (timer)Aplica posición/mira (e interpolación) de una cámara Normal en modo espectador.

Enumeraciones de datos

  • E_WAYPOINT — posición + mira de un waypoint.
  • E_SEGMENT — overrides de tiempo/easing de un tramo.
  • E_PROJECT — metadatos del proyecto Secuencial (nombre, conteo, tiempos globales, loop, easing).
  • E_NCAM — datos completos de una cámara Normal (posición, posición interpolada, mira, mira interpolada, tiempos).
  • E_FLY — estado del modo de vuelo por jugador (objeto, dirección, aceleración, multiplicador de velocidad, boost).
  • E_SESSION — estado general de sesión (estado actual, tipo de proyecto abierto, timer activo, progreso de preview/loop, edición en curso).

Todos los arreglos están indexados por playerid, así que cada jugador mantiene su propio proyecto en edición de forma completamente aislada.


Límites y configuración

Todos ajustables al principio de CamEditor.pwn:

ConstanteValor por defectoSignificado
MAX_WAYPOINTS30Waypoints máximos por proyecto Secuencial.
MAX_NCAMS40Cámaras máximas por proyecto Normal.
MAX_PROJECT_NAME32Longitud máxima del nombre de un proyecto.
MAX_PROJECT_FILES20Proyectos listables por tipo en el menú.
DEFAULT_MOVE_MS / DEFAULT_ROT_MS3000 msTiempos globales por defecto (Secuencial).
DEFAULT_DELAY_MS300 msDelay entre tramos por defecto.
DEFAULT_POSTIME / DEFAULT_LOOKTIME1000 msTiempos de interpolación por defecto (Normal).
FLY_MOVE_SPEED100.0Velocidad base del modo vuelo.
FLY_ACCEL_RATE0.03Incremento de aceleración por tick.
FLY_MOVE_THROTTLE_MS100 msFrecuencia de reemisión de MoveCamera().
FLY_SPEED_MULT_MIN / MAX / STEP0.25 / 4.0 / 0.25Rango y paso del multiplicador de velocidad (Q/E).
FLY_BOOST_MUL2.5Multiplicador de velocidad con ESPACIO mantenido.
CAM_LOOK_DISTANCE5.0Distancia hacia adelante usada para calcular la mira al marcar un waypoint.
SCRIPTFILES_DIR"cameditor"Carpeta de guardado dentro de scriptfiles/.

Los rangos de los diálogos de tiempo (segundos, milisegundos, repeticiones de loop) están además acotados en el propio manejo de cada diálogo (por ejemplo, tiempos de posición/mira del modo Normal: 1–600 s; movimiento/rotación global: 100–60000 ms; repeticiones de loop: 0–99).


Preguntas frecuentes / notas

Leer el resto en GitHub

filterscriptopenmppawnpawnscriptssa-mpsa-mp-developmentsa-mp-filterscriptsa-mp-librarysa-mp-serversamp

Esta página se genera con lo que GitHub publica sobre el repositorio. samp.directory no aloja el código. Informar de un problema con esta ficha