Levitating Orb

using System.Collections;
using UnityEngine;

public class Levitate : MonoBehaviour 
{
   public float amplitude;      
   public float speed;                
   private float startHeight;
   private Vector3 tempPos;
     
   void Start () 
   {
       startHeight = transform.position.y;
   }
 
   void Update () 
   {       
      tempPos = transform.position;
      tempPos.y = startHeight  + amplitude * Mathf.Sin(speed * Time.time);
      transform.position = tempPos;
   }
}

I’ve been working on a new 2.5D platformer in which I have a little witch that creates a levitating orb to light her path. This script creates the levitating effect. It is attached to the orb which is a child of the witch in the hierarchy. ‘amplitude’ controls the amplitude of the sine curve. ‘speed’ controls the speed at which the orb oscillates. ‘startHeight’ sets the Y position of the bottom of the sine curve. ‘tempPos’ holds the temporary position of the orb. For a gentle effect, in the inspector I have the amplitude set at 0.3 and the speed set at 1.5.

Advertisements

Binary Serialization: Creating a File

 

using UnityEngine;
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Generic;

class PlayingCards : MonoBehaviour
{
   void Awake()
   {
      #if UNITY_IPHONE
         Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
      #endif
   }
   void Start ()
   {
      print(Application.persistentDataPath + "/Example.dat");
      CreateFile();
   }

   void CreateFile()
   {
      BinaryFormatter bf = new BinaryFormatter ();
      FileStream file = File.Create(Application.persistentDataPath + "/Example.dat");
      Cards card = new Cards();
      bf.Serialize (file, card);
      file.Close ();
   }
}

[Serializable]
class Cards
{
   public List<string> questions = new List<string>();
   public List<string> answers = new List<string> ();
   public List<int> questionSizes = new List<int> ();
   public List<int> answerSizes = new List<int> ();
}

Probably the best two things about Unity are that it’s free and that there’s a fantastic asset store with tons of useful assets including serialization assets. There are some more economical options as well as some really beefy packages that will probably handle everything you’ll ever need to do. However, serialization is quite simple. In order to create a file, you just need 5 lines of code and a basic understanding of how it works. Here are some points to consider when implementing binary serialization:

  • As always make sure you’re using the necessary namespaces.
  • If you’re developing for iPhone, you may experience some AOT/JIT compilation issues.  If you do, include a preprocessor directive indicated on lines 11 and 13 and use Environment.SetEnvironmentVariable() with the necessary arguments.
  • If you’d like to see where the file is and if it was successfully created or not, simply print Application.PersistenDataPath to see the exact location on your computer.
  • At the moment I can’t think of a reason you’d ever want to hardcode a file name but I did so here for the sake of simplicity.
  • Whatever you are going to serialize, make sure it’s serializable as indicated on line 31.

The Fisher-Yates Shuffle

using UnityEngine;
using System.Collections;

public class Shuffle : MonoBehaviour
{
   public static void ShuffleItems<T>(T[] items)
   {
      for (int i = items.Length - 1; i > 0; i--)
      {
         int r = Random.Range (0,i);
         T temp = items[i];
         items[i] = items[r];
         items[r] = temp;
      }
   }
}

If you’ve played Galactic Scholar you may have noticed the cards always come at the ship in a different order. I did this intentionally so that the player could not simply memorize the order thus making it more challenging. I achieved this by implementing the Fisher-Yates shuffle(above).

using UnityEngine;
using System.Collections;

public class PlayingCards : MonoBehaviour
{
   int[] deck = new int[52];

   void Start ()
   {
      InitializeDeck();
   }

   void Update ()
   {
      if (Input.GetKeyDown (KeyCode.Return))
      {
         Shuffle.ShuffleItems(deck);
         foreach(int card in deck)
         {
            print(card.ToString());
         }
      }
   }

   void InitializeDeck ()
   {
      for(int i = 0; i < 52; i++)
      {
         deck[i] = i + 1;
      }
   }
}

In this script we’ve created a standard deck of 52 cards with a numerical value assigned to each one. Then we call ShuffleItems() and print the result to the console.

Considerations

  1. ShuffleItems() is a generic function indicated by the <T> and T[] syntax.  This allows you to call this function with different types.
  2. Random.Range() is a Unity function that can return either an int or a float inclusive.  So if you have a range (0,5) it could return either 0 or 5.
  3. Because this is a generic function that allows you to use arrays of any length, it is very reusable thus good for modular game development.

Obligatory Singleton Post

using UnityEngine;
using System.Collections;

public class Singleton : Monobehaviour
{
   public static Singleton instance;

   void Awake()
   {
      if(instance == null)
      {
         instance = this;
         DontDestroyOnLoad(gameObject);
      }
      else if(instance != this)
      {
         Destroy(gameObject);
      }
   }
}

This is the Singleton I often use when developing in Unity. I’ve spent the past few days doing some more in depth research for using Singletons specifically for game development in Unity. I’ve learned a few things; first, everyone and their dog has written a post on Singletons, secondly, there are an endless amount of developers arguing the merits and woes of Singletons, and lastly I’ve learned that even though there are many implementations of Singletons, this basic pattern handles most scenarios.  These things have given me inspiration as to the direction of future posts and this blog in general.  I am going to keep things concise and practical.  So without further ado, here is an example of a Singleton in use.

using UnityEngine;
using System.Collections;

public class Player : Monobehaviour
{
   public static Player instance;
   public int health = 100;

   void Awake()
   {
      if(instance == null)
      {
         instance = this;
         DontDestroyOnLoad(gameObject);
      }
      else if(instance != this)
      {
         Destroy(gameObject);
      }
   }
}

In this Player class we have added health and made it Public. This is important if you want to give other scripts access to this variable.

using UnityEngine;
using System.Collections;

public class Sword : Monobehaviour
{
   void Update()
   {
      if(Input.GetKeyDown(KeyCode.Return))
      {
         Slash();
         print(Player.instance.health.ToString());
      }
   }

   void Slash()
   {
      Player.instance.health -= 30;
   }
}

In this Sword class we have a Slash function that accesses the Player’s health and subtracts it by 30. In the Update function I’ve added some code to test Slash. It does indeed go down by 30. I realize the Player can now have negative health but for the sake of simplicity I’ll leave it there as it already demonstrates a Singleton.

Considerations

  1. DontDestroyOnLoad() only works with root GameObjects or components on root GameObjects.  Therefore you should leave DontDestroyOnLoad() off of child objects at least to save yourself from warnings filling up the console.