I am trying to blend between multiple animations on key presses. I want to move from the regular walking animation to different animations on different keys.
This is my script so far - I have added a new function at the bottom but I’m a little stuck - could anyone tell me where I’m going wrong? Currently I can only blend to the bottom animation “dancing” and not “stretch”…
var AnimationBlending = pc.createScript('animationBlending');
AnimationBlending.states = {
idle: {
animation: 'catwalk_walking_inPlace (1).json'
},
stretch: {
animation: 'arm_stretching.json'
},
dancing: {
animation: 'jazz_dancing_inPlace.json'
}
};
// initialize code called once per entity
AnimationBlending.prototype.initialize = function() {
this.blendTime = 1;
this.setState('idle');
this.app.keyboard.on(pc.EVENT_KEYDOWN, this.keyDown, this);
this.app.keyboard.on(pc.EVENT_KEYUP, this.keyUp, this);
};
AnimationBlending.prototype.setState = function (state) {
var states = AnimationBlending.states;
this.state = state;
// Set the current animation, taking 0.2 seconds to blend from
// the current animation state to the start of the target animation.
this.entity.animation.play(states[state].animation, this.blendTime);
};
AnimationBlending.prototype.keyDown = function (e) {
if ((e.key === pc.KEY_P) && (this.state !== 'stretch')) {
this.setState('stretch');
}
};
AnimationBlending.prototype.keyUp = function (e) {
if ((e.key === pc.KEY_P) && (this.state === 'strech')) {
this.setState('idle');
}
};
AnimationBlending.prototype.keyDown = function (e) {
if ((e.key === pc.KEY_O) && (this.state !== 'dancing')) {
this.setState('dancing');
}
};
AnimationBlending.prototype.keyUp = function (e) {
if ((e.key === pc.KEY_O) && (this.state === 'dancing')) {
this.setState('idle');
}
};
The above solution fixed that initial problem, but I have one other. I am also swapping out my model (but retaining the same animation) with the below code. I have two issues:
When I swap to object ‘c’ - pressing the ‘Q’ key, the model swaps fine but the animation stops - but works when I go to object ‘b’.
Ideally, rather than start the animation again I want to carry it on so that it doesn’t restart, is there a good to way to achieve this?
Apologies for all the questions, am new to this but keen to learn and I am really enjoying the experience so far.
Thanks!
// Model swapper
var UpdateAsset = pc.createScript('updateAsset');
UpdateAsset.attributes.add('a', {
type: 'asset',
assetType: 'model'
});
UpdateAsset.attributes.add('b', {
type: 'asset',
assetType: 'model'
});
UpdateAsset.attributes.add('c', {
type: 'asset',
assetType: 'model'
});
UpdateAsset.prototype.initialize = function() {
this.app.keyboard.preventDefault = true;
};
// update code called every frame
UpdateAsset.prototype.update = function(dt) {
var app = this.app;
if (app.keyboard.isPressed(pc.KEY_Q)) {
if (this.entity.model.model !== this.b.resource) {
// update the model component to the new model
this.entity.model.model = this.b.resource;
}
} else {
if (this.entity.model.model !== this.a.resource) {
// restore original model
this.entity.model.model = this.a.resource;
}
if (app.keyboard.isPressed(pc.KEY_W)) {
if (this.entity.model.model !== this.c.resource) {
// update the model component to the new model
this.entity.model.model = this.c.resource;
}
} else {
if (this.entity.model.model !== this.a.resource) {
// restore original model
this.entity.model.model = this.a.resource;
}
}
}
// clear
if (app.keyboard.isPressed(pc.KEY_L)) {
app.assets.load(this.c);
}
};
You can play the same animation on the other model and then set the currentTime property on the animation component to move it where you want. So first store the currentTime before changing models and then set it again after playing the animation.
AnimationBlending.prototype.setState = function (state) {
var states = AnimationBlending.states;
this.state = state;
// Set the current animation, taking 0.2 seconds to blend from
// the current animation state to the start of the target animation.
this.entity.animation.play(states[state].animation, this.blendTime);
};
AnimationBlending.prototype.keyDown = function (e) {
if ((e.key === pc.KEY_P) && (this.state !== ‘Great_Sword_Slash.json’)) {
this.setState(‘Great_Sword_Slash.json’);
}
};
same basic idea here, something about set State or passed to or set function