You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
71
-
// unused
72
-
}
73
-
74
-
/** Custom Keybinding: Map named actions to inputs. */
75
-
private void initKeys() {
76
-
inputManager.addMapping("Walk", new KeyTrigger(KeyInput.KEY_SPACE));
77
-
inputManager.addListener(actionListener, "Walk");
78
-
}
79
-
private ActionListener actionListener = new ActionListener() {
80
-
public void onAction(String name, boolean keyPressed, float tpf) {
81
-
if (name.equals("Walk") && !keyPressed) {
82
-
if (!channel.getAnimationName().equals("Walk")) {
83
-
channel.setAnim("Walk", 0.50f);
84
-
channel.setLoopMode(LoopMode.Loop);
85
-
}
86
-
}
74
+
75
+
/**
76
+
* Callback to indicate that the "advance" animation action has completed.
77
+
*/
78
+
void onAdvanceDone() {
79
+
/*
80
+
* Play the "stand" animation action.
81
+
*/
82
+
control.setCurrentAction("stand");
83
+
}
84
+
85
+
/**
86
+
* Map the spacebar to the "Walk" input action, and add a listener to initiate
87
+
* the "advance" animation action each time it's pressed.
88
+
*/
89
+
private void initKeys() {
90
+
inputManager.addMapping("Walk", new KeyTrigger(KeyInput.KEY_SPACE));
91
+
92
+
ActionListener handler = new ActionListener() {
93
+
@Override
94
+
public void onAction(String name, boolean keyPressed, float tpf) {
95
+
if (keyPressed && control.getCurrentAction() != advance) {
96
+
control.setCurrentAction("advance");
97
+
}
98
+
}
99
+
};
100
+
inputManager.addListener(handler, "Walk");
87
101
}
88
-
};
89
102
}
90
103
91
104
----
@@ -128,59 +141,36 @@ After you load the animated model, you register it to the Animation Controller.
128
141
[source,java]
129
142
----
130
143
131
-
private AnimChannel channel;
132
-
private AnimControl control;
144
+
private AnimComposer control;
133
145
134
146
public void simpleInitApp() {
135
147
...
136
148
/* Load the animation controls, listen to animation events,
137
149
* create an animation channel, and bring the model in its default position.
138
150
*/
139
-
control = player.getControl(AnimControl.class);
140
-
control.addListener(this);
141
-
channel = control.createChannel();
142
-
channel.setAnim("stand");
151
+
control = player.getControl(AnimComposer.class);
152
+
control.setCurrentAction("stand");
143
153
...
144
154
}
145
155
----
146
156
147
-
This line of code will return NULL if the AnimControl is not in the main node of your model.
157
+
This line of code will return NULL if the AnimComposer is not in the main node of your model.
148
158
149
159
[source,java]
150
160
----
151
-
control = player.getControl(AnimControl.class);
161
+
control = player.getControl(AnimComposer.class);
152
162
----
153
163
154
164
To check this, btn:[RMB] select your model and click "`Edit in SceneComposer`" if the models file extension is .j3o, or "`View`" if not. You can then see the tree for the model so you can locate the node the control resides in. You can access the subnode with the following code.
In response to a question about animations on different channels interfering with each other, *Nehon*, on the jME forum wrote,
164
-
165
-
[quote, Nehon, Team Leader: Retired]
166
-
____
167
-
You have to consider channels as part of the skeleton that are animated. The default behavior is to use the whole skeleton for a channel.
168
-
169
-
In your example the first channel plays the walk anim, then the second channel plays the dodge animation.
170
-
171
-
Arms and feet are probably not affected by the doge animation so you can see the walk anim for them, but the rest of the body plays the dodge animation.
172
-
173
-
Usually multiple channels are used to animate different part of the body. For example you create one channel for the lower part of the body and one for the upper part. This allow you to play a walk animation with the lower part and for example a shoot animation with the upper part. This way your character can walk while shooting.
174
-
175
-
In your case, where you want animations to chain for the whole skeleton, you just have to use one channel.
176
-
____
177
-
====
178
-
179
-
180
-
181
171
== Responding to Animation Events
182
172
183
-
Add `implements AnimEventListener` to the class declaration. This interface gives you access to events that notify you when a sequence is done, or when you change from one sequence to another, so you can respond to it. In this example, you reset the character to a standing position after a `Walk` cycle is done.
173
+
A Tween (part of an action sequence) can call a method on a class, allowing your application code to be informed of the animation state. In this example, you reset the character to a standing position after a `Walk` cycle is done.
184
174
185
175
[source,java]
186
176
----
@@ -189,17 +179,24 @@ public class HelloAnimation extends SimpleApplication
* Callback to indicate that the "advance" animation action has completed.
193
+
*/
194
+
void onAdvanceDone() {
195
+
/*
196
+
* Play the "stand" animation action.
197
+
*/
198
+
control.setCurrentAction("stand");
198
199
}
199
-
}
200
-
public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
201
-
// unused
202
-
}
203
200
...
204
201
}
205
202
----
@@ -220,45 +217,39 @@ There are ambient animations like animals or trees that you may want to trigger
220
217
[source,java]
221
218
----
222
219
223
-
private void initKeys() {
224
-
inputManager.addMapping("Walk", new KeyTrigger(KeyInput.KEY_SPACE));
225
-
inputManager.addListener(actionListener, "Walk");
226
-
}
227
-
228
-
----
229
-
230
-
To use the input controller, you need to implement the actionListener by testing for each action by name, then set the channel to the corresponding animation to run.
231
-
232
-
* The second parameter of setAnim() is the blendTime (how long the current animation should overlap with the last one).
233
-
* LoopMode can be Loop (repeat), Cycle (forward then backward), and DontLoop (only once).
234
-
* If needed, use channel.setSpeed() to set the speed of this animation.
235
-
* Optionally, use channel.setTime() to Fast-forward or rewind to a certain moment in time of this animation.
236
-
237
-
[source,java]
238
-
----
239
-
240
-
private ActionListener actionListener = new ActionListener() {
241
-
public void onAction(String name, boolean keyPressed, float tpf) {
242
-
if (name.equals("Walk") && !keyPressed) {
243
-
if (!channel.getAnimationName().equals("Walk")){
244
-
channel.setAnim("Walk", 0.50f);
245
-
channel.setLoopMode(LoopMode.Cycle);
220
+
/**
221
+
* Map the spacebar to the "Walk" input action, and add a listener to initiate
222
+
* the "advance" animation action each time it's pressed.
223
+
*/
224
+
private void initKeys() {
225
+
inputManager.addMapping("Walk", new KeyTrigger(KeyInput.KEY_SPACE));
226
+
227
+
ActionListener handler = new ActionListener() {
228
+
@Override
229
+
public void onAction(String name, boolean keyPressed, float tpf) {
230
+
if (keyPressed && control.getCurrentAction() != advance) {
231
+
control.setCurrentAction("advance");
232
+
}
246
233
}
247
-
}
234
+
};
235
+
inputManager.addListener(handler, "Walk");
248
236
}
249
-
};
250
237
251
238
----
252
239
253
240
241
+
* By default, the animation will loop, there is an overloaded `setCurrentAction` method that allows you to set the loop mode.
242
+
* If needed, use Action::setSpeed to set the speed of this animation.
243
+
* Optionally, use AnimComposer::.setTime to Fast-forward or rewind to a certain moment in time of this animation.
244
+
254
245
== Exercises
255
246
256
247
257
248
=== Exercise 1: Two Animations
258
249
259
250
Make a mouse click trigger another animation sequence!
260
251
261
-
. Create a second channel in the controller.
252
+
. Create a second layer in the controller.
262
253
. Create a new key trigger mapping and action. (see: xref:beginner/hello_input_system.adoc[Hello Input])
263
254
+
264
255
[TIP]
@@ -269,7 +260,7 @@ Use:
269
260
270
261
[source,java]
271
262
----
272
-
for (String anim : control.getAnimationNames()) {
263
+
for (String anim : control.getAnimClipsNames()) {
273
264
System.out.println(anim);
274
265
}
275
266
----
@@ -293,8 +284,8 @@ Add the following import statements for the SkeletonDebugger and Material classe
0 commit comments