Unity 3D Battleship Tutorial

Unity 3D Battleship Tutorial

Battleship is a game I grew up playing. It has the right amount of strategy and randomness that eight year old me was looking for. Wanting to make a game that most are already familiar I thought Battleships, or Broadsides, (thanks Milton Bradley copyright) was a perfect fit.

So you want to learn how to create a game? You want to learn 3D game development in Unity online for free and have fun? Impossible. Build with free assets and complete access to the code? Doubly impossible. Learn while working on a game you already know? Triply imposs — You get the point. In this tutorial I walk through step-by-step building a 3D battleship style game. Feel free to use the code and assets for this game or any other creation you like. Want to copy my code/ mock my design / steal my models / tell good jokes – feel free. Make something awesome!

Plain Text of the GameManager.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class GameManager : MonoBehaviour
{
[Header(“Ships”)]
public GameObject[] ships;
public EnemyScript enemyScript;
private ShipScript shipScript;
private List<int[]> enemyShips;
private int shipIndex = 0;
public List<TileScript> allTileScripts;

[Header(“HUD”)]
public Button nextBtn;
public Button rotateBtn;
public Button replayBtn;
public Text topText;
public Text playerShipText;
public Text enemyShipText;

[Header(“Objects”)]
public GameObject missilePrefab;
public GameObject enemyMissilePrefab;
public GameObject firePrefab;
public GameObject woodDock;

private bool setupComplete = false;
private bool playerTurn = true;

private List<GameObject> playerFires = new List<GameObject>();
private List<GameObject> enemyFires = new List<GameObject>();

private int enemyShipCount = 5;
private int playerShipCount = 5;

// Start is called before the first frame update
void Start()
{
shipScript = ships[shipIndex].GetComponent<ShipScript>();
nextBtn.onClick.AddListener(() => NextShipClicked());
rotateBtn.onClick.AddListener(() => RotateClicked());
replayBtn.onClick.AddListener(() => ReplayClicked());
enemyShips = enemyScript.PlaceEnemyShips();
}

private void NextShipClicked()
{
if (!shipScript.OnGameBoard())
{
shipScript.FlashColor(Color.red);
} else
{
if(shipIndex <= ships.Length – 2)
{
shipIndex++;
shipScript = ships[shipIndex].GetComponent<ShipScript>();
shipScript.FlashColor(Color.yellow);
}
else
{
rotateBtn.gameObject.SetActive(false);
nextBtn.gameObject.SetActive(false);
woodDock.SetActive(false);
topText.text = “Guess an enemy tile.”;
setupComplete = true;
for (int i = 0; i < ships.Length; i++) ships[i].SetActive(false);
}
}

}

public void TileClicked(GameObject tile)
{
if(setupComplete && playerTurn)
{
Vector3 tilePos = tile.transform.position;
tilePos.y += 15;
playerTurn = false;
Instantiate(missilePrefab, tilePos, missilePrefab.transform.rotation);
} else if (!setupComplete)
{
PlaceShip(tile);
shipScript.SetClickedTile(tile);
}
}

private void PlaceShip(GameObject tile)
{
shipScript = ships[shipIndex].GetComponent<ShipScript>();
shipScript.ClearTileList();
Vector3 newVec = shipScript.GetOffsetVec(tile.transform.position);
ships[shipIndex].transform.localPosition = newVec;
}

void RotateClicked()
{
shipScript.RotateShip();
}

public void CheckHit(GameObject tile)
{
int tileNum = Int32.Parse(Regex.Match(tile.name, @”\d+”).Value);
int hitCount = 0;
foreach(int[] tileNumArray in enemyShips)
{
if (tileNumArray.Contains(tileNum))
{
for (int i = 0; i < tileNumArray.Length; i++)
{
if (tileNumArray[i] == tileNum)
{
tileNumArray[i] = -5;
hitCount++;
}
else if (tileNumArray[i] == -5)
{
hitCount++;
}
}
if (hitCount == tileNumArray.Length)
{
enemyShipCount–;
topText.text = “SUNK!!!!!!”;
enemyFires.Add(Instantiate(firePrefab, tile.transform.position, Quaternion.identity));
tile.GetComponent<TileScript>().SetTileColor(1, new Color32(68, 0, 0, 255));
tile.GetComponent<TileScript>().SwitchColors(1);
}
else
{
topText.text = “HIT!!”;
tile.GetComponent<TileScript>().SetTileColor(1, new Color32(255, 0, 0, 255));
tile.GetComponent<TileScript>().SwitchColors(1);
}
break;
}

}
if(hitCount == 0)
{
tile.GetComponent<TileScript>().SetTileColor(1, new Color32(38, 57, 76, 255));
tile.GetComponent<TileScript>().SwitchColors(1);
topText.text = “Missed, there is no ship there.”;
}
Invoke(“EndPlayerTurn”, 1.0f);
}

public void EnemyHitPlayer(Vector3 tile, int tileNum, GameObject hitObj)
{
enemyScript.MissileHit(tileNum);
tile.y += 0.2f;
playerFires.Add(Instantiate(firePrefab, tile, Quaternion.identity));
if (hitObj.GetComponent<ShipScript>().HitCheckSank())
{
playerShipCount–;
playerShipText.text = playerShipCount.ToString();
enemyScript.SunkPlayer();
}
Invoke(“EndEnemyTurn”, 2.0f);
}

private void EndPlayerTurn()
{
for (int i = 0; i < ships.Length; i++) ships[i].SetActive(true);
foreach (GameObject fire in playerFires) fire.SetActive(true);
foreach (GameObject fire in enemyFires) fire.SetActive(false);
enemyShipText.text = enemyShipCount.ToString();
topText.text = “Enemy’s turn”;
enemyScript.NPCTurn();
ColorAllTiles(0);
if (playerShipCount < 1) GameOver(“ENEMY WINs!!!”);
}

public void EndEnemyTurn()
{
for (int i = 0; i < ships.Length; i++) ships[i].SetActive(false);
foreach (GameObject fire in playerFires) fire.SetActive(false);
foreach (GameObject fire in enemyFires) fire.SetActive(true);
playerShipText.text = playerShipCount.ToString();
topText.text = “Select a tile”;
playerTurn = true;
ColorAllTiles(1);
if (enemyShipCount < 1) GameOver(“YOU WIN!!”);
}

private void ColorAllTiles(int colorIndex)
{
foreach (TileScript tileScript in allTileScripts)
{
tileScript.SwitchColors(colorIndex);
}
}

void GameOver(string winner)
{
topText.text = “Game Over: ” + winner;
replayBtn.gameObject.SetActive(true);
playerTurn = false;
}

void ReplayClicked()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}

}

Leave a Reply

Your email address will not be published. Required fields are marked *