JME3 cinematics (com.jme.cinematic) allow you to remote control nodes and cameras in a 3D game. You use cinematics to script and record scenes. Use it for example to create cutscenes of your game.
Cinematics are implemented as AppStates. Attach the scene that you want to be visible in the cinematic to one Node. You create a Cinematic object, and add individual CinematicEvents to it.
Cinematic cinematic = new Cinematic(sceneNode, duration); cinematic.addCinematicEvent(triggerTime, cinematicEvent);
cinematic.pause()
and cinematic.play();
There are several kinds of cinematic events:
CinematicEvent | Description |
---|---|
MotionTrack | Use this to move a Spatial non-linearly over time. A motionPath is a list of several waypoints added to a MotionPath. The path is interpolated using Catmull-Rom Splines between waypoints. |
PositionTrack | Use this to move a Spatial linearly over time. It translates the Spatial to a destination in the given amount of time by linearly interpolating the positions. |
RotationTrack | Use this to change the rotation of a Spatial over time. It rotates the Spatial in the given amount of time by linearly interpolating the rotation. |
ScaleTrack | Use this to change the size of a Spatial over time. It scales the Spatial in the given amount of time by linearly interpolating the scale. |
SoundTrack | Use this to play a sound at a given time for the given duration. |
GuiTrack | Displays a Nifty GUI at a given time for the given duration. Use it to display subtitles or HUD elements. Bind the Nifty GUI XML to the cinematic using cinematic.bindUi("path/to/nifty/file.xml"); |
AnimationTrack | Use this to start playing a model animation at a given time (a character walking animation for example) |
We will add more types of track implementions over time.
Each CinematicEvent supports the following methods to control the event.
CinematicEvent method | Usage |
---|---|
play() | Starts playing the cinematic. |
stop() | Stops playing the cinematic. |
pause() | Pauses the cinematic. |
Those methods, must be called on the Cinematic and are propagated to the events. Don't use them directly on a sub cinematic event
A motion track is made up of MotionPaths.
MotionPath path = new MotionPath();
MotionPath Method | Usage |
---|---|
setCycle(true) | Sets whether the motion along this path should be closed (true) or not (false). |
addWayPoint(vector) | Adds individual waypoints to this path. The order is relevant. |
removeWayPoint(vector) removeWayPoint(index) | Removes individual waypoints from this path. You can specify a vector or the integer index. |
setCurveTension(0.83f) | Sets the tension of the curve (only for Catmull Rom Spline). A value of 0.0f will give a straight linear line, 1.0 a round curve. |
enableDebugShape(assetManager,rootNode) | Shows a line to visualize the path. Used for debugging. |
disableDebugShape() | Hides the line that visualizes the path. Used for debugging. |
getNbWayPoints() | Returns the number of waypoints in this path. |
MotionTrack thingMotionControl = new MotionTrack(thingNode, path);
MotionTrack method | Usage |
---|---|
setLoopMode(LoopMode.Loop) | Sets whether the animation along this path should loop (true) or play only once (false). |
setDirectionType(MotionTrack.Direction.None) | Sets the direction behavior type of the controled node. Direction.None deactivates this feature. See the following options: |
setDirectionType(MotionTrack.Direction.LookAt) | Rotate to keep facing a point. Specify the point with setLookAt(). |
setDirectionType(MotionTrack.Direction.Path) | Face the direction of the path. |
setDirectionType(MotionTrack.Direction.PathAndRotation) | Face the direction of the path, plus an added rotation. Use together with the setRotation() method. |
setDirectionType(MotionTrack.Direction.Rotation) | Rotate while moving. Use together with the setRotation() method. |
setLookAt(teapot.getWorldTranslation(), Vector3f.UNIT_Y) | Optional: Make the moving face towards a certain location. Use together with setDirectionType(). |
setRotation(quaternion) | Optional: Sets the rotation. Use together with MotionTrack.Direction.Rotation or MotionTrack.Direction.PathAndRotation. |
You can register a MotionPathListener to the MotionPath to track whether waypoints have been reached, and then trigger a custom action. In this example we just print the status. The onWayPointReach() method of the interface gives you access to the MotionTrack object control
, and an integer value representing the current wayPointIndex.
path.addListener( new MotionPathListener() { public void onWayPointReach(MotionTrack control, int wayPointIndex) { if (path.getNbWayPoints() == wayPointIndex + 1) { println(control.getSpatial().getName() + "Finished!!! "); } else { println(control.getSpatial().getName() + " Reached way point " + wayPointIndex); } } });
PositionTrack thingPositionControl = new PositionTrack( thingNode, endPosition, duration, loopMode);
Details of the constructor:
The start location is always the current location of the Spatial.
RotationTrack thingRotationControl = new RotationTrack( thingNode, endRotation, duration, loopMode);
Details of the constructor:
ScaleTrack thingScaleControl = new ScaleTrack( thingNode, endScale, duration, loopMode);
Details of the constructor:
SoundTrack( audioPath, isStream, duration, loopMode )
Details of the constructor:
GuiTrack( screen, duration, loopMode )
You must use this together with bindUI() to specify the Nifty GUI XML file that you want to load:
cinematic.bindUi("Interface/subtitle.xml");
Details of the constructor:
AnimationTrack( thingNode, animationName, duration, loopMode )
Details of the constructor:
You can extend individual CinematicEvents. The SubtitleTrack.java example shows how to extend a GuiTrack to script subtitles. See how the subtitles are used in the TestCinematic.java example.
You can also create new CinematicEvent by extending AbstractCinematicEvent. An AbstractCinematicEvent implements the CinematicEvent interface and provides duration, time, speed, etc… management. Look at the TestCinematic.java example is to use this for a custom fadeIn/fadeOut effect in combination with a com.jme3.post.filters.FadeFilter.
The camera management is handled as follows:
CameraNode camNode = cinematic.bindCamera("topView", cam);
cinematic.activateCamera(6, "topView");
Code samples:
flyCam.setEnabled(false); CameraNode camNodeTop = cinematic.bindCamera("topView", cam); camNodeTop.setControlDir(ControlDirection.SpatialToCamera); camNodeTop.getControl(0).setEnabled(false); CameraNode camNodeSide = cinematic.bindCamera("sideView", cam); camNodeSide.setControlDir(ControlDirection.CameraToSpatial); camNodeSide.getControl(0).setEnabled(false);
Upcoming.
See also: Cinematics by Nehon