¿Como hacer un videojuego sencillo de carreras?

 

Rally Dakar

El videojuego, para pc y para teléfonos tablets, para pc manejo solo mouse , para teléfonos dedo en pantalla conducir.




Abra segunda parte con mejorías ....pos su puesto...la primera siempre es peor que la ultima.

Esta en el teléfono es jugable.......En el pc desde navegador web lo acabo de probar y e ganado la partida, ESTRATEGIA ES LA CLAVE, Y JUGAR UNAS CUANTAS VECES, ES SIMPLE PERO TIENE SU GRACIA.....



¿Como esta echo el videojuego Rally Dakar?

¿Como hacer un videojuego sencillo de carreras?

Este juego lo hice rápidamente en un día prácticamente unas 10 o 12 horas, entre que lo pensaba, lo construía, ponía hacia los gameobjets, osea los gráficos los coches , el terreno, y los topes unos simples cubos, y lo subía a gamejolt, buscaba los sonidos y recursos musicales. Una captura de vídeo del videojuego subirla a youtube.........y claro los scripts en c# para unity, estos los tenia ya medio echos del anterior videojuego.

La idea que tengo ahora es construirlos de forma que se puedan jugar desde el teléfono el phone,

Entonces no puedo cargarlos mucho tengo que mirar de hacerlos ligeros y las resoluciones mirar que sean correctas para que se vean todos los elementos del juego que son necesarios.

Bueno al grano.


1- la idea, 3 o 4 coches que se mueven solos a la meta, utilizo la IA de unity con el siguiente script


using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class PERSIGEROJO : MonoBehaviour {



Transform player;

UnityEngine.AI.NavMeshAgent nav;



void Awake ()

{



player = GameObject.FindGameObjectWithTag ("CONEJOROJO").transform;


nav = GetComponent <UnityEngine.AI.NavMeshAgent> ();

}



void Update ()

{

nav.SetDestination (player.position);

}

}



El tag con el nombre.....osea la linea completa... player = GameObject.FindGameObjectWithTag ("CONEJOROJO").transform;




CONEJOROJO es el gameobjet ,un cubo que hay al otro extremo del terreno donde se dirige el coche de color rojo, luego el lila tiene el suyo propio, el azul el suyo, y todos funcionan con este script y este tag, cada uno se dirige a su cubo, cuando lo toca, sale , la escena de que he perdido el juego, por que yo manejo el coche verde, que funciona con otros scripts, en esa escena hay un texto construido con blender que dice game over, y a su vez tiene un script de tiempo que hace se reinicie el videojuego otra vez pues, se ha perdido la partida ya que otros coches han llegado antes.


2- scripts del coche verde que manejo yo,








using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class avionvuelasolo : MonoBehaviour {



public float moveSpeed = 110f;

public float turnSpeed = 50f;



void Update ()

{




//if (Input.GetKey(KeyCode.W))////funciona contantemente al apretar W mayusculas a de ser

//if (Input.GetKeyDown(KeyCode.W))// funciona pasito a pasito

//if(Input.GetKey(KeyCode.UpArrow))

transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);



if (Input.GetKey(KeyCode.W))////funciona contantemente al apretar W mayusculas a de ser

//if (Input.GetKeyDown(KeyCode.W))// funciona pasito a pasito

//if(Input.GetKey(KeyCode.UpArrow))

transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);





if (Input.GetKey(KeyCode.S))////funciona contantemente al apretar W mayusculas a de ser

//if(Input.GetKey(KeyCode.DownArrow))

transform.Translate(-Vector3.forward * moveSpeed * Time.deltaTime);



if (Input.GetKey(KeyCode.A))////funciona contantemente al apretar W mayusculas a de ser

//if(Input.GetKey(KeyCode.LeftArrow))

transform.Rotate(Vector3.up, -turnSpeed * Time.deltaTime);


if (Input.GetKey(KeyCode.D))////funciona contantemente al apretar W mayusculas a de ser


//if(Input.GetKey(KeyCode.RightArrow))

transform.Rotate(Vector3.up, turnSpeed * Time.deltaTime);

}

}




Este script hace que el coche avance solo sin tocar ninguna tecla de pc hacia adelante, lo hice así para que desde un teléfono sin tocar nada se moviese, por que para girar el coche utilizo este siguiente script que en teléfonos móviles al tacto con el dedo en la pantalla hace que funcione el giro del coche.









using System;

using UnityEngine;

