techmania-docs

Documentations of TECHMANIA projects, hosted in a repo so they can be localized.


Project maintained by techmania-team Hosted on GitHub Pages — Theme by mattgraham

Applies to version: 2.3

This page explains how to define an animation for combo text.

Animation, curves and key frames

In the context of combo text, an animation is a collection of curves. Each curve controls one attribute of the combo text, and describes how that attribute changes over time.

A curve is a collection of key frames, each specifying the value of the controlled attribute at a specified time.

This is rather abstract so let’s look at an example. This is also the default animation if a combo skin does not define an animation.

    "animationCurves": [
        {
            "keys": [
                {
                    "time": 0,
                    "value": 1.2
                },
                {
                    "time": 0.1,
                    "value": 0.8
                },
                {
                    "time": 0.133,
                    "value": 1.1
                },
                {
                    "time": 0.167,
                    "value": 1
                },
                {
                    "time": 1,
                    "value": 1
                }
            ],
            "attribute": "scaleX"
        },
        {
            "keys": [
                {
                    "time": 0,
                    "value": 1.2
                },
                {
                    "time": 0.1,
                    "value": 0.8
                },
                {
                    "time": 0.133,
                    "value": 1.1
                },
                {
                    "time": 0.167,
                    "value": 1
                },
                {
                    "time": 0.833,
                    "value": 1
                },
                {
                    "time": 1,
                    "value": 2
                }
            ],
            "attribute": "scaleY"
        },
        {
            "keys": [
                {
                    "time": 0,
                    "value": 0.5,
                    "outTangent": 8
                },
                {
                    "time": 0.1,
                    "value": 1
                },
                {
                    "time": 0.833,
                    "value": 1
                },
                {
                    "time": 1,
                    "value": 0
                }
            ],
            "attribute": "alpha"
        }
    ]

This animation consists of 3 curves.

Looking at the scaleX curve, it consists of 5 key frames. Put together, this curve:

The scaleY curve is similar to the scaleX one, except there’s an additional stretch to 2x normal height near the end.

The alpha curve makes the combo text start half transparent, then gradually become fully opaque, hold for a while, then gradually become fully transparent (while scaleY curve is doing its final stretch). The outTangent thing will be explained later.

The three curves apply simultaneously, combining into one animation for the combo text.

Here’s an image representation of the 3 curves:

image

animationCurves format

The animation:

"animationCurves": [
    <curve 1>,
    <curve 2>,
    ...
]

A curve:

{
    "keys": [
        <key frame 1>,
        <key frame 2>,
        ...
    ],
    "attribute": <attribute to control>,
    "loopMode": <loop mode>
}

"attribute" must be one of:

"loopMode" is optional, and must be one of:

Attributes and loop modes will be explained in later sections.

A key frame:

{
    "time": <time>,
    "value": <value>,
    "inTangent": <in tangent>,
    "outTangent": <out tangent>,
    "inWeight": <in weight>,
    "outWeight": <out weight>,
    "weightedMode": <weighted mode>
}

All fields other than "time" and "value" are optional and default to 0. Tangents and weights will be explained in a later section.

Attributes

Here are all the attributes you can control via curves.

translationX and translationY

These attributes move the combo text away from its “normal” position (distanceToNote pixels above the note being played). translationX moves the combo text left (when negative) and right (when positive); translationY moves the combo text down (when negative) and up (when negative).

Unit: pixel (scaled so the game window’s height is 1080 pixels)

Default value: 0

An image showing the effect of translationX and translationY

rotationInDegrees

This attribute rotates the combo text around its center counterclockwise.

Unit: degree

Default value: 0

An image showing the effect of rotationInDegrees

scaleX and scaleY

These attributes stretch or shrink the combo text from its “normal” size, in the horizontal and vertical direction, respectively.

Unit: multiples of the “normal” size

Default value: 1

An image showing the effect of scaleX and scaleY

alpha

This attribute makes the combo text transparent (0) or opaque (1). Values outside of [0, 1] are meaningless.

Unit: none

Default value: 1

An image showing the effect of alpha

Loop mode

Each curve may optionally specify a loop mode, which indicates how the animation behaves when time is outside of the range defined by key frames.

once

The animation will play once and hold at the value at the final key frame. This is the default loop mode.

pingpong

The animation will play to the end, then reverse to the beginning as if time flows backwards, then play forward to the end again, ad infinitum.

loop

The animation will play to the end, then instantly revert to the beginning and play again to the end, ad infinitum.

An image showing the three loop modes

Tangent and weight

If you need finer control of your curve’s shape, tangent and weight will come into play. They are defined on key frames, and control how a curve’s value is interpolated between each pair of key frames.

inTangent and outTangent

inTangent controls the slope of the curve as it approaches the key frame from the previous one; outTangent controls the slope of the curve as it leaves the key frame towards the next one. Tangents can be any real number, and the default value is zero.

An image showing the curve shape at different tangents

inWeight, outWeight and weightedMode

By default, each segment of the curve between two key frames is affected equally by their values and tangents, but this can be changed via weight.

Before setting inWeight and outWeight, make sure you set weightedMode to a non-zero value so they are meaningful. The possible values of weightedMode are:

When inWeight and outWeight are meaningful, their values should be in [0, 1], and the default value is 0. Larger values mean the key frame’s value and tangent have a larger influence on the curve’s shape before or after the key frame.

When inWeight and outWeight are meaningless, the curve will be calculated as if the weight is 0.333.

An image showing the curve shape at different tangents

A tool to edit curves

To make it easier to define curves, we provide a script that allows you to use Unity’s built-in tools to edit a curve, and translate it to the combo skin’s format. To use this script:

A screenshot of creating a new project in Unity Hub

A screenshot of creating a new script

using System.Text;
using UnityEngine;

public class CurveTest : MonoBehaviour
{
    public AnimationCurve curve;

    private void OnGUI()
    {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.AppendLine("{");
        stringBuilder.AppendLine("  \"keys\": [");
        for (int i = 0; i < curve.keys.Length; i++)
        {
            Keyframe k = curve.keys[i];
            stringBuilder.AppendLine("    {");
            stringBuilder.AppendLine($"      \"time\": {k.time},");
            stringBuilder.AppendLine($"      \"value\": {k.value},");
            stringBuilder.AppendLine($"      \"inTangent\": {k.inTangent},");
            stringBuilder.AppendLine($"      \"outTangent\": {k.outTangent},");
            stringBuilder.AppendLine($"      \"inWeight\": {k.inWeight},");
            stringBuilder.AppendLine($"      \"outWeight\": {k.outWeight},");
            stringBuilder.AppendLine($"      \"weightedMode\": {(int)k.weightedMode}");
            stringBuilder.Append("    }");
            if (i < curve.keys.Length - 1)
            {
                stringBuilder.Append(",");
            }
            stringBuilder.AppendLine();
        }
        stringBuilder.AppendLine("  ],");
        stringBuilder.AppendLine("  \"attribute\": \"REPLACE WITH THE ATTRIBUTE TO ANIMATE\"");
        stringBuilder.AppendLine("}");
        GUI.Window(0, new Rect(0, 0, Screen.width, Screen.height),
            (int windowID) =>
            {
                GUI.TextArea(new Rect(0, 20, Screen.width, Screen.height - 20),
                    stringBuilder.ToString());
            }, "");
    }
}

A screenshot showing where the drag should start and end

A screenshot showing where to find the curve property

A screenshot showing the play button and the game view