Hi everyone! This is my first post here (Blender n00b), hope I am getting it right.
I am trying to use the BGE to build a kind of linear presentation, with a very simple flow and limited interactivity. Basically, right key animates up to the next step, left key animates back to the previous one.
This is a bit similar to the several “Powerpoint in Blender” threads I have seen here, except that I don’t want to switch between slides, but rather move forward and backward through a more complex animation involving many different objects. My initial idea is to have a global animation which progresses up until the next timeline marker when the user pushes the right key, and back to the previous one upon pressing left.
I have a few issues with this idea though: the most obvious one being that the game engine seems to be designed to play individual actions, and not a global animation defined by the timeline (at least, that’s what the available set of actuators in the logic blocks suggest). So it seems like my idea is not doable as-is, or that it would involve some Python (not a problem in itself, but I have no idea how to do that). So my question to experienced users is: does it seem like the correct way to achieve this, and if so, which Python classes should I look to implement it?
Blender’s animation system is also a little bit confusing to me - it seems like the timeline represents a “global” timeline (since moving its cursor animates all the actions I have created to far), but on the other hand the game engine can trigger a given action at any time… If anyone could recommand a good resource to understand how everything is put together, that would be great.
The BGE uses (game typically) object-level animations.
Creating “group level” animation is not that hard. It is more a question of synchronization. You need it ensure the according actions are played at the right time.
Examples: On scene start playing animations of 5 different objects.
This is pretty easy as you can measure the “scene start” with an always sensor.
When a certain animation ends play an animation (same object).
When an animation of a certain object ends start playing animations of 5 different objects.
This is a bit more complicated. We already know (see above) how to measure the animation end. But how to provide it to the other objects?
You can send a message. The interested objects can listen to this message via MessageActuator. This way any number of objects in any (active) scenes can measure this event happened. There is a small drawback: the message event is one frame after the actuator event do to the chaining of events. In most cases this is no big deal.
This all together should help you to achieve what you want.
It would be easy in python, not so much with logic bricks.
The game engine play action actuator plays an action in a range of frames which you specify.
So if you gave every object an action actuator with an always sensor, a start frame 1 and end frame 1000 and then hit play you would get the kind of global playback you’re talking about.
The problem would be the skipping back and forth part. You need to set the start frame and end frame dynamically. Setting the end frame lower than the start frame makes the animation play backwards so that bit would be easy if you could set the frame numbers.
In python I’d wait for a key press and then loop through the objects setting their start/end values based on a property. If I had some time I’d mock up a demo for you but It’s very late here I’m afraid.
I think I now have a clearer idea of how this should be done, based on your suggestions:
Each object has only one action, going from frame 0 to the end of the presentation
One (empty) master object controls the whole animation, with markers or something else to indicate where the animation should pause and wait for the next key to be pressed
When a key is pressed, a Python script gets the next or previous marker from the master object, sets the frame range for all objects and triggers the animation start. I expect the BGE will keep the frames in perfect synchronization and that they will thus stop exactly at the same time.
I like the fact that this allows me to control everything in a single timeline. This way I should even be able to use the Dope Sheet for reorganizing the animations globally.
I believe it should also be possible to detect when a key is pressed during an animation and revert the flow or quick-move to the next step.
The only small drawback I see is that each object has only one single action, which prevents reusability in case the same animation needs to be repeated several times. I wonder if the NLA editor could not be used to fix this (but then, won’t I lose the ability to use the Dope Sheet to have a bird’s-eye view of the presentation?). I have to admit I don’t really grok the NLA editor yet.
Let me study the Python API a bit and try to come with a working example (or more questions!). Thanks again!
This can probably be implemented more easily by having the master object’s action actuator use the frame property parameter to store its current frame into a game property, and all other objects use an action actuator driven by property that reads back the master object’s current frame from this property and sync to it.
Hi! I won’t have time to post a proper demo before a few days (or maybe next year), but here are my findings so far.
So solution devised in this thread works quite well: one single action per object, presentation sequence organized in the dope sheet, markers used to delimitate the “slides”, a master object to control the animation flow using a frame property, and all other objects following that master by copying that property and using property-controlled action actuator.
With the proper Python script in a controller, I can use the left/right keys to set the action range of the master object and move smoothly to the next/previous state of the presentation, which is just neat.
I suspect I can simplify things a bit by having the controller’s script parse all the objects of the scene and twiddling their actions instead of adding all these actuators, I will explore that. But so far, things look really good.
I have run into a few minor issues for which I wonder whether we can find a simple solution:
Using markers to delimitate the states of the presentation is great for putting things together, but it adds a dependency on the bpy module, which cannot be used with the standalone player. I wonder whether I could not “compile” the marker information into some data block/Python list for use with the standalone player. Any suggestion?
A common need I have is to make objects appear/disappear. I could set the alpha component of their material to 0 or 1, but it requires duplicating material that could otherwise be identical and is not optimal. I tried animating on the hide_render property (the little camera at the right in the Outliner), but it turns out it has no effect when the change happens during runtime. Another option that would work is the visible option of the KX_GameObject class, but since it belongs to the game engine I cannot find it anywhere in the editor and thus cannot add a channel for it in the action editor… here again, ideas would be welcome.
In any case, this looks very promising. I have tried doing so same thing using Three.js and Godot before, and for now the BGE is by far the most efficient tool.
Haven’t read all the posts, but here’s how I would do it.
Like you mentioned, all objects should have animations from 0 to the end of the “slide”.
You can have multiple animations per object per slide. For example, object A has a separate animation (dope sheet) for Slide 1, Slide 2, etc.
Then, have one object in Python hold all the objects that are part of the full presentation (multiple “slides”). Now, you can iterate through the animations and play, for example, all of their “slide 1” animations.
It’s pretty simple to do once you learn python! Even without python, you can do it pretty easily (though a little bit convoluted) with logic bricks.