In this example, the scripting functionality within DeepAR will be explained by expanding the ping pong mini game created as an example for showcasing the physics mechanics (check out the relevant tutorial). Callbacks onStart, onUpdate, onCollisionEnter and onCollisionLeave will be showcased.

The steps to recreate this concrete example are given in the rest of the article. The given property values are all exemplary and can be adjusted if some value change doesn't result in the expected behaviour.

Step 0

Since this example follows up on the ping pong mini game linked previously, locate the previously made effect or download the pre-made effect stored as scripting_pingPong_start within the zip located at the bottom of the article. The file should be opened as an already existing effect using FileOpen effect or Cmd+O keyboard shortcut.

Step 1 - initialisation

In a new JavaScript file, create variables ball and paddle that will contain the respective nodes, minimumScale and maximumScale variables that will represent the minimum/maximum scale factor of the ball, colorToggle and scaleToggle variables which are boolean variables used to toggle between the two possible colours or scale factors respectively, as well as the delta variable representing the amount by which the ball's scaling factor will increase or decrease each frame.

var ball, paddle;
var minimumScale, maximumScale;
var colorToggle, scaleToggle;

var delta = 0.025;


Step 2 - onStart()

The onStart callback is called only once, immediately after the effect is loaded.

In this function, the ball and head nodes are retrieved from the hierarchy, located starting from the root node. Also initialised are the minimum and maximum scale factors of the ping pong ball, as well as the two toggles (the true/false values used for initialisation that only changes the order of the changes made when these values end up being checked) - colorToggle and scaleToggle.

ball = Node.root.getChild('Ball');
paddle = Node.root.getChild('Racket').getChild('Paddle');

minimumScale = 1;
maximumScale = 2;

colorToggle = false;
scaleToggle = false;

Step 3 - onUpdate()

The onUpdate callback is called on every frame update and checks whether the face visibility status changed in comparison to the previous frame.

The function adds or subtracts, depending on the value of the scaleToggle variable, the amount stored in the delta variable from the current scale factor of the ball.

Since the localScale member of the Node class is both readable and writable, its value can be directly read and modified, without a setter or by using the Utility.changeParamater function.

var local = ball.localScale;
var newScale = new Vec3();
ball.localScale = scaleToggle ? ball.localScale.sub(delta) :
ball.localScale.add(delta);

Step 4 - onCollisionEnter(firstNode, secondNode)

The onCollisionEnter callback is called when two nodes with physical characteristics start colliding.

if (!checkIfCollidedWithPaddle(firstNode, secondNode)) return; 

changePaddleColor();
changeBallMinMaxScale();

Since there are more than two objects in the effect that fit that description and are able to collide, an additional check needs to be performed.

That check is implemented in the form of a function called checkIfCollidedWithPaddle - a local boolean value is initialised and returned by the function, determining whether the correct objects collided - a truth value is assigned if the pair of the collided nodes is the ball and the paddle node, no matter the order of collision (unordered pair).

If the collided nodes are indeed the ball and the paddle, then two changes in the effect occur - the paddle color and the ball's scale factors are modified.

function checkIfCollidedWithPaddle(firstNode, secondNode) {
var collides = false;
if (firstNode.equals(ball))
collides = secondNode.equals(paddle);
else if (firstNode.equals(paddle))
collides = secondNode.equals(ball);

return collides;
}

The changePaddleColor function changes the color of the paddle depending on the current value/state of the colorToggle variable. The colors are changed depending on the state of the collision. When entering collision, the paddle becomes green. The scale factors are updated using the Utility.changeParameter function, since the needed parameters aren't solely exposed, but rather have to be explicitly changed using the aforementioned function. The parameter modified depends on the shader used for that node - for this example, Standard shader full was used for the paddle shading and the internal name of the value that needs to be changed needs to be located in the respective shader files. The parameter that is to be changed is Diffuse color and the corresponding variable in the shader is u_diffuseColor. For further information about this topic, check out this article.

The parameters of the function then end up being:

  • nodeName: Paddle

    • representing the node that, or rather whose parameter, is being modified

  • componentName: MeshRenderer

    • the internal name of the component that contains the relevant parameter

  • parameterName: u_diffuseColor

  • params: 0.7, 0.05, 0.05, 1.0

    • the amount and types of values given as params depend on the parameter to which they will be newly assigned to

    • in this case, u_diffuseColor is a Vector, requiring four double values, representing a color value

After the color change is made, then the colorToggle's value becomes the opposite of the previous one.

function changePaddleColor() {
if (colorToggle)
Utility.changeParameter('Paddle', 'MeshRenderer',
'u_diffuseColor', 0.7, 0.05, 0.05, 1.0)
else
Utility.changeParameter('Paddle', 'MeshRenderer',
'u_diffuseColor', 0.0, 1.0, 0.0, 1.0);

colorToggle = colorToggle ? false : true;
}

The changeBallMinMaxScale function assigns one of two previously defined scale factors of the ping pong ball, depending on the value of the scaleToggle variable. The scale changes between the previously set minimum and maximum scale factor. The scale factor using the same Utility.changeParameter function as mentioned for the color changing, but instead of a concrete component name, null is passed so that the entire node is affected and not a specific component of the node.

After the new scale factor is set, then the scaleToggle's value becomes the opposite of the previous one.

function changeBallMinMaxScale() {
var newScale = scaleToggle ? minimumScale : maximumScale;
Utility.changeParameter('Ball', null, 'scale', newScale, newScale,
newScale);

scaleToggle = scaleToggle ? false : true;
}

Step 5 - onCollisionLeave(firstNode, secondNode)

The onCollisionLeave callback is called when two nodes with physical characteristics finish colliding.

if (!checkIfCollidedWithPaddle(firstNode, secondNode)) 
return;

changePaddleColor();

The same check using checkIfCollidedWithPaddle is performed, as described in the previous step. If the function yields a positive result, then the changePaddleColor function is called. The value of the colorToggle in the case of this state of collision will result in changing the colour of the paddle back to red from green. The effect achieved is that whenever the ball comes in contact with the paddle, the paddle becomes green, otherwise it is red - if the colorToggle's value were initialised as true instead of false in the onStart function, the colors would be switched, i.e., the paddle would become red when colliding with the ball and green otherwise.

Step 6 - loading the finished script

The Script component needed to load the script can be added by selecting the root node RootNode and choosing it through Add ComponentScript.

The finished script can opened by choosing Choose Script File... option within the component and it should be located where it was previously stored on the computer.

The final effect can also be obtained by opening the scripting_pingPong_finished file as an already existing effect using FileOpen effect or Cmd+O keyboard shortcut in the Studio.

Download the baseline and the final effect

Did this answer your question?