Saturday, March 28, 2015

Unity: Two flavours of LERP





 In this post I will show two uses of LERP as you can often see in Unity scripts.


LERP


 LERP stands for linear interpolation and it is easy way how to get "mid-points" if you need to travel from point A to point B. Let's say you need to get from point A to point B in 3 seconds. We will call these 3 seconds as "MOVEMENT_TIME". You set up some counter "_currentTime" that will increase every frame with elapsed time until you reach MOVEMENT_TIME. Your current position on every frame is then calculated like this:

newPosition = point A + (point B - point A) * (_curerntTime / MOVEMENT_TIME)

 What it does is:
  • elapsed time is changed into range 0 to 1 (_curerntTime / MOVEMENT_TIME),
  • distance between ending and starting point (point B - point A) is calculated,
  • these two values are multiplied to know how much of the distance we already traveled (if time is 0 we are still in beginning and if time is 1 we are in target position),
  • finally we add the distance to starting position (point A) to get current position
 As this is used very frequently Unity has Lerp function in its Mathf class. It simplifies whole thing to single call to:

float newValue = Mathf.Lerp(valueA, valueB, time);

 But points are not single values! Fortunately, Unity has whole bunch of Lerp functions for Vector2, Vector3, Color, ... Our position change would look like this in code:

Vector2 newPosition = Vector2.Lerp(PointA, PointB, _currentTime / MOVEMENT_TIME);



Two common usages of LERP


 Now look at following picture:

 Both, ship and zeppelin are using LERP for its movement. But, it is obvious that zeppelin is not moving linearly.

 The ship is using our previous formula: we have starting point, end point and every frame we are looking for current point between them. Here is chart with our x position with regard to time:


 Here is complete code for ship:

using UnityEngine;
using System.Collections;

public class Ship : MonoBehaviour {

    public const float MOVEMENT_TIME = 3f;

    private float _startX;
    private float _endX;
    private float _currentTime;

    void Start() {
        _startX = -1f;
        _endX = 1f;
        _currentTime = 0;
    }

    void Update() {
        // update time
        _currentTime = Mathf.Min(_currentTime + Time.deltaTime, MOVEMENT_TIME);

        // update position
        Vector3 newPosition = transform.position;
        newPosition.x = Mathf.Lerp(_startX, _endX, _currentTime / MOVEMENT_TIME);
        transform.position = newPosition;

        // check if already in destination
        if (_currentTime >= MOVEMENT_TIME) {
            // move again, but switch start and destination
            float tmpX = _startX;
            _startX = _endX;
            _endX = tmpX;

            // init timer again
            _currentTime = 0;

            // turn ship to head in right direction
            Vector3 newScale = transform.localScale;
            newScale.x *= -1;
            transform.localScale = newScale;
        }
    }
}


 Zeppelin is moving also using LERP, but instead of interpolating between start and end position, it is interpolating between current and end position. It also does not calculate time between 0 and 1. Instead it uses fixed value. This fixed value says how much of the remaining distance (from current position to target position) should be traveled. As the remaining distance is getting shorter and shorter then also the calculated distance to move in every frame is shorter and shorter, so the zeppelin is slowing down. Exactly, it does never reach target position, but it gets so close to it that this is not problem for us. The chart for movement looks like this:


 And here is complete code for zeppelin:

using UnityEngine;
using System.Collections;

public class Zeppelin : MonoBehaviour {

    public const float MOVEMENT_TIME = 3f;

    private float _endX;

    void Start() {
        _endX = 1f;
        StartCoroutine(InfiniteSwap());
    }

    void Update() {
        // update position
        Vector3 newPosition = transform.position;
        newPosition.x = Mathf.Lerp(transform.position.x, _endX, MOVEMENT_TIME * 0.5f * Time.deltaTime);
        transform.position = newPosition;
    }

