Todo juego necesita un protagonista, no importa sí es complejo o simple, es el alma de nuestro juego y el usuario debe interactuar con el. Puede ser un Ente con inteligencia propia o un simple comecocos que se ejecutará las ordenes del usuario sin planteárselo.
Para nuestro primer juego vamos a crear un protagonista muy sencillo, tan solo una simple pelota que podrá recorrer nuestro escenario en búsqueda de tesoros y huyendo de enemigos.
Este post forma parte del Tutorial de Desarrollo de Videojuegos en Unity. En post anteriores hemos creado el escenario de nuestro juego, si no lo has seguido puedes bajarte los ficheros necesarios en este enlace: ficheros_megafastball-1.
Creamos nuestro protagonista con un Standard Asset.
Lo primero va a ser importar los Standard Assets que necesitamos, en este caso vamos al menú: Assets->Import Packages->Characters.
En el cuadro de dialogo de selección de Assets nos aseguramos que estén todos seleccionados, y pulsamos el botón Import. Esto nos creara una carpeta Characters dentro de Standard Assets en la sección Project.
Dentro de la carpeta de Characters encontramos una de FirtPersonCharacter, que contiene una de RollerBall, donde hay un Prefab que es el que seleccionaremos para crear nuestra bola protagonista!!! Yo le he cambiado el nombre a FastBall. La seleccionamos y arrastramos a la sección Hierarchy. La situamos que este por encima del suelo, y en una posición centrada.
Estudiemos nuestra bola
Acabamos de crear un objeto, partiendo de una plantilla, que tiene una forma de bola, pero tiene mucho mas. Si ejecutamos nuestro juego, pulsando el botón play del situado en la parte superior central del IDE, veremos que podemos mover nuestra bola usando las teclas de cursor, o las teclas “wsad”. Es decir, el Prefab standard de RollerBall ya incorpora los scripts necesarios para el movimiento, y es mas, si lo movemos vemos que choca y rebota contra los obstáculos que hemos situado en el juego.
En rojo he marcado los dos scripts que esta usando nuestra bola. Vamos a verlos: si hacemos doble click sobre el nombre del script se nos abrirá el editor de scripts de Unity. No hace falta que los entendamos del todo, pero vamos a darle un vistazo.
Primero el código del Script Ball.
using System; using UnityEngine; namespace UnityStandardAssets.Vehicles.Ball { public class Ball : MonoBehaviour { [SerializeField] private float m_MovePower = 5; // The force added to the ball to move it. [SerializeField] private bool m_UseTorque = true; // Whether or not to use torque to move the ball. [SerializeField] private float m_MaxAngularVelocity = 25; // The maximum velocity the ball can rotate at. [SerializeField] private float m_JumpPower = 2; // The force added to the ball when it jumps. private const float k_GroundRayLength = 1f; // The length of the ray to check if the ball is grounded. private Rigidbody m_Rigidbody; private void Start() { m_Rigidbody = GetComponent<Rigidbody>(); // Set the maximum angular velocity. GetComponent<Rigidbody>().maxAngularVelocity = m_MaxAngularVelocity; } public void Move(Vector3 moveDirection, bool jump) { // If using torque to rotate the ball... if (m_UseTorque) { // ... add torque around the axis defined by the move direction. m_Rigidbody.AddTorque(new Vector3(moveDirection.z, 0, -moveDirection.x)*m_MovePower); } else { // Otherwise add force in the move direction. m_Rigidbody.AddForce(moveDirection*m_MovePower); } // If on the ground and jump is pressed... if (Physics.Raycast(transform.position, -Vector3.up, k_GroundRayLength) && jump) { // ... add force in upwards. m_Rigidbody.AddForce(Vector3.up*m_JumpPower, ForceMode.Impulse); } } } }
Por ahora, solo hace falta en que nos fijemos que las variables que define al principio son muy parecidas a las que nosotros podemos configurar desde el editor de Inspector y que hay dos funciones: Start se ejecuta al iniciarse el objeto y Move es una función publica que se va a llamar desde otra parte de Unity. ¿Desde que parte? Pues desde el otro Script: Ball User Control.
Le damos doble clik al nombre de BallUserControl y vemos una parte de su código:
... private void Update() { // Get the axis and jump input. float h = CrossPlatformInputManager.GetAxis("Horizontal"); float v = CrossPlatformInputManager.GetAxis("Vertical"); jump = CrossPlatformInputManager.GetButton("Jump"); // calculate move direction if (cam != null) { // calculate camera relative direction to move: camForward = Vector3.Scale(cam.forward, new Vector3(1, 0, 1)).normalized; move = (v*camForward + h*cam.right).normalized; } else { // we use world-relative directions in the case of no main camera move = (v*Vector3.forward + h*Vector3.right).normalized; } } ....
La mayoría de scripts tienen una función Update, esta se llama cada vez que se redibuja un frame en el juego, por lo que es el lugar ideal de poner las cosas que queremos que se ejecuten cada vez que suceda algo. En este caso calcula el movimiento, dependiendo de las teclas pulsadas y de la posición de la bola, y lo sitúan en un vector llamado move. Este vector se usa en otra función que se llama FixedUpdate que también se llama al redibujar cada Frame, y donde se usa el vector parta situar la bola en su nueva posición.
Mas propiedades de nuestro objeto
Pero nuestra bola tiene mas propiedades aparte de los Scripts, vamos a ver tan solo algunas de ellas:
- Spehre Collider: En esta sección encontramos el campo Material: si lo pulsamos nos muestra que material estamos usando y veremos que podemos escoger otros dentro de la lista de Materiales Standard. Nuestra bola es de Caucho (Rubber) pero podemos seleccionar otros materiales, como Metal, Madera, Goma, Sin fricción, con mucha Fricción, y Rebotador (Bouncy). Cada uno de estos materiales tiene comportamientos diferentes. Probadlos!!! Cambiad el material de la Bola y quedaros con el que os guste más. Con el Bouncy rebotara mucho mas y con el de zero friction, la bola, girará como una loca pero no se va a mover del sitio.
- RigidBody: Encontramos la opción de indicar si queremos que use o no la gravedad, si no la usa, no estará sujeta a nuestras leyes de la física, no se va a mover y no saltará, ni rebotará y si la hemos creado mas alta del suelo, no caerá hasta el. La opción Collision Detection nos indica cada cuanto comprueba si ha colisionado con otro objeto, la opción Discrete suele ser suficiente, para objetos con una velocidad relativa. Es decir, si estamos programando una bala, que se mueve mas rápida que la vista no es suficiente, pero si que lo es para nuestra Bola.
¿Que hemos aprendido?
- Usado un Asset Standard como protagonista.
- Descubierto que los Assets ya nos vienen con Scripts y son muy funcionales.
- Hemos mirado los Scripts y entendido (un poco) su funcionamiento.
- Hemos jugado con los materiales y visto que tiene comportamientos diferentes.
Podéis obtener el proyecto de Unity tal como ha quedado después de estos pasos en este enlace: megafastball-creacion-protagonista.