How to combine 2 Events in script

Hi guys!
I wanna try combine mouthopen and delayedcallback events.
In my case I need to trigger function to change blendshape value and toggle it every N time

I haven’t errors on it, but blendshapes doesn’t work

// @input Component.RenderMeshVisual face
// @input float delayTime = 1.0

var nol = 0.5;
var edin = 1;

var delayedEvent = script.createEvent("DelayedCallbackEvent");
function onDelay( eventData ){
  var event  = script.createEvent("MouthOpenedEvent");
  event.faceIndex = 0;
  event.bind(function (eventData){
    var toggle = false;

    toggle = !toggle;
    var newnum = toggle ? nol : edin;
    script.face.setBlendShapeWeight('Pose_3', newnum);
    print('open');
  });
  delayedEvent.reset(script.delayTime);
}

delayedEvent.reset(script.delayTime);
print("bound")

You will need to bind the delayed callback to the function, like this:

delayedEvent.bind(onDelay)

Also, I’m not sure how much it matters, but it’s probably more efficient to just create the mouth opened event once and reuse it. You can disable/enable it by setting the enabled property.

event.enabled = false
event.enabled = true

1 Like

Like this?
Also, I’m not sure where I need put enable property

// @input Component.RenderMeshVisual face
// @input float delayTime = 1.0

var nol = 0.5;
var edin = 1;


var delayedEvent = script.createEvent("DelayedCallbackEvent");
function onDelay( eventData ){
  var event  = script.createEvent("MouthOpenedEvent");
  event.faceIndex = 0;
  event.bind(function (eventData){
    var toggle = false;

    toggle = !toggle;
    var newnum = toggle ? nol : edin;
    script.face.setBlendShapeWeight('Pose_3', newnum);
    print('open');
  });
  delayedEvent.reset(script.delayTime);
}

delayedEvent.bind(onDelay)
delayedEvent.reset(script.delayTime);
print("bound")

I think you would enable the mouth open event in the delay callback, then disable when the mouth open is triggered.

But here’s a more flexible approach that uses a boolean to check the time state. It will only allow the mouth open logic to run if the delay has run once since the last time.

// @input Component.RenderMeshVisual face
// @input float delayTime = 1.0

var nol = 0.5;
var edin = 1;
var toggle = false;
var allowMouthOpen = true;

var event  = script.createEvent("MouthOpenedEvent");
event.faceIndex = 0;
event.bind(function (eventData){
    // block if not enough time has passed
    if(!allowMouthOpen) return
    allowMouthOpen = false
    
    toggle = !toggle;
    var newnum = toggle ? nol : edin;
    script.face.setBlendShapeWeight('Pose_3', newnum);
    print('open');
});

var delayedEvent = script.createEvent("DelayedCallbackEvent");
function onDelay( eventData ){
    // allow mouth open after delay
    allowMouthOpen = true
    delayedEvent.reset(script.delayTime);
    // TODO you could set another flag in the mouth open and execute the logic block 
}

delayedEvent.bind(onDelay)
delayedEvent.reset(script.delayTime);

You can also add another flag in there to run the same logic if the mouth opens but not enough time has elapsed. It depends on the UX you want.

1 Like

yay!! Awesome! its work. But, toggle switch just by trigger and I thought it will be toggle all the time until a trigger is off.

Ok, now its toggle work, but its start without trigger. and I think I need one more function for BlowsReturnToNormal event to disable toggle.

// @input Component.RenderMeshVisual face
// @input float delayTime = 1.0

var nol = 0.7;
var edin = 1;
var toggle = false;
var allowTrigger = true;

var event  = script.createEvent("BrowsRaisedEvent");
event.faceIndex = 0;
event.bind(function (eventData){
    // block if not enough time has passed
    if(!allowTrigger) return
    allowTrigger = false
    
});


var delayedEvent = script.createEvent("DelayedCallbackEvent");
function onDelay( eventData ){
    // allow mouth open after delay 
    //
    var newnum = toggle ? nol : edin;
    script.face.setBlendShapeWeight('Pose_1', newnum);
    print('open');
    toggle = !toggle;
    allowTrigger = true
    delayedEvent.reset(script.delayTime);
    // TODO you could set another flag in the mouth open and execute the logic block 
}

delayedEvent.bind(onDelay)
delayedEvent.reset(script.delayTime);



You need to use the allowTrigger boolean (inside of your onDelay handler) to determine if that logic should run or not. The return statement will block everything after it.

So, when i use

   var newnum = toggle ? nol : edin;
    script.face.setBlendShapeWeight('Pose_1', newnum);
    print('open');
    toggle = !toggle;

in evenData function then the toggle work just once.

When i use it in onDelay function its toggle first and after raiseBrow its lock
but i need to start toggle when raiseBrow. That is, I need to do the opposite
But it doesn’t work. =(