
Installation:
Download and install Unity Hub from the official Unity site.
Use Unity Hub to install the Unity Editor version suitable for your project.
Open Unity Hub, create a new project, and select the appropriate template (e.g., “3D”).
User Interface:
Unity’s user interface is composed of several panels and tools that facilitate game development:
Scene View: A visual editor where you design and arrange your game objects in the 3D or 2D environment.
Game View: Displays what the player will see when the game runs.
Hierarchy Panel: Lists all objects in the current scene.
Inspector Panel: Allows you to adjust properties of the selected object, such as position, scale, and attached components.
Project Panel: Organizes all your assets, including models, scripts, and textures.
Console: Displays debugging messages and errors during development.
Unity uses C# scripting to implement game logic. Here’s how to build a simple game:
Setting Up the Scene:
Create a new scene or use the default one.
Add 3D objects (like terrain, trees, and props) using the GameObject > 3D Object menu.
Import assets such as character models or environment objects via the Assets menu.
Adding the Player Object:
Import or create a player object (e.g., a character model).
Attach a Rigidbody component for physics and a Collider to detect interactions with other objects.
Add a C# script to control player movement. Example:
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed = 5f;
void Update()
{
float horizontal = Input.GetAxis(“Horizontal”);
float vertical = Input.GetAxis(“Vertical”);
Vector3 movement = new Vector3(horizontal, 0, vertical) * moveSpeed * Time.deltaTime;
transform.Translate(movement);
}
}
Game Logic with C#:
using UnityEngine;
public class Target : MonoBehaviour
{
public int scoreValue = 10;
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag(“Arrow”))
{
GameManager.instance.AddScore(scoreValue);
Destroy(gameObject);
}
}
}
Exporting Your Game:
Unity allows you to export to multiple platforms, including PC, Android, and Web. In this case, export as follows:
Unity3D’s templates are designed to provide a starting point tailored to different types of projects, making it easier for developers of all skill levels to create high-quality games and experiences.
Unity3D offers a variety of templates that provide a solid foundation for your projects. These templates are pre-configured with settings and tools suited for specific genres or applications. Below are some common templates:
Unity offers more specialized templates to cater to various game genres and mechanics:
Unity3D templates are highly customizable, allowing you to tailor them to your vision:
Choose a Template: Start a new project in Unity Hub and select a template that suits your game’s genre or platform.
Explore the Template: Familiarize yourself with the default setup, including pre-configured objects, scripts, and settings.
Customize: Replace default assets with your own, refine mechanics, and add new gameplay features to bring your vision to life.
Test and Iterate: Use Unity’s Play Mode to test your project frequently, making adjustments as needed to improve performance and gameplay.
For this game development was needed to develop 6 C# scripts related to game and one GameManager:
Here’s the description of each script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerActions : MonoBehaviour
{
public Transform Arco;
public Transform Camara;
public float distancia = 100f;
public GameObject flechaPrefab;
public LayerMask ignoreLayer;
public float precision = 0;
public int carcaj = 10;
int contador = 0;
public int Vida = 100;
RaycastHit hit;
// Update is called once per frame
private void Update()
{
Debug.DrawRay(Camara.position, Camara.forward * distancia, Color.red);
Debug.DrawRay(Arco.position, Camara.forward * distancia, Color.blue);
if (Input.GetMouseButtonDown(0)) //0 boton izquierdo, 1 boton derecho
{
Vector3 direction = Camara.InverseTransformDirection(new Vector3(precision, precision, 1));
Debug.DrawRay(Camara.position, direction * 100f, Color.green, 5f);
contador++;
if (contador<=carcaj)
{
GameObject flechaObj = Instantiate(flechaPrefab);
GameManager.instance.AddFlechasUsadas(contador);
flechaObj.transform.position = Arco.position;
if(Physics.Raycast(Camara.position, Camara.forward, out hit, Mathf.Infinity, ~ignoreLayer))
{
flechaObj.transform.LookAt(hit.point);
}
else
{
//Vector3 dir = Camara.position + Camara.forward * 10f;
Vector3 dir = Camara.position + direction * 10f;
flechaObj.transform.LookAt(dir);
}
}
if(contador==10)
{
GameManager.instance.TxtFin(“NO ARROWS – END OF GAME”);
}
}
}
}
This script manages player actions related to using a bow and arrows.
Shooting: Detects mouse clicks to shoot arrows, instantiates an arrow prefab, and calculates its trajectory using raycasts.
Arrow management: Keeps track of available arrows in the quiver and ends the game when 10 arrows are used.
Visual feedback: Displays debug rays to indicate trajectories and targets for the arrows.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public Transform cam;
//CONTROL RATON
float vMouse;
float hMouse;
float yReal = 0.0f;
public float horizontalSpeed;
public float verticalSpeed;
//CONTROL TECLADO MOVIMIENTO
public CharacterController controller;
public float speed = 12f;
float x;
float z;
Vector3 move;
//GRAVEDAD
Vector3 velocity;
public float gravity = -15f;
bool isGrounded = false;
//SALTO
public float jumpForce = 1f;
float jumpValue;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
jumpValue = Mathf.Sqrt(jumpForce * -2 * gravity);
}
// Update is called once per frame
void Update()
{
MueveRaton();
CompruebaisGrounded();
MueveTeclado();
Salta();
Gravedad();
}
void CompruebaisGrounded()
{
if (isGrounded == true && velocity.y < 0) velocity.y = gravity;
}
void Gravedad()
{
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
void MueveRaton()
{
hMouse = Input.GetAxis(“Mouse X”) * horizontalSpeed * Time.deltaTime;
vMouse = Input.GetAxis(“Mouse Y”) * verticalSpeed * Time.deltaTime;
yReal -= vMouse;
yReal = Mathf.Clamp(yReal, -90f, 90f);
transform.Rotate(0f, hMouse, 0f);
cam.localRotation = Quaternion.Euler(yReal, 0f, 0f);
}
void MueveTeclado()
{
x = Input.GetAxis(“Horizontal”);
z = Input.GetAxis(“Vertical”);
move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
}
void Salta()
{
if(Input.GetButtonDown(“Jump”) && isGrounded) //KeyCode.Space
{
isGrounded = false;
velocity.y = jumpValue;
}
}
private void OnControllerColliderHit(ControllerColliderHit hit)
{
if (hit.collider.CompareTag(“floor”))
{
if(isGrounded ==false)
{
isGrounded = true;
}
}
}
}
Handles player movement and physical interactions.
Movement: Uses the keyboard to move the player horizontally and vertically with a CharacterController.
Camera rotation: Allows the player to control their view with the mouse, with limits to prevent over-rotation.
Jumping and gravity: Includes a jump function and applies constant gravity for realistic physics.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DianaController : MonoBehaviour, IDamage
{
public int Vida = 10;
public int puntua = 10;
public void DoDamage(int vld, bool isPlayer)
{
if (isPlayer)
{
Debug.Log(“DAMAGE ” + vld + “isPlayer =” + isPlayer);
Debug.Log(“LIFE ” + Vida);
Vida -= vld;
Debug.Log(“LIFE ” + Vida);
if (Vida <= 0) Muere();
}
}
void Muere()
{
//sistema de particulas;
GameManager.instance.AddScore(puntua);
GameManager.instance.AddDianas1();
Destroy(gameObject);
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
Represents targets (type 1 garbage bags).
Health: Each target has hit points and takes damage when hit.
Destruction: When health reaches 0, the target is removed from the game, and the score and target count are updated in the GameManager.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : MonoBehaviour, IDamage
{
public Transform target;
public int Vida=10;
public int puntua = 20;
public void DoDamage(int vld, bool isPlayer)
{
Debug.Log(“DAMAGE” + vld + “isPlayer =” + isPlayer);
if(isPlayer)
{
Vida -= vld;
if (Vida <= 0) Muere();
}
}
void Muere()
{
//sistema de particulas;
GameManager.instance.AddScore(puntua);
GameManager.instance.AddDianas2();
Destroy(gameObject);
}
// Update is called once per frame
void Update()
{
//Vector3 posNoRot = new Vector3(target.position.x, 0.0f, target.position.z);
//transform.LookAt(target);
}
}
Similar to the DianaController but represents type 2 garbage bags with different scoring.
Player interaction: Bags take damage from the player and notify the GameManager when destroyed.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Flecha : MonoBehaviour
{
public float speed = 8f;
public float lifeDuration = 2f;
float lifeTimer;
public int danyoFlecha = 10;
// Start is called before the first frame update
void Start()
{
lifeTimer = lifeDuration;
}
// Update is called once per frame
private void Update()
{
lifeTimer -= Time.deltaTime;
if (lifeTimer <= 0)
{
gameObject.SetActive(false);
}
}
private void FixedUpdate()
{
transform.position += transform.forward * speed * Time.fixedDeltaTime;
}
private void OnTriggerEnter(Collider other)
{
var nombre = other.name;
Debug.Log(nombre);
IDamage danyo = other.GetComponent<IDamage>();
if(danyo != null)
{
danyo.DoDamage(danyoFlecha, true);
gameObject.SetActive(false);
}
}
}
Manages the behaviour of arrows.
Movement: Arrows travel in a straight line and disappear after a set duration.
Collisions: Detects collisions with objects that implement the IDamage interface, applies damage, and deactivates upon impact.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public static GameManager instance;
public Text txtPuntua;
public Text txtDianasTipo1;
public Text txtDianasTipo2;
public Text txtFlechas;
public Text txtFin;
public int FlechasPendientes;
public int DianasTipo1destruidas;
public int DianasTipo2destruidas;
public int Score;
// Start is called before the first frame update
void Start()
{
instance = this;
DianasTipo1destruidas = 7;
DianasTipo2destruidas = 6;
FlechasPendientes = 10;
Score = 0;
txtFlechas.text = “Available Arrows: ” + FlechasPendientes.ToString();
txtPuntua.text = “Score: “+ Score.ToString();
txtDianasTipo1.text = “Garbage Bags Type 1: ” + DianasTipo1destruidas.ToString();
txtDianasTipo2.text = “Garbage Bags Type 2: ” + DianasTipo2destruidas.ToString();
}
public void AddFlechasUsadas(int contador)
{
FlechasPendientes = 10-contador;
txtFlechas.text = “Available Arrows: ” + FlechasPendientes.ToString();
}
public void AddDianas1()
{
DianasTipo1destruidas–;
txtDianasTipo1.text = “Garbage Bags Type 1: ” + DianasTipo1destruidas.ToString();
}
public void AddDianas2()
{
DianasTipo2destruidas–;
txtDianasTipo2.text = “Garbage Bags Type 2: ” + DianasTipo2destruidas.ToString();
}
public void AddScore(int puntos)
{
Score=Score+puntos;
txtPuntua.text = “Score: ” + Score.ToString();
}
public void TxtFin(string Txt)
{
txtFin.text = Txt;
}
}
Coordinates game statistics and user interface.
State control: Tracks remaining arrows, score, and destroyed target types.
UI updates: Updates on-screen text to inform the player about progress and the end of the game.
interface IDamage
{
void DoDamage(int vld, bool isPlayer);
}
Defines the IDamage interface, which allows objects to take damage.
Function: DoDamage(int vld, bool isPlayer) is implemented by objects like targets and enemies to handle damage logic.
Import the Image:
Check the Import Settings: