Alright I’ve attached a script to a ball that I thought would give motion control to an iphone after publishing. My project I’m playing with is here: https://playcanvas.com/project/471589/overview/playhackmm
The script I found that somebody else posted is below (original post: Animation Root Motion Script ). I have this script attached to the ball. What am I missing? @whydoidoit
pc.script.attribute('xmotion', 'boolean', false);
pc.script.attribute('ymotion', 'boolean', false);
pc.script.attribute('zmotion', 'boolean', true);
pc.script.attribute('rotation', 'boolean', true);
pc.script.create('rootmotion', function (app) {
function diffQuat(q1, q2) {
var a = q1.clone().invert();
return a.clone().mul(q2);//
}
pc.Skeleton.prototype.updateGraph = function () {
if (this.graph) {
var time = this.getCurrentTime();
var rootMotion;
for (var i = 0; i < this._interpolatedKeys.length; i++) {
var interpKey = this._interpolatedKeys[i];
if (i == 0) {
var obj = interpKey.getTarget().getParent();
if (obj.script && obj.script.rootmotion) {
rootMotion = obj.script.rootmotion;
}
var transform = interpKey.getTarget();
transform.localRotation.copy(interpKey._quat);
}
if (interpKey._written) {
var transform = interpKey.getTarget();
var pos = interpKey._pos;
if (i >= 2) {
transform.localPosition.copy(pos);
transform.localRotation.copy(interpKey._quat);
}
else if (rootMotion) {
if (rootMotion.rotation) {
if (time == 0) {
rootMotion.lastRotation = interpKey._quat.clone();
}
rootMotion.lastRotation = rootMotion.lastRotation || interpKey._quat.clone();
var diffA = diffQuat(rootMotion.lastRotation, interpKey._quat).getEulerAngles();
var existing = interpKey._quat.getEulerAngles();
rootMotion.setRotation(new pc.Quat().setFromEulerAngles(0, diffA.y,0));
transform.localRotation.setFromEulerAngles(existing.x, 0, existing.z);
}
if (time == 0) {
rootMotion.lastPosition = pos.clone();
}
rootMotion.time = time;
rootMotion.lastPosition =
rootMotion.lastPosition || transform.localPosition;
var diff = pos.clone().sub(rootMotion.lastPosition);
if (!rootMotion.zmotion) {
diff.z = 0;
}
if (!rootMotion.ymotion || rootMotion.rotation) {
diff.y = 0;
}
if (!rootMotion.xmotion || rootMotion.rotation) {
diff.x = 0;
}
rootMotion.setMotion(diff);
}
transform.localScale.copy(interpKey._scale);
transform.dirtyLocal = true;
interpKey._written = false;
}
}
}
};
// Creates a new Rootmotion instance
var Rootmotion = function (entity) {
this.entity = entity;
this.rootMotion = new pc.Vec3();
this.rootRotation = new pc.Quat();
this.time = 0;
};
Rootmotion.prototype = {
// Called once after all resources are loaded and before the first update
initialize: function () {
this.scale = this.entity.getLocalScale().x;
},
// Called every frame, dt is time in seconds since last update
update: function (dt) {
this.entity.translateLocal(this.rootMotion.clone().scale(this.scale));
this.entity.setLocalRotation(this.rootRotation.clone().mul(this.entity.getLocalRotation().clone()));
},
setMotion: function (delta) {
this.rootMotion = delta;
this.lastPosition.add(delta);
},
setRotation: function (delta) {
this.rootRotation = delta.clone();
this.lastRotation = delta.clone().mul(this.lastRotation);
}
};
return Rootmotion;
});