How to create collidable curves (trail, lines, whatever) in Unity3D

Halloweee screenshot
Halloweee! Pumpkins and candies for a Halloween game (Android, free)

A few weeks before Halloween we decided to create a minigame to polish and learn new tricks (and treats, ha!). With not much time left for the game, we came up with simple mechanics: pumpkins fall from the top of the screen and must land safely. If pumpkins fall too fast they break and don’t score. By drawing a line (which would look like a spiderweb), players guide healthy pumpkins gently to the ground while throwing rotten pumpkins away.  Both actions score points. The goal consists just on getting as many points as posible in 64 seconds. We called it Halloweee! and it finally looked like you see on the image (you may try it on Android, it’s free)

The trickiest part was how to create a collidable and properly textured curve from a gesture drawn by the player. Thanks to Unity’s Mesh class it was not that hard.

Continue reading

Autómata finito en C# para Unity3D

Este artículo es una traducción del que escribimos originalmente en Inglés.

Los Autómatas Finitos o  Máquinas de Estado Finito (FSMs en sus siglas en Inglés) son bastante útiles en contextos muy diversos, como probablemente ya sabrás si estás leyendo ésto. Desde el menú al comportamiento complejo de las entidades de un juego, una buena FSM puede mejorar la legibilidad de tu código y simplificar el diseño. O convertirlo en un infierno de código espaguetti, dependiendo de cómo se implemente…

Continue reading

Walking on the surface of a planetoid with Quaternions

In Rain, Sand, Stars, all objects inhabit little planetoids a la Mario Galaxy (or much before that, a la The Little Prince). Therefore, at each time step, all dynamic objects must be rotated so they stand upright on the planet surface. In a game like Mario Galaxy, their transform.up should coincide with the normal of the surface they are standing on.

Rain, Sand, Stars is simpler, so this vector always coincides with the opposite to the vector from the object towards the planetoid center (black lines in the picture). Along with this vector we also need the tangent vector to the planetoid surface (red lines) and the object’s forward vector (transform.forward in Unity3D, blue lines in the picture). Yellow lines point from each enemy towards the player, but we don’t need them now. Note that although it’s 3D, objects run in circles.

Computing the tangent is easy but tricky, as it’s direction should be always constant in its local space (say, ‘looking to the right’). Knowing that the cross product of two vectors produces a third vector which is perpendicular to the plane in which the first two lie, we obtain the planet tangent using Vector3.forward, which is (0.0, 0.0, 1.0f), and the towardsPlanetCenter vector.

Vector3 towardsPlanetCenter =
  planet.position - transform.position;
 
Vector3 planetTangent = Vector3.Cross (
  Vector3.forward, 
  towardsPlanetCenter);
Our hero being chased by an infamous cube. Black lines are vectors towards the planetoid's center. Blue lines are object's facing vectors. Red lines are the tangent vector to the planet's surface, computed from Vector3.forward and the vector towards the planetoid center. You may happily ignore yellow lines (they are vectors from each enemy towards the player)

The first rotation, the one that makes objects stand upwards when walking or running, must be applied instantly. The second one rotates objects smoothly towards their desired facing direction, which coincides with the planet’s tangent (or it’s opposite) at the object’s position.

Thanks to Unity3D’s Quaternion methods, FromToRotation and LookRotation, we may achieve this in four lines of code. First, we compute the required rotation so that an object’s transform.up coincides with the opposite of towardsPlanetCenter, and we apply it:

Quaternion standUpRotation = Quaternion.FromToRotation (
  transform.up,
  -towardsPlanetCenter.normalized);
 
transform.rotation =
  standUpRotation * transform.rotation;

Then we compute the rotation that represents the object’s desired facing direction. We use a heading variable, which is either -1.0 or 1.0 depending on user input or AI, to face towards the planet tangent or its opposite. This time, we rotate the object smoothly depending on its turning speed (Zadkiel turns much faster than Yaks):

Quaternion headingRotation = Quaternion.LookRotation(
  planetTangent * heading,
  -towardsPlanetCenter);
 
transform.rotation = Quaternion.Slerp(
  transform.rotation, 
  headingRotation,
  turnSpeed);

And that’s it! Yes, I know, that’s not all. But seriously, it’s more difficult to explain it than to implement it. And you may use something similar for moving objects in true 3D around a planetoid, as Mario does.

 

Simple FSM-like structure using Coroutines in C# (Unity3D)

The previous post got a funny comment in Reddit: “Yawn. Hang on, inheritance, singletons? Bletch”. So I thought… “I may be getting rusty… let’s give those coroutines a try”. At first, coroutines seemed like a sure way of leaving behind all my (humble) OOP practices.  I though they were some kind of goto statement, probably because I had never given them a try. Ignorance is bold.

So here’s the same Miner from our previous post (yes, the one from Programming Game AI by Examples), going back and forth from the mine to the bank. But this time, each state is implemented using a coroutine. Thanks to the yield statement, coroutines can simulate our three state stages: Enter, Execute and Exit. Even better, we may easily add pauses wherever we need. If the coroutine is used to implement an entity’s AI, it can be updated every x milliseconds (depending, for example, on the entity’s reflexes), instead of every frame.

The trick lies in the FSM coroutine:

 IEnumerator FSM() {
    // Execute the current coroutine (state)
    while (true)
	yield return StartCoroutine(state.ToString());
  }

It constantly calls and waits for the execution of the current state (which is another coroutine). If the executed state changes the current state, the next iteration will launch it properly. I guess some code should be added to change states in external events, stopping any running coroutines.

So here we go! I’ve removed some variables, but it’s mostly the same behaviour:

File: CoMiner.cs

using UnityEngine;
using System.Collections;

public class CoMiner : MonoBehaviour {
  public enum State {
    EnterMineAndDigForNuggets,
    EnterBankAndDepositGold
  }

  public State state;

  public void Awake() {
    state = State.EnterMineAndDigForNuggets;

    // Start the Finite State Machine
    StartCoroutine(FSM());
  }

  IEnumerator FSM() {
    // Execute the current coroutine (state)
    while (true)
	yield return StartCoroutine(state.ToString());
  }

  IEnumerator EnterMineAndDigForNuggets() {
    /* This part works as the Enter function
    of the previous post (it's optional) */

    print("Entering the mine...");
    yield return null;

    /* Now we enter in the Execute part of a state
    which will be usually inside a while - yield block */

    bool dig = true;
    int digged = 0;
    while (dig) {
      print("Digging... " + (digged++) + " " + Time.time);
      if (digged == 2) dig = false;
      yield return new WaitForSeconds(1);
    }

    /* And finally do something before leaving
    the state (optional too) and starting a new one */

    print ("Exiting the mine...");
    state = State.EnterBankAndDepositGold;
  }

  IEnumerator EnterBankAndDepositGold() {
    //Enter
    print ("Entering the bank...");
    yield return null;

    //Execute
    bool queing = true;
    float t = Time.time;
    while (queing) {
      print ("waiting...");
      if (Time.time - t > 5) queing = false;
      yield return new WaitForSeconds(1);
    }

    //Exit
    print ("Leaving the bank a little bit richer...");
    state = State.EnterMineAndDigForNuggets;
  }
}

This way, each class contains it’s own FSM-like structure, though a simple one. No need for multiple files for each state, which can be cumbersome if a project grows (and they always do). And its really easy to follow and understand, once you understand how coroutines work.

It is a simpler solution, but pretty useful indeed! And of course, it can be combined with good OOP practices, not exactly as shown before 🙂