Skip to content

Commit c5574ff

Browse files
no message
1 parent 00e8be5 commit c5574ff

23 files changed

+158
-35
lines changed

LSQuickScripts/Example Project/LSQuickScripts Examples/Assets/LSQuickScripts/LSQuickScripts.js

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@ui {"widget":"label"}
22
//@ui {"widget":"separator"}
3-
//@ui {"widget":"label", "label":"<big><b>📜 LSQuickScripts 2.25</b> <small>by Max van Leeuwen"}
3+
//@ui {"widget":"label", "label":"<big><b>📜 LSQuickScripts 2.26</b> <small>by Max van Leeuwen"}
44
//@ui {"widget":"label", "label":"See this script for more info!"}
55
//@ui {"widget":"label"}
66
//@ui {"widget":"label", "label":"<small><a href=\"https://www.maxvanleeuwen.com/lsquickscripts\">maxvanleeuwen.com/LSQuickScripts</a>"}
@@ -160,7 +160,7 @@
160160
// .scaleOut(delay, duration, startAtTime, easeFunction) // start scale-out (disables SceneObject and all running animations on end)
161161
// .squeeze(delay, strength, duration) // do scale squeeze
162162
// .rotateAround(delay, rotations, axis, duration, easeFunction) // do rotational swirl
163-
// .scaleTo(delay, toScale, duration, easeFunction) // scale towards new size (overrides other rotation animations)
163+
// .scaleTo(delay, toScale, isLocal, duration, easeFunction) // scale towards new size (overrides other rotation animations)
164164
// .moveTo(delay, point, duration, easeFunction) // move towards new position (local screen space if ScreenTransform, world space if Transform) (overrides other position animations)
165165
// .keepBlinking(delay, interval, strength, easeFunction) // keep blinking
166166
// .lookAt(delay, point, duration, easeFunction) // rotate to look at a point (local screen space if ScreenTransform, world space if Transform) (overrides other rotation animations)
@@ -699,6 +699,22 @@
699699
//
700700
//
701701
//
702+
// -
703+
//
704+
//
705+
//
706+
// rankedAction(label [string], prio [number], func [function])
707+
// Ranked Actions make it easy to compare a bunch of features coming from different scripts on the same frame, and only call the one with the highest priority at the end of the frame.
708+
//
709+
// An example of when this would be useful:
710+
// Imagine a scene containing a button and another tap event of some kind (like on-screen taps).
711+
// When the user taps on the button, the other event is also triggered.
712+
// By having the actions of both interactables pass through rankedAction first, the highest-prio action at the end of each frame is triggered and the other is ignored.
713+
//
714+
// All actions to be pooled together should have the same label. At the end of each frame, all pools are cleared.
715+
//
716+
//
717+
//
702718
// -------------------
703719

704720