using UnityStandardAssets.CrossPlatformInput;


namespace UnityStandardAssets.Utility

{

public class SimpleMouseRotator : MonoBehaviour

{

// A mouselook behaviour with constraints which operate relative to

// this gameobject's initial rotation.

// Only rotates around local X and Y.

// Works in local coordinates, so if this object is parented

// to another moving gameobject, its local constraints will

// operate correctly

// (Think: looking out the side window of a car, or a gun turret

// on a moving spaceship with a limited angular range)

// to have no constraints on an axis, set the rotationRange to 360 or greater.

public Vector2 rotationRange = new Vector3(70, 70);

public float rotationSpeed = 10;

public float dampingTime = 0.2f;

public bool autoZeroVerticalOnMobile = true;

public bool autoZeroHorizontalOnMobile = false;

public bool relative = true;

private Vector3 m_TargetAngles;

private Vector3 m_FollowAngles;

private Vector3 m_FollowVelocity;

private Quaternion m_OriginalRotation;



private void Start()

{

m_OriginalRotation = transform.localRotation;

}



private void Update()

{

// we make initial calculations from the original local rotation

transform.localRotation = m_OriginalRotation;


// read input from mouse or mobile controls

float inputH;

float inputV;

if (relative)

{

inputH = CrossPlatformInputManager.GetAxis("Mouse X");

inputV = CrossPlatformInputManager.GetAxis("Mouse Y");


// wrap values to avoid springing quickly the wrong way from positive to negative

if (m_TargetAngles.y > 180)

{

m_TargetAngles.y -= 360;

m_FollowAngles.y -= 360;

}

if (m_TargetAngles.x > 180)

{

m_TargetAngles.x -= 360;

m_FollowAngles.x -= 360;

}

if (m_TargetAngles.y < -180)

{

m_TargetAngles.y += 360;

m_FollowAngles.y += 360;

}

if (m_TargetAngles.x < -180)

{

m_TargetAngles.x += 360;

m_FollowAngles.x += 360;

}


#if MOBILE_INPUT

// on mobile, sometimes we want input mapped directly to tilt value,

// so it springs back automatically when the look input is released.

if (autoZeroHorizontalOnMobile) {

m_TargetAngles.y = Mathf.Lerp (-rotationRange.y * 0.5f, rotationRange.y * 0.5f, inputH * .5f + .5f);

} else {

m_TargetAngles.y += inputH * rotationSpeed;

}

if (autoZeroVerticalOnMobile) {

m_TargetAngles.x = Mathf.Lerp (-rotationRange.x * 0.5f, rotationRange.x * 0.5f, inputV * .5f + .5f);

} else {

m_TargetAngles.x += inputV * rotationSpeed;

}

#else

// with mouse input, we have direct control with no springback required.

m_TargetAngles.y += inputH*rotationSpeed;

m_TargetAngles.x += inputV*rotationSpeed;

#endif


// clamp values to allowed range

m_TargetAngles.y = Mathf.Clamp(m_TargetAngles.y, -rotationRange.y*0.5f, rotationRange.y*0.5f);

m_TargetAngles.x = Mathf.Clamp(m_TargetAngles.x, -rotationRange.x*0.5f, rotationRange.x*0.5f);

}

else

{

inputH = Input.mousePosition.x;

inputV = Input.mousePosition.y;


// set values to allowed range

m_TargetAngles.y = Mathf.Lerp(-rotationRange.y*0.5f, rotationRange.y*0.5f, inputH/Screen.width);

m_TargetAngles.x = Mathf.Lerp(-rotationRange.x*0.5f, rotationRange.x*0.5f, inputV/Screen.height);

}


// smoothly interpolate current values to target angles

m_FollowAngles = Vector3.SmoothDamp(m_FollowAngles, m_TargetAngles, ref m_FollowVelocity, dampingTime);


// update the actual gameobject's rotation

transform.localRotation = m_OriginalRotation*Quaternion.Euler(-m_FollowAngles.x, m_FollowAngles.y, 0);

}

}

}





A partir de aquí para girar mas rápido o correr mas rápido o mas lento solo hay que subir o bajar los valores....osea lento es 1 rápido es 7 por que 7 es mayor que 1.....explicado para que lo entienda todo el mundo.


3- Y ganar el juego, el coche que manejamos tiene estos dos script de arriba para hacerlo funcionar y para ganar usa este script de debajo , consiste en que al tocar en la meta su cubo de color verde el mismo color que tenemos.....(cada coche tiene un color y su meta es del mismo color de cada coche).....activa la escena con el texto, echo también con blender “JUEGO GANADO O JUEGO COMPLETADO” y una música de fondo de victoria.












