I have tried to make a bobbing animation for my laser rifle with scripting rather than actual animation files. I have used the tutorial script for the “Animate Position”, and re purposed it to make a nice bobbing animation. However, my rifle does not follow my character, but just rotates based on how I look around, while doing the desired animation. Is there any way to add in the position of my camera without majorly interfering my animation?
Here is that script:
// More information about curves can be found at:
// http://developer.playcanvas.com/en/user-manual/scripting/script-attributes/
// http://developer.playcanvas.com/en/api/pc.Curve.html
var AnimatePosition = pc.createScript('Bobbing');
// Example of creating curve attribute with multiple curves (in this case, x, y, z)
AnimatePosition.attributes.add("offsetCurve", {type: "curve", title: "Offset Curve", curves: [ 'x', 'y', 'z' ]});
AnimatePosition.attributes.add("duration", {type: "number", default: 3, title: "Duration (secs)"});
// initialize code called once per entity
AnimatePosition.prototype.initialize = function() {
// Store the original position of the entity so we can offset from it
this.startPosition = this.entity.getPosition().clone();
// Keep track of the current position
this.position = new pc.Vec3();
this.time = 0;
};
// update code called every frame
AnimatePosition.prototype.update = function(dt) {
this.time += dt;
// Loop the animation forever
if (this.time > this.duration) {
this.time -= this.duration;
}
// Calculate how far in time we are for the animation
var percent = this.time / this.duration;
// Get curve values using current time relative to duration (percent)
// The offsetCurve has 3 curves (x, y, z) so the returned value will be a set of
// 3 values
var curveValue = this.offsetCurve.value(percent);
// Create our new position from the startPosition and curveValue
this.position.copy(this.startPosition);
this.position.x += curveValue[0];
this.position.y += curveValue[1];
this.position.z += curveValue[2];
this.entity.setPosition(this.position);
};
Please note: I am also using the First Person tutorial scripts for looking around too.
(The scene with the animation running)
This is a little tricky as you need to add the bob animation offset to the position of where the player is. As the camera is a child of the player entity, I would apply the bob animation to the local position of the camera entity rather than the player.
Right now, every frame the start position of the entity is copied to the new position, hence you can’t move.
Just to go through the issue, in the initialise function we store the original position of the entity in world space.
In the update function, it is copied back to the entity’s position (plus the animation offset) so it basically doesn’t move from it’s starting position.
// Create our new position from the startPosition and curveValue
this.position.copy(this.startPosition);
this.position.x += curveValue[0];
this.position.y += curveValue[1];
this.position.z += curveValue[2];
this.entity.setPosition(this.position);
As the animation script is on the gun in the project, we don’t want to keep the position of the gun in the same position in world space. So we modify the script to affect local space which means we animate the position relative to it’s parent.
// More information about curves can be found at:
// http://developer.playcanvas.com/en/user-manual/scripting/script-attributes/
// http://developer.playcanvas.com/en/api/pc.Curve.html
var AnimatePosition = pc.createScript('Bobbing');
// Example of creating curve attribute with multiple curves (in this case, x, y, z)
AnimatePosition.attributes.add("offsetCurve", {type: "curve", title: "Offset Curve", curves: [ 'x', 'y', 'z' ]});
AnimatePosition.attributes.add("duration", {type: "number", default: 3, title: "Duration (secs)"});
// initialize code called once per entity
AnimatePosition.prototype.initialize = function() {
// Store the original position of the entity so we can offset from it
this.startPosition = this.entity.getLocalPosition().clone();
// Keep track of the current position
this.position = new pc.Vec3();
this.time = 0;
};
// update code called every frame
AnimatePosition.prototype.update = function(dt) {
this.time += dt;
// Loop the animation forever
if (this.time > this.duration) {
this.time -= this.duration;
}
// Calculate how far in time we are for the animation
var percent = this.time / this.duration;
// Get curve values using current time relative to duration (percent)
// The offsetCurve has 3 curves (x, y, z) so the returned value will be a set of
// 3 values
var curveValue = this.offsetCurve.value(percent);
// Create our new position from the startPosition and curveValue
this.position.copy(this.startPosition);
this.position.x += curveValue[0];
this.position.y += curveValue[1];
this.position.z += curveValue[2];
this.entity.setLocalPosition(this.position);
};