    IEnumerator InfiniteSwap() {
        while (true) {
            // suspend for 3 seconds
            yield return new WaitForSeconds(MOVEMENT_TIME);

            // change end position
            _endX *= -1;

            // turn zeppelin to head in right direction
            Vector3 newScale = transform.localScale;
            newScale.x *= -1;
            transform.localScale = newScale;
        }
    }
}

 We are using coroutine here to change target position every 3 seconds. In both cases we are moving form -1 to 1 in x direction.

 The second way of using Lerp has lot of usages. For example if you want your camera move from player to focus on some object, it looks much better if you do it in this way. In Unity example projects you can see this for camera movement in Survival shooter or for alarm lights intensity in Stealth project.



Friday, March 6, 2015

Mobile Income Report #8 - January & February 2015





previous parts
  Mobile Income Report #7 - December 2014
  Mobile Income Report #6 - November 2014
  Mobile Income Report #5 - October 2014 
  Mobile Income Report #4 - September 2014 
  Mobile Income Report #3 - August 2014
  Mobile Income Report #2 - July 2014
  Mobile Income Report #1 - June 2014
  Apps page - Portfolio (what are my assets?)


 If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.

 Under Apps page you can see my portfolio. It is list of the games that are then reported in Income Reports. The portfolio is regularly updated with new information (releases for new platforms, new updates, ...)



 As there were no interesting events in January I merged January and February report together.

What I did in January and February

  • Flat Jewels Match 3 is finished. In February we released iOS version at iTunes. Unfortunately, number of downloads is low. As we passed Amazon's developer select program with Android version we will have advertising campaign with 500k impressions in March for free,
  • on 27th January Shards was promoted by AppGratis on Android. We finally crossed 50k downloads at Google Play,
  • in the end of February we finished our first HTML5 game Annihilate. You can play it right here. Game is build with Phaser engine. Now we are looking for sponsors. Read whole post on Annihilate here. Annihilate is simple puzzle game in modern design. It scales well on almost any resolution:



Report

 

 First numbers for January. Here are paid apps:

 In January Shards dominates. In the beginning of the month there was positive effect of promotion of iOS version by AppGratis which took place on 31th December 2014 and promotion of Android version on 27th January.

 Here are versions supported with ads for January:

 In January income from ads was really poor. Chartboost was only $39 compared to $61 in December, but it still stays the most profitable ads network for us. Admob earnings are getting lower and lower with the same traffic. In the end of January Flat Jewels Match 3 was released for Android and you can see first $2 from it :-)


 In February paid apps did like this:

 Decrease compared to January (from $76 to $37,5). Almost all earnings are from Shards for Android and iOS.

 Fortunately, income from free versions increased little (from $84,2 to $128,5) to compensate decrease from paid apps:

 Surprise for us are earnings from Chartboost for Flat Jewels Match 3. Despite lower number of downloads compared to Shards, the earnings are almost the same. Now the question is: did we something wrong with Shards? Or did we something good with Flat Jewels Match 3? Flat Jewels Match 3 is also our first free app for iOS.

 Total income for January was $76,0 + $84,2 = $160,2 which is +3,9% increase compared to December.

 Total income for February was $37,5 + $128,5 = $166,0 which is another +3,6% increase compared to January... All I need now is to increase the base for calculation :-)



Next

 

 Next month I will report our experience with looking for sponsors for our first HTML5 game Annihilate. We are working on next HTML5 game.
 Also I invested some money into tutorials by 3DBuzz on new Unity UI. These tutorials are really great and I hope it will help me to start our first own Unity game. We already have clear idea and game design.






Sunday, March 1, 2015

Annihilate, puzzle game made with Phaser engine, is finshed!


 Finally, we just finshed our HTML5 game called Annihilate. Game was made using great Phaser engine. Annihilate is puzzle game in which you are matching pairs o atoms. In 48 levels you have to avoid various pitfalls like lasers, black holes, ...

 Now, we are looking for sponsors. If you are interested, conntact me at my gmail address: tomas[dot]rychnovsky[at]gmail[dot]com

 Game features:
  • 48 puzzle levels,
  • nice simple and clear graphics and music,
  • scales well for different screen resolutions (no black belts on iPhone nor iPad),
  • ready for easy translation



 And you can try the game right here!:



 Screenshots: