Saturday, February 18, 2012

Treasure Hunter - Early Development

I have begun work on my first solo game development project.  It is tentatively titled Treasure Hunter.  


Below is a bit of information regarding my game.  I will periodically be posting updates to the design of the game, as well as some sample code so people can see the nuts and bolts behind what I am doing.  This game is being developed in the Unity Game Engine.  When it is finished I plan to put it up for sale on a site that publishes indie games.  But readers of this blog will get sneak peaks of the game, and playable demos before it is ever launched to the public.

Here is a synopsis of the game that I posted on my design website:

Treasure Hunter will be the first game development project that is 100% my own work. The concept behind it is to be a top down adventure game similar in spirit to the classic Legend of Zelda games for NES and SNES, yet developed in a 3d game engine that supports superior visuals. My goal with this project is to undertake something that at the core is simple enough for me to complete as a 1 man team. I will be doing all of the programming, modeling, animation, story, sound effects, music, and level design. It is also going to be my first test at developing AI scripts for enemies that move, chase the player, shoot, attack, teleport, and whatever mechanics I can come up with.
As of this update it is in very early development, though the basics are in place. I will put of a prototype version to showcase my work once I feel I have developed enough content, and have packaged it in a way that looks nice and feels fun.

I am very excited about this project and look forward to producing something interactive the people will enjoy.

As always, feel free to check out my website to see what other projects I am working on.

Game Development in Unity

I have recently started learning to develop games using the Unity Game Engine. Posted here is some of my work. The games were developed using JavaScript inside the Unity Engine. Creating these games has been a process of learnign as I go. Each new project I take on I learn more about game development and I improve my programming ability. My greatest resource has been the amazing people at Walker Boys Studio. They have a top notch Unity training program availible on thier site that I have used to teach me the basics.

Crazy Clicks and Asteroid Destroyer were developed based on the tutorials on their site. The tutorials are used as a guide and help create the basic structure for the games as well as teaching the programming behind it as you go. The tutorials always end with challenges to be completed on your own. So much of the coding put into these games is actually my own work. Plenty of head banging trying to figure out how to get the programs to do what I want them to. In the end I feel I have been very successful.


All of the artwork put into these games is my own work. I have created all the models, textures and animations myself. These are always the finishing touch when it comes to making games. The polish that makes the functions look appealing and fun. I hope you enjoy what I have put together.



Here are some links to a couple of the games I have created. Click on the pics to go to the games.

Crazy Clicks - A simple clicking game made in Unity

Asteroid Destroyer - A 2d space shooter developed in Unity 




Thursday, February 16, 2012

Some code for the enemy AI for my Treasure Hunter game project.

I have recently started writing code for my Treasure Hunter game project.  The game is being developed in the Unity Game engine.  It is being designed as an old school Zelda clone, with modern graphics and gameplay elements.  This is the first major game design project I have undertaken, and my first time writing such large amounts of code.  I intend to make this a long term project.  The goal is to release something with a high enough level of quality and fun that people will actually play it.  It is also meant to be a portfolio builder that will eventually showcase my programming, animation and game design skills.

So, here is my first post.  It is just an example of the programming work I have been doing so far.  It is my first attempt at writing code for enemy AI that reacts to the player.  Right now it is some relatively simple code  that creates idle, wander, and chase states for the enemy object, based on their distance from the player.  There is also code to handle damage to the player and enemy, as well as a knock back function for both the enemy and player.

I have created some other behaviors for different enemy types not included in this code.  One teleports on top of the player when they are close enough, but the player is able to shield themselves from the damage if they react by blocking.  The other is an enemy with a ranged attack.  It attempts to maintain distance from the player, and fires projectiles to damage the player.  The projectiles may be blocked by the players shield.

I hope as I progress in my programming experience I will be able to write more and more advanced AI code.  As with everything, this is a learning experience.

Blogger does some weird stuff to formatting when I copy/paste code.  Hope this turns out readable.


//Enemy Script//

//Inspector Variables//
var health : int = 5;
var enemySpeed : float = 1.0;
var newPositionDelay : float = 3.0;

//Private Variables//
private var findPlayer : GameObject;
private var playerObject         :       Transform;
private var playerPosition         :       Vector3;
private var damageOn : boolean = true;
private var spawnPosition        :       Vector3;
private var getNewPosition : boolean = true;
private var randomOffsetX : float = 0.0;
private var randomOffsetZ : float = 0.0;
private var wanderPosition : Vector3;

function Start()
{
findPlayer = GameObject.FindWithTag ("Player");        //Load the Player into the script
playerObject = findPlayer.transform;        //Load the Players position into the script
spawnPosition = transform.position; //Save the Enemies Initial position
}

function Update ()
{
//If the player is close enough, chase them.
if (Vector3.Distance(playerObject.position, transform.position) <=  8)
{
EnemyChase();
}

//If the player is a medium distance, wander to random positions nearby.
if (Vector3.Distance(playerObject.position, transform.position) > 8 && Vector3.Distance(playerObject.position, transform.position) < 12)
{
EnemyWander();
}

//If the player is too far away, return to initial position.
if (Vector3.Distance(playerObject.position, transform.position) >  12)
{
EnemyReturnHome();
}
}


function OnTriggerEnter (other : Collider)    //If the enemy is hit by the players weapon, damage the enemy
{
if (other.gameObject.CompareTag("Weapon")) //Check if the object entering the collider is a weapon.
{
health--; //Damage Health
EnemyKnockback(); //Get Knocked Back
if(health <= 0) //Check if health is 0
{
Destroy(gameObject); //If enemy's life is 0, kill the enemy.
}
}
}

function OnTriggerStay (other : Collider) //If the player remains in contact with the enemy, damage the player periodically.
{
if (other.gameObject.CompareTag("Player") && damageOn) //Check if the object inside the collider
                                                                                                         // is a player.
{
Knockback(other.gameObject); //Knockback the player
other.GetComponent("scriptPlayer").DamageHealth();        //Damage the player
damageOn = false; //Prevent further damage until          
                                                                                                                //player has had time to react
yield WaitForSeconds(1.0); //Give player time to react
damageOn = true; //Re-enable damage to the player
}
}

function EnemyKnockback()
{
var startEnemyKnockback = Time.time;
while (Time.time <= (startEnemyKnockback +.2))
{
transform.Translate(0, 0, -12 * Time.deltaTime);
yield;
}
}


function Knockback (other : GameObject)
{  
var startKnockback = Time.time;
while (Time.time <= (startKnockback +.2))
{
other.transform.Translate(0, 0, 12 * Time.deltaTime, gameObject.transform);
yield;
}
}

function EnemyChase()
{
transform.LookAt(playerObject);
transform.position = Vector3
(Mathf.MoveTowards(transform.position.x, playerObject.transform.position.x, enemySpeed * Time.deltaTime),
Mathf.MoveTowards(transform.position.y, playerObject.transform.position.y, enemySpeed * Time.deltaTime),
Mathf.MoveTowards(transform.position.z, playerObject.transform.position.z, enemySpeed * Time.deltaTime));
}

function EnemyReturnHome()
{
transform.position = Vector3
(Mathf.MoveTowards(transform.position.x, spawnPosition.x, enemySpeed * Time.deltaTime),
Mathf.MoveTowards(transform.position.y, spawnPosition.y, enemySpeed * Time.deltaTime),
Mathf.MoveTowards(transform.position.z, spawnPosition.z, enemySpeed * Time.deltaTime));
}

function GetWanderPosition()
{
if(getNewPosition)
{
getNewPosition = false;
randomOffsetX = Random.Range(-5,5);
randomOffsetZ = Random.Range(-5,5);
wanderPosition = Vector3 (spawnPosition.x + randomOffsetX,
                                                          Terrain.activeTerrain.SampleHeight(transform.position)+ 0.2,
                                                          spawnPosition.z + randomOffsetZ);
yield WaitForSeconds (newPositionDelay + Random.Range(-1,2));
getNewPosition = true;
}
}

function EnemyWander ()
{
GetWanderPosition();
transform.LookAt(wanderPosition);
transform.position = Vector3
(Mathf.MoveTowards(transform.position.x, (wanderPosition.x), enemySpeed * Time.deltaTime),
wanderPosition.y,
Mathf.MoveTowards(transform.position.z, (wanderPosition.z), enemySpeed * Time.deltaTime));
}