using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class GANASNIVEL : MonoBehaviour {



//public AudioSource tickSource;



void Start () {


//tickSource = GetComponent<AudioSource> ();




}


void Update () {

}


void OnTriggerEnter(Collider other) {

//if (other.gameObject.CompareTag ("PASOVERDE")){

//if (other.gameObject.CompareTag ("ogri2")){

if (other.gameObject.CompareTag ("MATA")){

//transform.Rotate (new Vector3 (0 * Time.deltaTime, 91, 90), Space.Self);////SOLO ROTA PERO PARA QUE?¿





//tickSource.Play ();

Application.LoadLevel (1);



}}


}





En rojo e señalado las lineas que provocan el cambio de escena, cuando los que ganan son los otro coches , el script de ellos hacen otro numero de cambio de escena, tenemos en total 3 escenas la 0 carrera de coche2, la 1 gana y la 2 pierde.







Debajo el script que produce el cambio a pierdes el juego y reinicia el videojuego, cuando los contrincantes tocan sus respectivas metas.










using UnityEngine;


// Include the namespace required to use Unity UI

using UnityEngine.UI;


using System.Collections;


public class BAJAPUNTOS0LILA : MonoBehaviour {




// Create public variables for player speed, and for the Text UI game objects

public float speed;

public Text countText;

public Text winText;









// Create private references to the rigidbody component on the player, and the count of pick up objects picked up so far

private Rigidbody rb;

private int count;/// <summary>



/// //////////////////////////////////////////

/// </summary>

//private int PUNTOS;/// <summary>

/// /////////////////////////////////////////////////

/// </summary>


// At the start of the game..

void Start ()

{




//tickSource = GetComponent<AudioSource> ();


//tickSource = Getcomponent<AudioSource> ();




// Assign the Rigidbody component to our private rb variable

rb = GetComponent<Rigidbody>();


// Set the count to zero

count = 0;


// Run the SetCountText function to update the UI (see below)

SetCountText ();


// Set the text property of our Win Text UI to an empty string, making the 'You Win' (game over message) blank

winText.text = "";

}


void OnTriggerEnter(Collider other)

{

// ..and if the game object we intersect has the tag 'Pick Up' assigned to it..



//if (other.gameObject.CompareTag ("bolaesplota"))

if (other.gameObject.CompareTag ("CONEJOLILA"))

//if (other.gameObject.CompareTag ("Terrain"))


{

// Make the other game object (the pick up) inactive, to make it disappear

//other.gameObject.SetActive (false);///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

other.gameObject.SetActive (true);

// Add one to the score variable 'count'

count = count - 1;



// Run the 'SetCountText()' function (see below)

SetCountText ();

}

}


// Create a standalone function that can update the 'countText' UI and check if the required amount to win has been achieved

void SetCountText()

{

// Update the text field of our 'countText' variable

//countText.text = "Count: " + count.ToString ();


countText.text = "VIDAS: " + count.ToString ();

// Check if our 'count' is equal to or exceeded 12

//if (count >= 20)

if (count <= -1)

{

// Set the text value of our 'winText'

winText.text = "JUEGO COMPLETADO";


//TextMeshPro = "CAMPEON GANASTES";


Application.LoadLevel (2);



}

}

}





Y el script alojado en el texto echo con blender de “GAME OVER” con un temporizador para que se reinicie el juego y volver a jugar......








using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class CAMBIANIVELPORTIEMPOTRANCURRIDO : MonoBehaviour {


[SerializeField] private float m_TimeOut = 2.0f;

[SerializeField] private bool m_DetachChildren = false;



private void Awake()

{

Invoke("DestroyNow", m_TimeOut);

}



private void DestroyNow()

{

if (m_DetachChildren)

{

transform.DetachChildren();

}

// DestroyObject(gameObject);



Application.LoadLevel (0);

}

}



Los obstáculos son para tener alguna dificultad con el juego al tener que rodearlos, esta versión la voy a mejorar con una segunda versión del juego para equilibrar velocidades, jugando con el pc e logrado ganar el juego solo con el mouse sin tocar las otras teclas , pero con el teléfono te has de colocar delante del coche azul que es el que mas se adelanta , hacer barrera y no dejar que te pase para poder ganar.











No hay comentarios:

Publicar un comentario