mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-29 14:22:56 +02:00
Merge pull request #8950 from huffman/tutorial/gotoentrystep
Add tutorial tracking for going through the welcome portal
This commit is contained in:
commit
95c175ae74
5 changed files with 48 additions and 64 deletions
|
@ -24,8 +24,11 @@ void UserActivityLoggerScriptingInterface::toggledAway(bool isAway) {
|
||||||
logAction("toggled_away", { { "is_away", isAway } });
|
logAction("toggled_away", { { "is_away", isAway } });
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserActivityLoggerScriptingInterface::tutorialProgress(QString stepName, int stepNumber, float secondsToComplete, float tutorialElapsedTime) {
|
void UserActivityLoggerScriptingInterface::tutorialProgress( QString stepName, int stepNumber, float secondsToComplete,
|
||||||
|
float tutorialElapsedTime, QString tutorialRunID, int tutorialVersion) {
|
||||||
logAction("tutorial_progress", {
|
logAction("tutorial_progress", {
|
||||||
|
{ "tutorial_run_id", tutorialRunID },
|
||||||
|
{ "tutorial_version", tutorialVersion },
|
||||||
{ "step", stepName },
|
{ "step", stepName },
|
||||||
{ "step_number", stepNumber },
|
{ "step_number", stepNumber },
|
||||||
{ "seconds_to_complete", secondsToComplete },
|
{ "seconds_to_complete", secondsToComplete },
|
||||||
|
|
|
@ -23,7 +23,8 @@ public:
|
||||||
Q_INVOKABLE void enabledEdit();
|
Q_INVOKABLE void enabledEdit();
|
||||||
Q_INVOKABLE void openedMarketplace();
|
Q_INVOKABLE void openedMarketplace();
|
||||||
Q_INVOKABLE void toggledAway(bool isAway);
|
Q_INVOKABLE void toggledAway(bool isAway);
|
||||||
Q_INVOKABLE void tutorialProgress(QString stepName, int stepNumber, float secondsToComplete, float tutorialElapsedTime);
|
Q_INVOKABLE void tutorialProgress(QString stepName, int stepNumber, float secondsToComplete,
|
||||||
|
float tutorialElapsedTime, QString tutorialRunID = "", int tutorialVersion = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void logAction(QString action, QJsonObject details = {});
|
void logAction(QString action, QJsonObject details = {});
|
||||||
|
|
|
@ -146,6 +146,8 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void requestGarbageCollection() { collectGarbage(); }
|
Q_INVOKABLE void requestGarbageCollection() { collectGarbage(); }
|
||||||
|
|
||||||
|
Q_INVOKABLE QUuid generateUUID() { return QUuid::createUuid(); }
|
||||||
|
|
||||||
bool isFinished() const { return _isFinished; } // used by Application and ScriptWidget
|
bool isFinished() const { return _isFinished; } // used by Application and ScriptWidget
|
||||||
bool isRunning() const { return _isRunning; } // used by ScriptWidget
|
bool isRunning() const { return _isRunning; } // used by ScriptWidget
|
||||||
|
|
||||||
|
|
|
@ -391,61 +391,6 @@ stepOrient.prototype = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// //
|
|
||||||
// STEP: Raise hands above head //
|
|
||||||
// //
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
var stepRaiseAboveHead = function(name) {
|
|
||||||
this.tag = name;
|
|
||||||
this.tempTag = name + "-temporary";
|
|
||||||
}
|
|
||||||
stepRaiseAboveHead.prototype = {
|
|
||||||
start: function(onFinish) {
|
|
||||||
var tag = this.tag;
|
|
||||||
|
|
||||||
var STATE_START = 0;
|
|
||||||
var STATE_HANDS_DOWN = 1;
|
|
||||||
var STATE_HANDS_UP = 2;
|
|
||||||
this.state = STATE_START;
|
|
||||||
|
|
||||||
editEntitiesWithTag(this.tag, { visible: true });
|
|
||||||
|
|
||||||
// Wait 2 seconds before starting to check for hands
|
|
||||||
this.checkIntervalID = null;
|
|
||||||
function checkForHandsAboveHead() {
|
|
||||||
debug("RaiseAboveHead | Checking hands");
|
|
||||||
if (this.state == STATE_START) {
|
|
||||||
if (MyAvatar.getLeftPalmPosition().y < (MyAvatar.getHeadPosition().y - 0.1)) {
|
|
||||||
this.state = STATE_HANDS_DOWN;
|
|
||||||
}
|
|
||||||
} else if (this.state == STATE_HANDS_DOWN) {
|
|
||||||
if (MyAvatar.getLeftPalmPosition().y > (MyAvatar.getHeadPosition().y + 0.1)) {
|
|
||||||
this.state = STATE_HANDS_UP;
|
|
||||||
Script.clearInterval(this.checkIntervalID);
|
|
||||||
this.checkIntervalID = null;
|
|
||||||
playSuccessSound();
|
|
||||||
onFinish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.checkIntervalID = Script.setInterval(checkForHandsAboveHead.bind(this), 500);
|
|
||||||
},
|
|
||||||
cleanup: function() {
|
|
||||||
debug("RaiseAboveHead | Cleanup");
|
|
||||||
if (this.checkIntervalID) {
|
|
||||||
Script.clearInterval(this.checkIntervalID);
|
|
||||||
this.checkIntervalID = null
|
|
||||||
}
|
|
||||||
if (this.waitTimeoutID) {
|
|
||||||
Script.clearTimeout(this.waitTimeoutID);
|
|
||||||
this.waitTimeoutID = null;
|
|
||||||
}
|
|
||||||
editEntitiesWithTag(this.tag, { visible: false, collisionless: 1 });
|
|
||||||
deleteEntitiesWithTag(this.tempTag);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1027,16 +972,23 @@ TutorialManager = function() {
|
||||||
var startedTutorialAt = 0;
|
var startedTutorialAt = 0;
|
||||||
var startedLastStepAt = 0;
|
var startedLastStepAt = 0;
|
||||||
|
|
||||||
|
var wentToEntryStepNum;
|
||||||
|
var VERSION = 1;
|
||||||
|
var tutorialID;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this.startTutorial = function() {
|
this.startTutorial = function() {
|
||||||
currentStepNum = -1;
|
currentStepNum = -1;
|
||||||
currentStep = null;
|
currentStep = null;
|
||||||
startedTutorialAt = Date.now();
|
startedTutorialAt = Date.now();
|
||||||
|
|
||||||
|
// Old versions of interface do not have the Script.generateUUID function.
|
||||||
|
// If Script.generateUUID is not available, default to an empty string.
|
||||||
|
tutorialID = Script.generateUUID ? Script.generateUUID() : "";
|
||||||
STEPS = [
|
STEPS = [
|
||||||
new stepStart("start"),
|
new stepStart("start"),
|
||||||
new stepOrient("orient"),
|
new stepOrient("orient"),
|
||||||
//new stepRaiseAboveHead("raiseHands"),
|
|
||||||
new stepNearGrab("nearGrab"),
|
new stepNearGrab("nearGrab"),
|
||||||
new stepFarGrab("farGrab"),
|
new stepFarGrab("farGrab"),
|
||||||
new stepEquip("equip"),
|
new stepEquip("equip"),
|
||||||
|
@ -1045,6 +997,7 @@ TutorialManager = function() {
|
||||||
new stepFinish("finish"),
|
new stepFinish("finish"),
|
||||||
new stepEnableControllers("enableControllers"),
|
new stepEnableControllers("enableControllers"),
|
||||||
];
|
];
|
||||||
|
wentToEntryStepNum = STEPS.length;
|
||||||
for (var i = 0; i < STEPS.length; ++i) {
|
for (var i = 0; i < STEPS.length; ++i) {
|
||||||
STEPS[i].cleanup();
|
STEPS[i].cleanup();
|
||||||
}
|
}
|
||||||
|
@ -1055,10 +1008,7 @@ TutorialManager = function() {
|
||||||
this.onFinish = function() {
|
this.onFinish = function() {
|
||||||
debug("onFinish", currentStepNum);
|
debug("onFinish", currentStepNum);
|
||||||
if (currentStep && currentStep.shouldLog !== false) {
|
if (currentStep && currentStep.shouldLog !== false) {
|
||||||
var timeToFinishStep = (Date.now() - startedLastStepAt) / 1000;
|
self.trackStep(currentStep.tag, currentStepNum);
|
||||||
var tutorialTimeElapsed = (Date.now() - startedTutorialAt) / 1000;
|
|
||||||
UserActivityLogger.tutorialProgress(
|
|
||||||
currentStep.tag, currentStepNum, timeToFinishStep, tutorialTimeElapsed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.startNextStep();
|
self.startNextStep();
|
||||||
|
@ -1071,6 +1021,12 @@ TutorialManager = function() {
|
||||||
|
|
||||||
++currentStepNum;
|
++currentStepNum;
|
||||||
|
|
||||||
|
// This always needs to be set because we use this value when
|
||||||
|
// tracking that the user has gone through the entry portal. When the
|
||||||
|
// tutorial finishes, there is a last "pseudo" step that the user
|
||||||
|
// finishes when stepping into the portal.
|
||||||
|
startedLastStepAt = Date.now();
|
||||||
|
|
||||||
if (currentStepNum >= STEPS.length) {
|
if (currentStepNum >= STEPS.length) {
|
||||||
// Done
|
// Done
|
||||||
info("DONE WITH TUTORIAL");
|
info("DONE WITH TUTORIAL");
|
||||||
|
@ -1080,7 +1036,6 @@ TutorialManager = function() {
|
||||||
} else {
|
} else {
|
||||||
info("Starting step", currentStepNum);
|
info("Starting step", currentStepNum);
|
||||||
currentStep = STEPS[currentStepNum];
|
currentStep = STEPS[currentStepNum];
|
||||||
startedLastStepAt = Date.now();
|
|
||||||
currentStep.start(this.onFinish);
|
currentStep.start(this.onFinish);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1102,6 +1057,21 @@ TutorialManager = function() {
|
||||||
currentStepNum = -1;
|
currentStepNum = -1;
|
||||||
currentStep = null;
|
currentStep = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.trackStep = function(name, stepNum) {
|
||||||
|
var timeToFinishStep = (Date.now() - startedLastStepAt) / 1000;
|
||||||
|
var tutorialTimeElapsed = (Date.now() - startedTutorialAt) / 1000;
|
||||||
|
UserActivityLogger.tutorialProgress(
|
||||||
|
name, stepNum, timeToFinishStep, tutorialTimeElapsed,
|
||||||
|
tutorialID, VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a message sent from the "entry" portal in the courtyard,
|
||||||
|
// after the tutorial has finished.
|
||||||
|
this.enteredEntryPortal = function() {
|
||||||
|
info("Got enteredEntryPortal, tracking");
|
||||||
|
this.trackStep("wentToEntry", wentToEntryStepNum);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// To run the tutorial:
|
// To run the tutorial:
|
||||||
|
|
|
@ -113,6 +113,14 @@ if (!Function.prototype.bind) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onEnteredEntryPortal: function() {
|
||||||
|
print("TutorialZone | Got onEnteredEntryPortal");
|
||||||
|
if (this.tutorialManager) {
|
||||||
|
print("TutorialZone | Calling enteredEntryPortal");
|
||||||
|
this.tutorialManager.enteredEntryPortal();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
enterEntity: function() {
|
enterEntity: function() {
|
||||||
print("TutorialZone | ENTERED THE TUTORIAL AREA");
|
print("TutorialZone | ENTERED THE TUTORIAL AREA");
|
||||||
},
|
},
|
||||||
|
@ -125,7 +133,7 @@ if (!Function.prototype.bind) {
|
||||||
}
|
}
|
||||||
if (this.tutorialManager) {
|
if (this.tutorialManager) {
|
||||||
this.tutorialManager.stopTutorial();
|
this.tutorialManager.stopTutorial();
|
||||||
this.tutorialManager = null;
|
//this.tutorialManager = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue