Video Games Development

Unity – Local Data Base – SQLite – JavaScript

Unity – Local Data Base – SQLite – JavaScript

What is SQLite?

SQLite is a database system that requires no administration, it is a single file .db that can be written to a USB memory stick.

It is not directly comparable to client/server SQL database engines such as MySQL, Oracle, PostgreSQL, or SQL Server since SQLite is trying to solve a different problem.

SQLite Works Well:

– cellphones, set-top boxes, televisions, game consoles

– media cataloging and editing suites, CAD packages, record keeping programs

– low to medium traffic websites (a conservative estimate of fewer than 100K hits/day)

Creating and Exporting:

– the resulting database is a single file that can be written to a USB memory stick or emailed to a colleague.
A DB file looks like this: PlayersSQLite.db

– it provides access to that file via standard SQL commands.

– a lot af free reader for developers and end-users
I like SQlite Browser (http://sqlitebrowser.org/)

Controls and wizards are available for users to:

Create and compact database files
Create, define, modify and delete tables
Create, define and delete indexes
Browse, edit, add and delete records
Search records
Import and export records as text
Import and export tables from/to CSV files
Import and export databases from/to SQL dump files
Issue SQL queries and inspect the results
Examine a log of all SQL commands issued by the application

Available for Windows, MacOSX, Linux

Official website at: http://www.sqlite.org/whentouse.html

Another good software to create SQLite DB is SQLite Manager, a it is a plug-in for Firefox, free and crossplatform (https://addons.mozilla.org/ru/firefox/addon/sqlite-manager/)

SQLite Browser

1. Open SQLite Browser> File> New Database> create players.db

2. Table: players

3. Add fields:
– ID – INTEGER the ptimary key – check AI and PK (AUTOINCREMENT PRIMARY KEY)
– Name – TEXT to store var:String (Pietro)
– Scores – INTEGER to store var:int (124)
– Time – REAL to store var:float (20.7)

Move field up or down if necessary

or

CREATE TABLE `players` (
	`ID`	INTEGER PRIMARY KEY AUTOINCREMENT,
	`Name`	TEXT,
	`Score`	INTEGER,
	`Time`	REAL
);

4. click ‘OK’

5. Populate the database:
Tab ‘Browse Data’
Table: Players

click ‘New Record’

the id field will auto increment

input Name – Score – Time

Andrea – 100 – 10
Antonio – 50 – 5
Serafina – 70 – 10
Erica – 20 – 5
Alice – 122 – 50

click ‘Write Changes’

SQLite and Unity

Unity 5.x comes with all SQLite Library included, you can see that in your:
C:/Programmi/Unity/Editor/Data/Mono/lib/mono/2.0/
“Mono.Data.dll”, “Mono.Data.Sqlite.dll” and “Mono.Data.SqliteClient.dll”

0. File> Build Settings…> PC MAC LINUX STAND ALONE
NOTICE: if you set WEB Player the console send you the error: Namespace ‘Mono.Data.Sqlite’ not found…
because of SQlite DOES NOT WORK with WEB PLAYER!

1. Download Precompiled Binaries for Windows 32> sqlite-dll-win32-x86-3081101.zip here:
https://www.sqlite.org/download.html
Inside the zip there are: sqlite3.dll and sqlite3.def

2. Download Precompiled Binaries for Windows 64> SQLite3-64.7z here:
http://blog.synopse.info/post/2013/03/23/Latest-version-of-sqlite3.dll-for-Windows-64-bit
There is sqlite3-64.dll, renaming to sqlite3.dll

Download library for Android> sqlite.so here:
https://github.com/ORuban/SQLite4Unity3d/tree/554b7ec0bea8fa17e5c5a11fd37b8f615dc549bc/Plugins/Android/libs/x86

2. Create

– Assets/Plugins/sqlite3.dll -> the sqlite3-64.dll renamed + sqlite3.def (Win MAC IOS)

– Assets/Plugins/Android/sqlite.so (Android)

– Unity/Scenes/MyScene.unity

– Unity/Scripts/dbAccess.js

– Unity Project Root/players.db (the database)

NOTICE: Project> Plugins> sqlite3.dll> Inspector, here you can setup the target platform, do not change anything, the recognization is automatic.

3. GameObject> Create Empty> name it GameController

DB Connection and Delete Table Contents

4. attach to GameController the script dbAccess.js:


#pragma strict

// IMPORT NAMESPACE CLASSES START ----------------------
// Mono non includone SQlite, devo importarlo a parte
// le classi le troviamo qui: C:/Programmi/Unity/Editor/Data/Mono/lib7mono/2.0/
import System.Data;  // we import our  data class
import Mono.Data.Sqlite; // we import sqlite
import System.Collections.Generic;
// IMPORT NAMESPACE CLASSES END ------------------------

// importo il namespace per verificare se un file esiste
import System.IO;

// variables for basic query access
var connection : String;
var dbcon : IDbConnection;
var dbcmd : IDbCommand;
var reader : IDataReader;

function Start () {
	OpenDB ();
}// END Start()

function Update () {
}// END Update()

// ####################################################################
// OPEN DB ############################################################
// ####################################################################
function OpenDB () {
	// Open Connection START ----------------------------
	
	// Windows MAC OS IOS +++++++++++++++++++++++++
	// è la posizione che assegnerà nella build finale
	// SE LO TROVA APRE LA CONNESSIONE
	// SE NON LO TROVA LO CREA IN AUTOMATICO NELLA ROOT DEL PROGETTO UNITY
	connection = "URI=file:players.db"; 
	// Android ++++++++++++++++++++++++++++++++++++
	// connection = "URI=file:" + p; // like this will NOT work on android
    // connection = "URI=file:" + Application.persistentDataPath + "/" + "players.db";  ---> PER ANDROID TOGLIERE QUESTO COMMENTO
    
    // DEBUG: check if connection exists START --------------------
    dbcon = new SqliteConnection(connection);
    if(dbcon != null) {
    	print ("MY COMMENT: connection to players.db OK");
    }
    else{
    	print ("MY COMMENT: connection to players.db FAIL");
    }
  	// DEBUG: check if connection exists END ----------------------
    
    dbcon.Open(); // open connection
    
	// Open Connection END --------------------------------
	
	// DEBUG: check if DB exists START --------------------
 	var fileName = "players.db";
    var path = Directory.GetCurrentDirectory() + "\\" + fileName;
    if (File.Exists(path))
    {
         print ("MY COMMENT: players.db file exists");
    }
    	else
    {
         print ("MY COMMENT: players.db file NOT exists");
    }
	// DEBUG: check if DB exists END ----------------------
}// END OpenDB

// ####################################################################
// DELETE TABLE #######################################################
// ####################################################################
// This function deletes all the data in the given table.  Forever.  WATCH OUT! Use sparingly, if at all
    function DeleteTableContents() {
    var query : String; // la definisco all'interno della funzione perchè resti limitata alla funzione corrente
    query = "DELETE FROM players" ;
    dbcmd = dbcon.CreateCommand();
    dbcmd.CommandText = query; 
    reader = dbcmd.ExecuteReader();
    Debug.Log("You have just deleted players tab");
    }

5. GameObject> UI> Button> name it Button-DeleteTableContents

Button-DeleteTableContents> Inspector> OnClick()> + > DRAG GameController and take function DeleteTableContents()

6. Play and press the button, try reload players.db with SQLite Browser, the table players will be empty.

img-001

img-002

We can analize the code:

1. import namespaces to integrate functions for ‘SQLite’ and ‘if file exist’


// IMPORT NAMESPACE CLASSES START ----------------------
// Mono non includone SQlite, devo importarlo a parte
// le classi le troviamo qui: C:/Programmi/Unity/Editor/Data/Mono/lib7mono/2.0/
import System.Data;  // we import our  data class
import Mono.Data.Sqlite; // we import sqlite
import System.Collections.Generic;
// IMPORT NAMESPACE CLASSES END ------------------------

// importo il namespace per verificare se un file esiste
import System.IO;

2. Set variables for basic query access


// variables for basic query access
var connection : String;
var dbcon : IDbConnection;
var dbcmd : IDbCommand;
var reader : IDataReader;

3. Open into Start() the DB connection


connection = "URI=file:players.db"; 
dbcon = new SqliteConnection(connection);
dbcon.Open(); // open connection

4. Delete Tab function using SQL syntax


function DeleteTableContents() {
    var query : String;
    query = "DELETE FROM players" ;
    dbcmd = dbcon.CreateCommand();
    dbcmd.CommandText = query; 
    reader = dbcmd.ExecuteReader();
    Debug.Log("You have just deleted players tab");
    }

Create Table


// ####################################################################
// CREATE TABLE #######################################################
// ####################################################################
// This function create tables
function CreateTable() { 
        // Create a table, name, column array, column type array
        var name : String = "friends";
        var col = ["Name", "Surname"];
        var colType = ["TEXT", "TEXT"];
        var query : String;
        query  = "CREATE TABLE " + name + "(" + col[0] + " " + colType[0];
        for(var i=1; i<col.length; i++) {
            query += ", " + col[i] + " " + colType[i];
        }
        query += ")";
        dbcmd = dbcon.CreateCommand(); // create empty command
        dbcmd.CommandText = query; // fill the command
        reader = dbcmd.ExecuteReader(); // execute command which returns a reader
        Debug.Log("You have just created friends tab");
    }// END CreateTable()

img-003

I can explain the code easily:

1. Set the name of the table, the name of the columns, the type of the columns
NOTICE: types can be NULL, INT, TEXT, REAL, BLOG
For more info about datatypes see: https://www.sqlite.org/datatype3.html


var name : String = "friends";
var col = ["Name", "Surname"];
var colType = ["TEXT", "TEXT"];

2. user ‘for’ to create all queries
NOTICE THE ROW: query += “)”;


for(var i=1; i<col.length; i++) {
            query += ", " + col[i] + " " + colType[i];
        }
query += ")";

Populate the DB


// #####################################################################
// INSERT INTO #########################################################
// #####################################################################
// This function insert values inside a table
function InsertInto() { // basic Insert with just values
        // our data
        var query : String;
        query = "INSERT INTO friends VALUES ('Jimi','Hendrix')";
              // INSERT INTO TABLE_NAME VALUES ('Name','Surname');
        dbcmd = dbcon.CreateCommand();
        dbcmd.CommandText = query; 
        reader = dbcmd.ExecuteReader(); 
        Debug.Log("You have just added Jimi Hendrix to friends tab");
    }// END InsertInto()

NOTICE THE APOSTROPHE: (‘Jimi’,’Hendrix’), NOT (Jimi,Hendrix)

If you insert the same data twice into the DB you will see:

img-004

Read DB content

Using the DB below:

img-005


...
// variables of ShowDatabase ()
var databaseData = new Array();
var textDbContent : UI.Text; // Assign in Inspector

function Start () {
...

// #########################################################################
// READ FULL TABLE #########################################################
// #########################################################################
    // This returns a simple JS Array
    function ReadFullTable(tableName : String) {
        var query : String;
        query = "SELECT * FROM " + tableName;
        dbcmd = dbcon.CreateCommand();
        dbcmd.CommandText = query; 
        reader = dbcmd.ExecuteReader();
        var readArray = new Array();
        while(reader.Read()) { 
            var lineArray = new Array();
            for (var i:int = 0; i < reader.FieldCount; i++)
                lineArray.Add(reader.GetValue(i)); // This reads the entries in a row
            readArray.Add(lineArray); // This makes an array of all the rows
        }
        return readArray; // return matches
    }// END ReadFullTable()
    
	function ShowDatabase (){
		databaseData = ReadFullTable("friends"); // invia i dati alla funzione per la lettura del DB
		Debug.Log ("This is the array content index 0: " + databaseData[0]); // Numa Pompilio
		Debug.Log ("This is the array content index 1: " + databaseData[1]); // Tullo Ostilio
		Debug.Log ("This is the array content index 2: " + databaseData[2]); // Anco Marzio
		Debug.Log ("This is the array content index 3: " + databaseData[3]); // Tarquinio Prisco
		Debug.Log ("This is the array content index 4: " + databaseData[4]); // Servio Tullio
		Debug.Log ("This is the array content index 5: " + databaseData[5]); // Tarquinio il Superbo
		textDbContent.text = Array(databaseData).ToString(); // Numa,Pompilio,Tullo,Ostilio,Anco,Marzio etc...
}// END ShowDatabase ()

How does it work?

1. Create a UIText> Assign to dbAccess.jstextDbContent> var textDbContent
2. Create UI. Button> Inspector OnClic()> GameController> dbAccess.ShowDatabase
3. Play
4. OnClick() -> ShowDatabase () send the table name ‘friends’ to ReadFullTable(tableName : String)
5. ReadFullTable(tableName : String) return an array
6. ShowDatabase () read the array databaseData

Select DB content WHERE


...
// variables of ShowDatabase ()
var databaseData = new Array();
var textDbContent : UI.Text; // Assign in Inspector

function Start () {
...

// #########################################################################
// READ TABLE WHERE ########################################################
// #########################################################################
    // This returns a simple JS Array
    function ReadTableWhere(tableName : String) {
        var query : String;
        query = "SELECT Surname FROM " + tableName + " WHERE Name='Servio'";
        dbcmd = dbcon.CreateCommand();
        dbcmd.CommandText = query; 
        reader = dbcmd.ExecuteReader();
        var readArray = new Array();
        while(reader.Read()) { 
            var lineArray = new Array();
            for (var i:int = 0; i < reader.FieldCount; i++)
                lineArray.Add(reader.GetValue(i)); // This reads the entries in a row
            readArray.Add(lineArray); // This makes an array of all the rows
        }
        return readArray; // return matches
    }// END ReadFullTable()
    
	function ShowDatabaseWhere (){
		databaseData = ReadTableWhere("friends"); // invia i dati alla funzione per la lettura del DB
		Debug.Log ("This is the array content index 0: " + databaseData[0]); // Tullio
		textDbContent.text = Array(databaseData).ToString(); // Tullio
}// END ShowDatabase ()

NOTICE:


query = "SELECT Surname FROM " + tableName + " WHERE Name='Servio'";
// SELECT Surname FROM friends WHERE Name='Servio'

a common mistake is omit the spaces after FROM or before WHARE as:


query = "SELECT Surname FROM" + tableName + "WHERE Name='Servio'";
// SELECT Surname FROMfriendsWHERE Name='Servio' ---> BAAAAAADDDDDDD!!!!!!

Select DB content ORDER BY



...
// variables of ShowDatabase ()
var databaseData = new Array();
var textDbContent : UI.Text; // Assign in Inspector

function Start () {
...

// #########################################################################
// ORDER BY ################################################################
// #########################################################################
    // This returns a simple JS Array
    function ReadTableOrderBy(tableName : String) {
        var query : String;
        query = "SELECT Surname FROM " + tableName + " ORDER BY Name ASC";
        dbcmd = dbcon.CreateCommand();
        dbcmd.CommandText = query; 
        reader = dbcmd.ExecuteReader();
        var readArray = new Array();
        while(reader.Read()) { 
            var lineArray = new Array();
            for (var i:int = 0; i < reader.FieldCount; i++)
                lineArray.Add(reader.GetValue(i)); // This reads the entries in a row
            readArray.Add(lineArray); // This makes an array of all the rows
        }
        return readArray; // return matches
    }// END ReadFullTable()
    
	function ShowDatabaseOrderBy (){
		databaseData = ReadTableOrderBy("friends"); // invia i dati alla funzione per la lettura del DB
		Debug.Log ("This is the array content index 0: " + databaseData[0]); // Marzio     -> Anco
		Debug.Log ("This is the array content index 1: " + databaseData[1]); // Pompilio   -> Numa
		Debug.Log ("This is the array content index 2: " + databaseData[2]); // Tullio     -> Servio
		Debug.Log ("This is the array content index 3: " + databaseData[3]); // Prisco     -> Tarquinio -> id 4 in DB
		Debug.Log ("This is the array content index 4: " + databaseData[4]); // il superbo -> Tarquinio -> id 6 in DB
		Debug.Log ("This is the array content index 5: " + databaseData[5]); // Ostilio    -> Tullo

		textDbContent.text = Array(databaseData).ToString(); // Tarquinio,Servio,Tarquinio,Numa,Tullo,Anco
}// END ShowDatabase ()

NOTICE:

	
		databaseData[3]); // Prisco     -> Tarquinio -> id 4 in DB
		databaseData[4]); // il superbo -> Tarquinio -> id 6 in DB	

Same Name but different id inside DB.

Close DB



...
// variables of ShowDatabase ()
var databaseData = new Array();
var textDbContent : UI.Text; // Assign in Inspector

function Start () {
...

// #########################################################################
// ORDER BY ################################################################
// #########################################################################
	// This returns a simple JS Array
    function ReadTableOrderBy(tableName : String) {
        var query : String;
        query = "SELECT Surname FROM " + tableName + " ORDER BY Name ASC";
        dbcmd = dbcon.CreateCommand();
        dbcmd.CommandText = query; 
        reader = dbcmd.ExecuteReader();
        var readArray = new Array();
        while(reader.Read()) { 
            var lineArray = new Array();
            for (var i:int = 0; i < reader.FieldCount; i++)
                lineArray.Add(reader.GetValue(i)); // This reads the entries in a row
            readArray.Add(lineArray); // This makes an array of all the rows
        }
        return readArray; // return matches
    }// END ReadFullTable()
    
	function ShowDatabaseOrderBy (){
		databaseData = ReadTableOrderBy("friends"); // invia i dati alla funzione per la lettura del DB
		Debug.Log ("This is the array content index 0: " + databaseData[0]); // Marzio     -> Anco
		Debug.Log ("This is the array content index 1: " + databaseData[1]); // Pompilio   -> Numa
		Debug.Log ("This is the array content index 2: " + databaseData[2]); // Tullio     -> Servio
		Debug.Log ("This is the array content index 3: " + databaseData[3]); // Prisco     -> Tarquinio -> id 4 in DB
		Debug.Log ("This is the array content index 4: " + databaseData[4]); // il superbo -> Tarquinio -> id 6 in DB
		Debug.Log ("This is the array content index 5: " + databaseData[5]); // Ostilio    -> Tullo

		textDbContent.text = Array(databaseData).ToString(); // Tarquinio,Servio,Tarquinio,Numa,Tullo,Anco
		CloseDB(); 
}// END ShowDatabase ()

// #########################################################################
// CLOSE DB ################################################################
// #########################################################################
function CloseDB() {
        reader.Close(); // clean everything up
        reader = null; 
        dbcmd.Dispose(); 
        dbcmd = null; 
        dbcon.Close(); 
        dbcon = null; 
        Debug.Log("DB Closed");
    }// END CloseDB()

References:
http://forum.unity3d.com/threads/unity-3d-android-sqlite-examples.114660/ -> very easy to understand C#
http://wiki.unity3d.com/index.php/SQLite -> complete JS classes
http://sysmagazine.com/posts/181239/
http://answers.unity3d.com/questions/188334/unity-sql-database.html

By |Unity3D, Video Games Development|Commenti disabilitati su Unity – Local Data Base – SQLite – JavaScript

3D Low Poly Characters for Games – Basic Workflow

Hi all,
today I will write about my favourite workflow to create low poly characters for games.
I will use 3DS Max + 3D Coat + Substance Painter + Photoshop.
You can do the same with other softwares, for example using 3DS Max + MudBox or Maya + ZBrush and so on…
The important is the file format you choose to exchange data.
To avoid plugins with fragile bridges I export using .fbx format + bitmap textures, after that I reconstruct by hand shaders inside Unity or Unreal.
With this workflow every software are independent and I can change tools whenever.

3DS Max – Scene Setup

1. Setup the scene with the System Unit Scale>1 Unit=1,0 Centimeters;
as described here:
http://www.lucedigitale.com/blog/3ds-max-micro-reference-manual-unit-setup-interiors/

2. Create a Box of 1x1x1m as reference

3. Create one or more Planes of 1x1m to map the image reference of your character, you will resize it to 1,80m if your character is 1,80m height

4. Setup the Viewport: Shaded + Edged Faces

5. RIGHT COLUMN> Utilities> Polygon Count

3DS Max – Modeling one side

CASE 1a.
I have a small collection of 1.000 poly people, male, female, fat, old, cartoon etc… with a very basic poly structure, starting from here I save a lot of time.
The low res character have a basic T pose and a structure suitable for animations.
Go to point 2

CASE 1b.
If you start from a hires model you will need first retopo it using 3D Coat.
Follow the lesson here:
http://www.lucedigitale.com/blog/3d-coat-retopo/
Consider to generate normal + occlusion map here to use the detail of hi res mesh.
Export to 3DS Max.
Go to point 2

2. RIGHT COLUMN> RMB over the Mesh name> Convert To: Editable Poly

4. The most used tools of ‘Editable Poly’ are:

Element

– Attach
– Detach

Polygon

– Create
– Slice Plane
– Quick Slice
– Cut (IT WORKS GREAT!)
– Make Planar
– View Align
– Relax
– Auto Smooth
– Use NURMS Subdivision (RMB over the Mesh name> Convert To: Editable Poly to collapse)

Border

– Double Click to select the entire loop
– CTRL + Click to use Additive Selection
– Split

Vertex

– Remove (remove the vertex without erase poly structure)
– Weld
– Target Weld
– Remove Isolated Vertices (to clear the mesh)

3DS Max – Mirror the other side

1. ‘Editable Poly’> select the middle vertices> Make Planar X> Move command to X=0

2. ‘Editable Poly’> modifers ‘Mirror’> Mirror AxisX, check ‘Copy’

3. ‘Editable Poly’> ‘Show end result on’

4. In the end ‘Editable Poly’> Vertex> Weld

5. RMB over the Mesh name> Collapse All

3DS Max – Export

1. RIGHT COLUMN> Hierarchy> Affect Pivot Only> move to 0,0,0

2. RIGHT COLUMN> Utilities> Reset XForm

3. Select the Mesh> RIGHT COLUMN> Modify> Modifier List> UVW Mapping Clear> RMB> Collapse All (remove old UVW)

4. Select the mesh> Export> Export Selected> name.fbx

3D-Coat – UV Mapping – Paint Texture

Remember that for games you have only one texture, usually 1024x1024px with all body UVW.
Leave more space for head and hands.

1. Run 3D Coat, into Wizard window select ‘UV Map Mesh’ etc…
Follow my tutorial here:
http://www.lucedigitale.com/blog/3d-coat-uv-mapping/

2. Switch 3D Coat to Paint.
Follow my tutorial here:
http://www.lucedigitale.com/blog/3d-coat-paint-texture/

You can paint here only diffuse channel, or diffuse + normal + specular.

3D Coat – Export

1. LEFT COLUMN> Commands> Apply UV-set
2. File> Export Model> .fbx and texture will be exported in the same folder
3. ‘OK’

Allegorithmic – Bitmap2Material

If you paint only diffuse color you can generate normal and specular with just one click using ‘Bitmap2Material’ software.
Follow the lesson here:
http://www.lucedigitale.com/blog/allegorithmic-bitmap2material-basic-tutorial/

Allegorithmic – Substance Painter – Paint Texture

To add more detail to your texture you can you Substance Painter, there are unbelivable tools here as ‘Paint with particles’

Follow the lesson here:
http://www.lucedigitale.com/blog/allegorithmic-substance-painter-basic-tutorial/

Photoshop

Use Photoshop for textures color correction.

3DS Max – Importing – Material

1. 3DS Max> Import> .fbx
2. Select the object> RIGHT COLUMN> Modify> Modifier List> Unwrap UVW
3. Select Unwrap UVW modifier> Edit UVs> Open UV Editor…, then you will see the work you have done using 3D Coat
4. Create a Material> Diffuse > Bitmap> assign the color texture created by 3D Coat, activate ‘Show Shaded Material’
5. DRAG and DROP the Material over the Mesh in the viewport

3DS Max – Face Expression

There are many ways to do that, the classic is:

1. Edit> Cloce> Copy and duplicate the Mesh, and move away from the original one, name it ‘Open Mouth’

2. Modify the face to create a new expression, not add or remove vertex o poly, only move it.

3. Select the original Mesh> RIGHT COLUMN> Modify> Modifier List> Morpher> Pick Object from Scene

4. Create others face expressions, try google-images ‘face expression’ to find useful photos

Follow the tutorial here:
http://www.lucedigitale.com/blog/3ds-max-micro-reference-manual-modifiers-animation-morpher/

3DS Max – Skeletal Animation

CASE 1. Humans
Use’Biped’ + Skin modifier
Follow the lesson here:
http://www.lucedigitale.com/blog/3ds-max-rigging-biped-skin/

CASE 2. Animals
Use ‘CAT’ rig + Skin modifier
Follow the lesson here:
http://www.lucedigitale.com/blog/3ds-max-rigging-cat-skin/

ADDITIONAL BONES
Follow the lesson here:
http://www.lucedigitale.com/blog/3ds-max-micro-reference-manual-animation-bones/

INVERSE KINEMATICS
Follow the lesson here:
http://www.lucedigitale.com/blog/3ds-max-micro-reference-manual-animation-inverse-kinematics/

3DS Max – Open Subdivision Surfaces

In this step you will convert the low poly model in a hi res model for a cinematic intro.

1. ‘Editable Poly’> modifers ‘OpenSubdiv’

3DS Max – Export for Games

The important is the file format you choose to exchange data.
To avoid plugins with fragile bridges I export using .fbx format + bitmap textures (diffuse + specular + normal + occlusion), after that I reconstruct by hand shaders inside Unity or Unreal Engine.
With this workflow every software are independent and I can change tools whenever.

By |3D Graphic, 3DS Max, Video Games Development|Commenti disabilitati su 3D Low Poly Characters for Games – Basic Workflow

MMORPG Anatomy – Basic Concepts

Today I will write about creating a MMORPG, basic concepts and variables only.

First, what is a MMORPG?

Massively multiplayer online role-playing games (MMORPGs) blend the genres of role-playing video games and massively multiplayer online games, potentially in the form of web browser-based games, in which a very large number of players interact with one another within a world.

As in all RPGs, the player assume the role of a character (often in a fantasy world or science-fiction world) and takes control over many of that character’s actions. MMORPGs are distinguished from single-player or small multi-player online RPGs by the number of players able to interact together, and by the game’s persistent world (usually hosted by the game’s publisher), which continues to exist and evolve while the player is offline and away from the game.

Main concepts

The idea is:
1. You, player have to fight monsters and/or other players to improve your skills.
2. Over time the strong players/monsters are going to beat you because they have more skills and power…
3. It’s time to improve your skill to take your revenge… again and again…

We have 2 protagonist: the player and the monster, this is the ultra basic concept, but it is not simple as it looks.

Click over the flow chart below:

mmorpg-anatomy-by-andrea-tonin-001

Classes

In a classic MMORPG there are 4 classes, every class has different skills and features.
This step is really important to understand because if you fail the character setup the game will be trash.
The right setup  is important to improve team play, strategies and general game play.

See the table below:

mmorpg-anatomy-by-andrea-tonin-002

I try to explain briefly:

1. DPS with short-range weapon, he deals great damage in a very short time. He has light leather armor, good endurance and good speed.

2. TANK. He wears heavy metal armor, he is slow while in combat but has great endurance. His main task is take aggro from monster and resist to frontal attacks to protect other party members.

3. DPS with long-range weapon, he deals good damage in a very short time. He has light leather armor, less endurance than DPS with melee weapon but he moves faster.

4. (Cute!) HEALER. She wears a cloth tunic, she has low endurance but can heal herself and, very important, others party members. Healer usually has buff and debuff ability.

Ok, these are main classes, after that you can imagine intermediate classes as Bersek, Assasin, Mistic, Gunner, Thief with unique abilities; the only limit is your fantasy! Remember that players like fine tuning and choose between a lot of characters and features!

Cast Time and Cool Down

MMORPG is not a Shoot’em Up, inside the game the player can’t spell 100 fire balls per second! He is not a heavy machine gun :/
We need setup inside our code a Cast Time, a Cool Down and a Skill Energy.
– Every magic/moves use an amount of Skill Energy per second.
– Cast Time is the time you need to spell a magic, or the time you need to lift your heavy sword to blow your foe. Light damage move needs low cast time, hight damage move needs long cast time.
– Cool Down is the wait time you need to repeat a move.

Press the key -> Cast Time counter -> Play Animation / Skill energy consumption -> Cool Down counter -> Press the key … and so on …

When player make a combo of moves he has to discover the better combination considering Damage/Cast Time/Cool Down/Skill Energy needed, it is very funny.
This gameplay rewads at the same time good reflex and tactics, it is like a chess game, but with more action :)

Combat Tactics

Understand the combact tactics is essential to create the AI for monsters in a MMORPG, you can see a simple example below:

mmorpg-anatomy-by-andrea-tonin-003

1. TANK takes Aggro to protect other party members and deals damage.
2. DPS with short-range weapon deals damage rear of the monster, to avoid frontal attacks.
3. DPS with long-range weapon deals damage far away of the monster, and support HEALER.
4. HEALER run a lot near and far away the monster to support all party members, also in her spare time, deals damage.

It is clear that our monster will need:
– long range attacks
– short range attacks
– global attacks to damage every party member at the same time.
– attacks to damage
– attacks to stun
– attacks to throwdown
– attacks to debuff
– special features

Next Time I will talk about AI for monsters.

Have a nice day

Andrea

Thanks to:
Roberto ‘Drago’ for the useful informations about general mmorpg gameplay
Chicca ‘Coccinella’, my favorite Priest/Healer 😛

By |Video Games Development|Commenti disabilitati su MMORPG Anatomy – Basic Concepts

How to monetize an Indie Videogame

Have you just developed your first indie videogame? Good! But now we have to monetize!

Begin your marketing campaign the moment you have something that illustrates the fundamental mechanics and look of your game.

Splash Page

Create your videogame splash page, it will be your most important marketing tool!
You need some images, a video trailer and a brief presentation, your contacts and a giant download button :)
Be social! It is important to collect fans, to start you have to create a facebook and twitter pages.

Press Kit

Create for your Game journalists ready to use materials:

– Relevant Screenshots
– Video
– Press Coverage
– Game Info Sheet
– Fact Sheet
– Logos and Awards

To create apress kit see http://dopresskit.com/ also.

Where can I self promote?

During the development process, my advice is post your WIP (work in progress) inside forums and social media group for developers.
There are a lot of nice people here that can give you constructive opinions about content, graphic, music and appeal.
If you are a lucky guy, you may be contacted by an editor before even finish the game.

A good place to self promotion is:

– http://www.gamasutra.com/
– http://indiemegabooth.com/
– http://www.reddit.com/r/indiegaming
– http://www.indiecade.com/
– http://www.rockpapershotgun.com/
– http://kotaku.com/
– http://indiegames.com/index.html
– http://www.cinemablend.com/games/
– http://www.tigsource.com/
– http://indiegamemag.com/
– http://www.pcgamesn.com/indie
– http://theindiemine.com/
– http://indiegamerchick.com/
– http://gamejolt.com/
– http://www.indieteamup.com/
– http://www.gamespress.com/
– http://www.nomsg.net/
– http://videogamecaster.com/

Cross Promotion

– http://moregamers.com/

Game Jam

– http://globalgamejam.org/
– http://nordicgamejam.org/
– http://www.orcajam.com/
– http://www.tojam.ca/home/default.asp
– http://www.trianglegamejam.com/

Find a Publisher

Try to find a publisher, you can have a direct contact with him using his website.
Remember, the best practice is obtain a minimum of royalty in advance or sign a good contract flat fee.

Here a list a publisher fro Wikipedia:
– http://en.wikipedia.org/wiki/List_of_video_game_publishers

3D RAZA

– http://www.3draza.com

Type: Publisher finding

It connect your productions with large video game publishers who also distribute the games.
Videogame projects are revised case by case.
In exchange for the videogame publishing and distribution, they will take 15% of the game sales.

Steam

– http://www.steampowered.com/steamworks/FAQ.php
– http://steamcommunity.com/greenlight/ (great exposition here)

Type: publisher

Now your game can take advantage of a gaming platform that has over 40 million players worldwide and spans multiple systems.

It’s free: There’s no charge for bandwidth, updating, or activation of copies at retail or from third-party digital distributors.

It’s freeing: With Steamworks you avoid the overhead and delay of certification requirements—there are none. Distribute your game on your terms, updating it when and as often as you want

Ad Sense

– http://www.google.com/adsense/start/

Type: Pay per click

Ad Sense program of Google can be a good way to earn money, but you need a lot of users.
Ad Sense works well with Google Analitycs and other Web Master Tools of Google.
ADS can turn off users alot if you abuse of that.

Revenue: Ad Sense will pay you per click, 1000 impressions can return about 1 USD.

skillz – eSports for Everyone

– http://skillz.com/

Type: Play for cash

Skillz is the first cash competition platform for mobile games.

Skillz is the only place where you can win bragging rights and real money by playing your favorite mobile games. Compete against friends and rivals in exciting multiplayer competitions and show off your skills today!

How does it worK:
1. Create a free Skillz account and use it to log in to your favorite Skillz-enabled game.
2. Practice by playing for Z, the Skillz virtual currency. When you’re ready to win real money, enter a cash competition!
3. Get match results and collect your prize as soon as you and your opponents are done playing. You can withdraw your winnings anytime.

Revenue: enabling pay-to-play cash tournaments. Monetize gamers in a way that aligns with their competitive nature.

– http://cashplay.co/

Type: Play for cash

Integration of the Cashplay platform is simple and typically takes no longer than two days of programing for a mobile game integration. Cashplay currently supports games developed for iOS, Android and Unity.

Cashplay offers developers a completely new way to generate additional revenue from their mobile games via offering player vs. player cash tournaments.

Revenue: game developers who integrate Cashplay are rewarded on a revenue share basis meaning that you can earn up to 60% of the profit generated from every single completed cash tournament or challenge.

FGL

https://www.fgl.com

Type: sponsorship – publishing – monetize

Over 7,000 publishers are on FGL looking to buy HTML5, Android, iOS, Unity and Flash games right now.

Beefjack Promote

– http://promote.beefjack.com/

Type: sponsorship – publishing – monetize

Seriouslyweb

– http://seriouslyweb.com/services/indie-game-marketing

Type: sponsorship – publishing – monetize

Crowd funding

Crowdfunding is the practice of funding a project or venture by raising monetary contributions from a large number of people, typically via the internet. If you want find investors you will need a great presentation with the best graphic, cool characters, good music.
A video will be more effective of thousands of written words!

– https://www.kickstarter.com/
– https://www.indiegogo.com/
– http://epocu.com/

Alphafunding

This allows you to get your game out into the public eye before its released, and maybe make a few bucks in the process.

– http://www.desura.com/

Free-to-play

Create a Free-to-play game, find thousands of users and add pay items, props or quest.
This is the way of Dota2, Tera on Line, League of Legends and others.
Inside Tera on Line, a free fantasy MMORPG there are a lot of packs from 4 USD to 50 USD to make your character cool ;p
Walking in Tera I have seen a lot of customized characters, I think some characters have at least $ 100 of cosmetics!

IMO monetize a F2P game is a fascinating process that involves psychology, art and UXD (User Interface Design)

Psychology and Free-to-Play

– Flow Theory
Introduced by Mihaly Csikszentmihalyi, flow theory is something all gamers have been through. It’s that feeling of being fully immersed in a game not knowing how much time has passed.
Flow theory can be defined as a state of positive immersion in an activity. Its components are full absorption in that activity, clear goals, a high degree of concentration, and a distorted sense of time.
This is the state that can lead to impulse purchases.

– Impulse Purchases
Purchasing virtual goods largely relies on impulse buying, as there is little planning involved. Players usually purchase virtual goods after playing the game a certain amount of time and this differs for each game.

Virtual Goods

– Vanity Items
Vanity items provide purely aesthetic purposes, such as items that can change the look of an in-game avatar.

– Power Enhancements
Power enhancing items elevate the player’s abilities in the game, and therefore affect game play overall.

– Boosts
Boosts accelerate progression or make the game easier to play by speeding up game play elements, such as getting experiance point inside and RPG

– Consumables
gThey give the player the same kinds of upgrades

– Monetization Strategies
Now that we know what to sell, how do we sell it? The most basic necessity is having multiple ways to pay to remove any friction and help increase conversion of non-paying to paying players. The longer a user plays, the more likely they will pay. Other strategies include having a store that’s simple to navigate and constantly checking metrics.

Subscription Fees
Offering subscriptions can be part of almost any monetization strategy, and it offers great flexibility. Subscribers are power users.
Offering discounts, giving hard currency each month, having subscriber-only events, these are all ways to create more value and give players incentive to become subscribers.

By |Video Games Development, Web Business|Commenti disabilitati su How to monetize an Indie Videogame

Unity3D – Tutorials – UI – Input Field – JS

Unity3D – Tutorials – UI – Input Field – JS

The new UI system give us a new Input Field, in this tutorials we are going to create a responsive ‘Input Field’ in the middle of the screen, get the user input and render it over a label.

Create a scene with:

– Main Camera

– Canvas
-> InputField
->> Placeholder
->> Text (the text of InputField)
-> Text (a label)

– EventSystem

– GameControl (Empty)

Hierarchy> Canvas> Inspector> Canvas Scaler (Script):
– Reference Resolution: X=800 Y=600
– Screen Marìtch Mode: Match Width Or Height

Hierarchy> InputField> Inspector
> Rect Transform
– Pos X=0 Y=0 Z=0
– Width= 200 Height=30
> Input Field (Script)
– Character Limit = 10 (max 10 characters allowed)

Hierarchy> InputField> Placeholder> Inspector
> Text (Script)
– Text= ‘Enter your name…, max 10 characters’

Hierchy> Text (a label)> Inspector
> Rect Transform>
– Pos X=0 Y=0 Z=0
– Width= 100 Height=100

> Text (Script)
– Text= ‘Your name here’

Now we will see in the middle of the screen:

Your name here -> (label)
|Enter your name…, max 10 characters | -> (Input Field)

Attach to GameController gameobject GameControllerScript.js:


#pragma strict
 
var MyInputField : UI.InputField; // ASSIGN IN INSPECTOR the InputField 
var TextGetInputField : UI.Text; // ASSIGN IN INSPECTOR the text of InputField
var TextLabel: UI.Text; // ASSIGN IN INSPECTOR the text of the label
 
function Awake () {
}// END Awake()
 
function Start () {
        // Focus on InputField if doesn't make sense to force the user to click on it.
	MyInputField.ActivateInputField();
	MyInputField.Select();
}// END Start()
 
function Update () {
	TextLabel.text = 'Your name is: ' + TextGetInputField.text;
}// END Update()

Hierarchy> Canvas/InputField> DRAG AND DROP over var MyInputField
Hierarchy> Canvas/InputField/Text> DRAG AND DROP over var TextGetInputField
Hierarchy> Canvas/Text> DRAG AND DROP over var TextLabel

Play and enjoy!

I like group all UI game objects in a single script, getting they from Inspector, in my opinion it is the easy way to manage a lot of text.

Reference: http://docs.unity3d.com/460/Documentation/ScriptReference/UI.InputField.html

By |Unity3D, Video Games Development|Commenti disabilitati su Unity3D – Tutorials – UI – Input Field – JS