@@ -1789,10 +1805,11 @@ global.QuickFlow = function(obj){
17891805
* @description (use undefined for any argument to pick its default value)
17901806
* @param {number} delay delay - default: 0 seconds
17911807
* @param {(vec2|vec3)} point point - default: original position (before animations were applied)
1808+
* @param {boolean} isLocal isLocal - default: false (only relevant for 3D motion, set to true to apply as local space instead of world space)
17921809
* @param {number} duration duration - default: .5 seconds
17931810
* @param {function} easeFunction easeFunction - default: EaseFunctions.Cubic.InOut
17941811
*/
1795-
this.moveTo = function(delay = 0, point = truePosition, duration = .5, easeFunction = EaseFunctions.Cubic.InOut){
1812+
this.moveTo = function(delay = 0, point = truePosition, isLocal = false, duration = .5, easeFunction = EaseFunctions.Cubic.InOut){
17961813
// register
17971814
registerCommand(this.moveTo, [...arguments]);
17981815

@@ -1803,7 +1820,7 @@ global.QuickFlow = function(obj){
18031820
nonRelativeAnimationClear(nrPositionAnim);
18041821

18051822
// convert toPosition from world space to local space on animation start (if not ScreenTransform)
1806-
if(!screenTrf){
1823+
if(!isLocal && !screenTrf){
18071824
var parent = obj.getParent(); // use parent's transform for local-to-world conversion
18081825
if(parent){
18091826
const mat = parent.getTransform().getInvertedWorldTransform();
@@ -3451,4 +3468,37 @@ global.VisualizePoints = function(showPointsOnStart){
34513468

34523469
// start right away if array given
34533470
if(showPointsOnStart) self.show(showPointsOnStart);
3471+
}
3472+
3473+
3474+
3475+
3476+
global.rankedAction = function(label, prio, func){
3477+
// store a given action/prio combo (creates store and label if not already there)
3478+
function store(){
3479+
if(!global.rankedActionStore) global.rankedActionStore = {}; // create store
3480+
if(!global.rankedActionStore[label]) global.rankedActionStore[label] = {}; // create label
3481+
global.rankedActionStore[label].func = func; // assign function
3482+
global.rankedActionStore[label].prio = prio; // assign prio
3483+
}
3484+
3485+
if(global.rankedActionStore){ // if a store was already made by another script
3486+
if(global.rankedActionStore[label]){ // if this specific label already exists in the store
3487+
if(prio > global.rankedActionStore[label].prio) store(); // store this new action if new prio is greater than existing
3488+
}else{ // if label does not exist yet
3489+
store(); // store new action under new label
3490+
}
3491+
}else{ // if this is the first script to make a store
3492+
store(); // initialize with new action
3493+
}
3494+
3495+
// do check at end of frame
3496+
var rankedActionEvent = script.createEvent("LateUpdateEvent");
3497+
rankedActionEvent.bind(function(){ // the end-of-frame check
3498+
for(const thisLabel in global.rankedActionStore){ // go through all labels' stored data
3499+
if(global.rankedActionStore[thisLabel].func) global.rankedActionStore[thisLabel].func(); // call winner
3500+
delete global.rankedActionStore[thisLabel]; // remove from list (but keep the overall store)
3501+
}
3502+
script.removeEvent(rankedActionEvent); // only do this for one frame
3503+
});
34543504
}

LSQuickScripts/LSQuickScripts.js

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@ui {"widget":"label"}
22
//@ui {"widget":"separator"}
3-
//@ui {"widget":"label", "label":"<big><b>📜 LSQuickScripts 2.25</b> <small>by Max van Leeuwen"}
3+
//@ui {"widget":"label", "label":"<big><b>📜 LSQuickScripts 2.26</b> <small>by Max van Leeuwen"}
44
//@ui {"widget":"label", "label":"See this script for more info!"}
55
//@ui {"widget":"label"}
66
//@ui {"widget":"label", "label":"<small><a href=\"https://www.maxvanleeuwen.com/lsquickscripts\">maxvanleeuwen.com/LSQuickScripts</a>"}
@@ -160,7 +160,7 @@
160160
// .scaleOut(delay, duration, startAtTime, easeFunction) // start scale-out (disables SceneObject and all running animations on end)
161161
// .squeeze(delay, strength, duration) // do scale squeeze
162162
// .rotateAround(delay, rotations, axis, duration, easeFunction) // do rotational swirl
163-
// .scaleTo(delay, toScale, duration, easeFunction) // scale towards new size (overrides other rotation animations)
163+
// .scaleTo(delay, toScale, isLocal, duration, easeFunction) // scale towards new size (overrides other rotation animations)
164164
// .moveTo(delay, point, duration, easeFunction) // move towards new position (local screen space if ScreenTransform, world space if Transform) (overrides other position animations)
165165
// .keepBlinking(delay, interval, strength, easeFunction) // keep blinking
166166
// .lookAt(delay, point, duration, easeFunction) // rotate to look at a point (local screen space if ScreenTransform, world space if Transform) (overrides other rotation animations)
@@ -699,6 +699,22 @@
699699
//
700700
//
701701
//
702+
// -
703+
//
704+
//
705+
//
706+
// rankedAction(label [string], prio [number], func [function])
707+
// Ranked Actions make it easy to compare a bunch of features coming from different scripts on the same frame, and only call the one with the highest priority at the end of the frame.
708+
//
709+
// An example of when this would be useful:
710+
// Imagine a scene containing a button and another tap event of some kind (like on-screen taps).
711+
// When the user taps on the button, the other event is also triggered.
712+
// By having the actions of both interactables pass through rankedAction first, the highest-prio action at the end of each frame is triggered and the other is ignored.
713+
//
714+
// All actions to be pooled together should have the same label. At the end of each frame, all pools are cleared.
715+
//
716+
//
717+
//
702718
// -------------------
703719

704720

@@ -1789,10 +1805,11 @@ global.QuickFlow = function(obj){
17891805
* @description (use undefined for any argument to pick its default value)
17901806
* @param {number} delay delay - default: 0 seconds
17911807
* @param {(vec2|vec3)} point point - default: original position (before animations were applied)
1808+
* @param {boolean} isLocal isLocal - default: false (only relevant for 3D motion, set to true to apply as local space instead of world space)
17921809
* @param {number} duration duration - default: .5 seconds
17931810
* @param {function} easeFunction easeFunction - default: EaseFunctions.Cubic.InOut
17941811
*/
1795-
this.moveTo = function(delay = 0, point = truePosition, duration = .5, easeFunction = EaseFunctions.Cubic.InOut){
1812+
this.moveTo = function(delay = 0, point = truePosition, isLocal = false, duration = .5, easeFunction = EaseFunctions.Cubic.InOut){
17961813
// register
17971814
registerCommand(this.moveTo, [...arguments]);
17981815

@@ -1803,7 +1820,7 @@ global.QuickFlow = function(obj){
18031820
nonRelativeAnimationClear(nrPositionAnim);
18041821

18051822
// convert toPosition from world space to local space on animation start (if not ScreenTransform)
1806-
if(!screenTrf){
1823+
if(!isLocal && !screenTrf){
18071824
var parent = obj.getParent(); // use parent's transform for local-to-world conversion
18081825
if(parent){
18091826
const mat = parent.getTransform().getInvertedWorldTransform();
@@ -3451,4 +3468,37 @@ global.VisualizePoints = function(showPointsOnStart){
34513468

34523469
// start right away if array given
34533470
if(showPointsOnStart) self.show(showPointsOnStart);
3471+
}
3472+
3473+
3474+
3475+
3476+
global.rankedAction = function(label, prio, func){
3477+
// store a given action/prio combo (creates store and label if not already there)
3478+
function store(){
3479+
if(!global.rankedActionStore) global.rankedActionStore = {}; // create store
3480+
if(!global.rankedActionStore[label]) global.rankedActionStore[label] = {}; // create label
3481+
global.rankedActionStore[label].func = func; // assign function
3482+
global.rankedActionStore[label].prio = prio; // assign prio
3483+
}
3484+
3485+
if(global.rankedActionStore){ // if a store was already made by another script
3486+
if(global.rankedActionStore[label]){ // if this specific label already exists in the store
3487+
if(prio > global.rankedActionStore[label].prio) store(); // store this new action if new prio is greater than existing
3488+
}else{ // if label does not exist yet
3489+
store(); // store new action under new label
3490+
}
3491+
}else{ // if this is the first script to make a store
3492+
store(); // initialize with new action
3493+
}
3494+
3495+
// do check at end of frame
3496+
var rankedActionEvent = script.createEvent("LateUpdateEvent");
3497+
rankedActionEvent.bind(function(){ // the end-of-frame check
3498+
for(const thisLabel in global.rankedActionStore){ // go through all labels' stored data
3499+
if(global.rankedActionStore[thisLabel].func) global.rankedActionStore[thisLabel].func(); // call winner
3500+
delete global.rankedActionStore[thisLabel]; // remove from list (but keep the overall store)
3501+
}
3502+
script.removeEvent(rankedActionEvent); // only do this for one frame
3503+
});
34543504
}

World Placement/Example Project/World Placement Example/Entities/1686666527994749_168.lsjson

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

World Placement/Example Project/World Placement Example/Entities/1686666527994749_169.lsjson

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

World Placement/Example Project/World Placement Example/Entities/1686666527994749_170.lsjson

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

World Placement/Example Project/World Placement Example/Entities/1686666527994788_191.lsjson

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

World Placement/Example Project/World Placement Example/Entities/1686666527994794_192.lsjson

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

World Placement/Example Project/World Placement Example/Public/Box.mesh renamed to World Placement/Example Project/World Placement Example/Public/Other/Box.mesh

File renamed without changes.

World Placement/Example Project/World Placement Example/Public/Place World On Tap.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99
// make instance with customizations
1010
//@input SceneObject obj
1111
var worldPlacementAnim = new WorldPlacement(script.obj);
12-
worldPlacementAnim.duration = .3;
13-
worldPlacementAnim.spherical = false;
14-
worldPlacementAnim.distanceFromCamera = 80;
12+
13+
// set custom distance from camera
14+
//@input float customDistanceFromCamera
15+
worldPlacementAnim.distanceFromCamera = script.customDistanceFromCamera;
1516

1617

1718

1819
// when user taps on screen, call WorldPlacement
1920
script.createEvent("TapEvent").bind(function(){
2021
worldPlacementAnim.start();
21-
})
22+
})
23+
24+
worldPlacementAnim.start(true); // do on script start with isInstant=true, to instantly see the block in front of you

World Placement/Example Project/World Placement Example/Public/World Placement.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
// World Placement
66

7-
// Requires LSQuickScripts 2.25
7+
// Requires LSQuickScripts 2.26
88
if(!global.lsqs) throw("LSQuickScripts is missing! Install it from maxvanleeuwen.com/lsquickscripts");
99

1010

@@ -45,6 +45,12 @@ if(!global.lsqs) throw("LSQuickScripts is missing! Install it from maxvanleeuwen
4545

4646

4747

48+
// action priority settings
49+
script.rankedPriority = 10; // priority level for interactions created by this button (only relevant if other action ranking scripts with the same label are used in this project)
50+
const rankedLabel = 'interactables'; // the priority pool name (should be same for other interactables)
51+
52+
53+
4854
global.WorldPlacement = function(moveObject){
4955
var self = this;
5056

@@ -101,36 +107,40 @@ global.WorldPlacement = function(moveObject){
101107
* @type {Function}
102108
* @description Starts the animation. If first argument is true, the animation will be skipped and placement will be instant. */
103109
this.start = function(doInstant){
110+
rankedAction(rankedLabel, script.rankedPriority, ()=>start(doInstant) ); // rankedAction makes sure other interactables (if there are any) are prioritized correctly
111+
}
112+
113+
function start(doInstant){
104114
// get transformation info
105115
var camTrf = self.cameraObject.getTransform();
106116
if(self.moveObject) var sceneTrf = self.moveObject.getTransform();
107-
117+
108118
var camPos = camTrf.getWorldPosition();
109119
var camFwd = camTrf.forward;
110120
var cursorPos = camPos.add(camFwd);
111121
var camPosXZ = new vec3(camPos.x, 0, camPos.z);
112122
var cursorPosXZ = new vec3(cursorPos.x, 0, cursorPos.z);
113123
var fwdXZ = camPosXZ.sub(cursorPosXZ).normalize();
114-
124+
115125
// facing user, y-axis only
116126
var newRot = quat.angleAxis( Math.atan2(fwdXZ.x, fwdXZ.z) + Math.PI, vec3.up());
117-
127+
118128
// positioned in front of user at correct height
119129
var camHeight = new vec3(0, camPos.y, 0);
120130
var sphericalHeight = 0;
121131
if(self.spherical) sphericalHeight = -camFwd.uniformScale(self.distanceFromCamera).y;
122132
var heightOffset = new vec3(0, self.height + sphericalHeight, 0);
123133
var newPos = camPosXZ.add(fwdXZ.uniformScale(self.distanceFromCamera));
124134
newPos = newPos.add(heightOffset).add(camHeight);
125-
135+
126136
// animate properties
127137
if(sceneTrf){
128138
var curPos = sceneTrf.getWorldPosition();
129139
var curRot = sceneTrf.getWorldRotation();
130140
}
131141

132142
finalTransformData = {pos:newPos, rot:newRot};
133-
143+
134144
function animationStep(v){
135145
// apply (if moveObject was given)
136146
if(sceneTrf){

0 commit comments

Comments
 (0)