En todo videojuego existen diferentes formas o maneras de mostrar las vidas del player o enemigos. Por lo tanto he considerado importante realizar un script basado en JS (javascript) el cual muestre por medio de una barra, las vidas del personaje principal.
Como se indica en la parte superior este script está realiazado en JS.
En primera instancia lo que debemos de tener en consideración es la relación existente entre los siguientes scripts. Primero debemos de crear el entorno en el cual nuestro player se va a ver afectado por el enemigo.
En mi caso he elaborado un plano, un cubo (enemigo), y el player (Primera Persona). Se pueden optimizar los scripts a realizar pero en mi caso he elaborado 3 Scripts para que se aprecie la mecánica.
El primer Script "muestra_vidas" se lo colocaremos a la cámara o a un gameobject vació, puesto que este script permitirá que se muestren las texturas de la vida del player. Este script posee la variable progress en la cual almacenaré la vida total del player. Las variables de tipo Texture2D sirven para adicionar las texturas de la barra de vida y la del fondo de la barra. Las texturas a usar pueden estar en formato PNG.
Adicional se han aumentado variables de tipo float que permiten almacenar el tamaño de la pantalla a visualizar y realizar una operación matemática para devidir la pantalla en cinco partes iguales. Pero esto se explicará en otra publicación.
*JS
------------------------------------------------
var progress : float= 0;
var progressBarEmpty : Texture2D;
var progressBarFull:Texture2D;
static var ScreenX:float;
static var ScreenY:float;
static var AnchoxPantalla: int;
static var AltoxPantalla:int;
function OnGUI () {
//barra vacia (posicionx,posiciony, ancho, alto)
GUI.DrawTexture (Rect(ScreenX*0.1,ScreenY*0.1,400,140), progressBarEmpty);
//barra llena
GUI.DrawTexture (Rect(ScreenX*0.55,ScreenY*0.65,progress,20), progressBarFull);
}
function Update (){
AnchoxPantalla=Screen.width;
AltoxPantalla=Screen.height;
ScreenX = (Screen.width)/5;
ScreenY=(Screen.height)/5;
progress = PlayerStat.vida; //llamo a la variable vida que se encuentra en el script PlayerStat
}
------------------------------------------------
La función OnGUI dibujará en la pantalla la barra de vida y el fondo. Como se ha comentado el GUIDrawTexture mostrará la textura almacenada en progressBarEmpty, y en otra línea se mostrará progressBarFull, la barra que se irá debilitando apenas el player reciba daño.
La variable progress almacenará el valor total de las vidas, osea que al principio esta tiene 250 vidas, pero por cada daño esta va a bajar 50pts. Si revisamos el GUIDraw de la progressBarFull, nos damos cuenta que en el ancho no tenemos un valor fijo, sino que el ancho va a estar guiado por los puntos de la vida.
Hasta este momento solo hemos mostrado las barras de vida pero no poseen interacción con el player. Para lo cual crearemos el segundo script llamado "PlayerStat" en este script creamos la variable vida que almacenará el total de la vida del player. Aquí realizamos el cálculo del daño, donde la funcion Update valida al momento que vida sea 0 se active la funcion dead (cambio de nivel), y para resetear la variable vida luego le asignamos los 250pts. Este Script se lo ponen al player.
*JS
------------------------------------------------
static var vida = 250;
function Update (){
if(vida <= 0){
Dead();
}
}
function Dead(){
Application.LoadLevel("enemigo 2");
vida = 250;
}
------------------------------------------------
El último script a realizar lo llamaremos "baja_vidas" Este script lo tiene el enemigo, y en este le indicamos cuanto es el daño que va a ocasionar. En mi caso he simplificado el ejemplo usando el OnTriggerEnter a un cubo.
En este script lo único que se realiza es cuando entra a la zona sensible la variable vida es restada por 50pts.
*JS
------------------------------------------------
function OnTriggerEnter () {
PlayerStat.vida = PlayerStat.vida -50;
}
------------------------------------------------
Los scripts están muy bien y funcionan de maravilla...excepto por los valores de la función ONGUI. He tenido que ir los acomodando para que queden uno encima de otro...(los DrawTexture)pues con los de la script aparece un recuadro en la esquina izquierda demasiado grande y la BarFull aparece muy por delante y más pequeña. Resetee ambos valores de las DrawTexture al mismo y así he logrado q estén uno encima de otro...
ResponderEliminarhola rolando saludos!! y como hiciste para alinear los Drawtexture porque yo tengo el mismo problemilla ya hize varios cambios pero aun no me sale--Gracias si me respondes y si no tambien Gracias..
EliminarHola,tengo el mismo problema,puedes explicar como lo solucionaste?
EliminarListo muchas gracias por la observación. Rolando
ResponderEliminarno me ha servido pero esta muy chulo (lo he probado) gracias chabal
ResponderEliminarcomo así no te ha servido, quizas te pueda ayudar
Eliminardonde puedo conseguir scripts para hacer diferentes cosas?
ResponderEliminarAquí en mi blog tengo algunos script pero de ahí es de buscar e ir probando, no conozco de un solo sitio donde se encuentren muchos scripts.
Eliminarhola alonso! gracias por los tutoriales y scripts.. se aprende y se agradece- solo una preguntita? y como le hago para que la barra se llene otra vez? porque tengo un script que me sube la vida otra vez, pero logicamente pues nada que ver con la barra de vida, o sea la barra de vida se acaba y yo sigo vivo haha! me cambia de nivel solamente que no toque los botiquines de salud..bueno saludos y gracias por compartir tus conocimientos saludos!!
ResponderEliminarEstimado Gerardo, bueno en este sería de forma inversa, cuando toques los botiquines de salud. si usas triggerEnter en ves de restar, sumas. Y esto enviará el valor a la misma variable que usa el GUI para mostrar la barra.
Eliminarfunction OnTriggerEnter () {
PlayerStat.vida = PlayerStat.vida +50;
}
Me comentas si te sirvió la ayuda... Disculpa por contestar ahora, es solo que me encontraba fuera del país y donde andaba no tenía internet...
Hola Alonso! Gracias por contestar, si en realidad asi lo hize. lo que pasaba es que el script de vida que yo use para subir de vida,era de otro tutorial.y tenia varias funciones.entonces pues logicamente si me subia la vida, pero no en la barra de (mostrar vidas) ya que en el script pues no existia ningun (PlayerStat) function: y lo que hize pues fue eso Agregar al script ::
ResponderEliminarfunction OnTriggerEnter () {
PlayerStat.vida = PlayerStat.vida +50;
}
solo le cambie el - por el + y quedo perfecto:
y es que en ese script si me mostraba las vidas y la cantidad de balas en pantalla, pero con numeros,pero no tenia barra de vida, y bueno yo queria que tubiera una Barra de vida, y ya la tiene!
Gracias de nuevo por tu material y por tu tiempo Alonso! Saludos!! cuidate,,
hola Alonso he colocado los scripts y ya fije la barra de vida excelente pero cuando el enemigo se acerca en mi caso es un zombie, no me resta la vida.
ResponderEliminarel enemigo tiene esta script con la que me sigue y me ataca
le coloque la script que colocaste pero no me resta vida no se que hacer.
esta script del enemigo trae una opcion con la que ya me resta la vida pero dicha script no posee una barra de vida y tampoco encuentro la forma de colocarle una... podrias ayudarme?
public var thePlayer : Transform;
ResponderEliminarprivate var theEnemy : Transform;
public var speed : float = 2.0;
var isOffScreen : boolean = false;
public var offscreenDotRange : float = 0.7;
var isVisible : boolean = false;
public var visibleDotRange : float = 0.8; // ** between 0.75 and 0.85 (originally 0.8172719)
var isInRange : boolean = false;
public var followDistance : float = 24.0;
public var maxVisibleDistance : float = 25.0;
public var reduceDistAmt : float = 3.1;
private var sqrDist : float = 0.0;
public var health : float = 300.0;
public var damage : float = 15.0;
public var enemySightedSFX : AudioClip;
private var hasPlayedSeenSound : boolean = false;
private var colDist : float = 5.0; // raycast distance in front of enemy when checking for obstacles
function Start()
{
if ( thePlayer == null )
{
thePlayer = GameObject.Find( "Player" ).transform;
}
theEnemy = transform;
}
function Update()
{
// Movement : check if out-of-view, then move
CheckIfOffScreen();
// if is Off Screen, move
if ( isOffScreen )
{
MoveEnemy();
// restore health
RestoreHealth();
}
else
{
// check if Player is seen
CheckIfVisible();
if ( isVisible )
{
// deduct health
DeductHealth();
// stop moving
StopEnemy();
// play sound only when the Man is first sighted
if ( !hasPlayedSeenSound )
{
GetComponent.().PlayClipAtPoint( enemySightedSFX, thePlayer.position );
}
hasPlayedSeenSound = true; // sound has now played
}
else
{
// check max range
CheckMaxVisibleRange();
// if far away then move, else stop
if ( !isInRange )
{
MoveEnemy();
}
else
{
StopEnemy();
}
// reset hasPlayedSeenSound for next time isVisible first occurs
hasPlayedSeenSound = false;
}
}
}
function DeductHealth()
{
// deduct health
health -= damage * Time.deltaTime;
// check if no health left
if ( health <= 0.0 )
{
health = 0.0;
Debug.Log( "YOU ARE OUT OF HEALTH !" );
// Restart game here!
Application.LoadLevel( "perdedor" );
}
}
function RestoreHealth()
{
// deduct health
health += damage * Time.deltaTime;
// check if no health left
if ( health >= 300.0 )
{
health = 300.0;
//Debug.Log( "HEALTH is FULL" );
}
}
function CheckIfOffScreen()
{
var fwd : Vector3 = thePlayer.forward.normalized;
var other : Vector3 = (theEnemy.position - thePlayer.position).normalized;
var theProduct : float = Vector3.Dot( fwd, other );
if ( theProduct < offscreenDotRange )
{
isOffScreen = true;
}
else
{
isOffScreen = false;
}
}
function MoveEnemy()
{
// Check the Follow Distance
CheckDistance();
// if not too close, move
if ( !isInRange )
{
GetComponent.().velocity = Vector3( 0, GetComponent.().velocity.y, 0 ); // maintain gravity
// --
// Old Movement
//transform.LookAt( thePlayer );
//transform.position += transform.forward * speed * Time.deltaTime;
// --
// New Movement - with obstacle avoidance
var dir : Vector3 = ( thePlayer.position - theEnemy.position ).normalized;
var hit : RaycastHit;
if ( Physics.Raycast( theEnemy.position, theEnemy.forward, hit, colDist ) )
{
//Debug.Log( " obstacle ray hit " + hit.collider.gameObject.name );
if ( hit.collider.gameObject.name != "Player" && hit.collider.gameObject.name != "Terrain" )
{
dir += hit.normal * 20;
}
}
var rot : Quaternion = Quaternion.LookRotation( dir );
theEnemy.rotation = Quaternion.Slerp( theEnemy.rotation, rot, Time.deltaTime );
theEnemy.position += theEnemy.forward * speed * Time.deltaTime;
//theEnemy.rigidbody.velocity = theEnemy.forward * speed; // Not Working
// --
}
else
{
StopEnemy();
}
}
function StopEnemy()
{
transform.LookAt( thePlayer );
GetComponent.().velocity = Vector3.zero;
}
function CheckIfVisible()
{
var fwd : Vector3 = thePlayer.forward.normalized;
var other : Vector3 = ( theEnemy.position - thePlayer.position ).normalized;
var theProduct : float = Vector3.Dot( fwd, other );
if ( theProduct > visibleDotRange )
{
// Check the Max Distance
CheckMaxVisibleRange();
if ( isInRange )
{
// Linecast to check for occlusion
var hit : RaycastHit;
if ( Physics.Linecast( theEnemy.position + (Vector3.up * 1.75) + theEnemy.forward, thePlayer.position, hit ) )
{
Debug.Log( "Enemy sees " + hit.collider.gameObject.name );
if ( hit.collider.gameObject.name == "Player" )
{
isVisible = true;
}
}
}
else
{
isVisible = false;
}
}
else
{
isVisible = false;
}
}
function CheckDistance()
{
var sqrDist : float = (theEnemy.position - thePlayer.position).sqrMagnitude;
var sqrFollowDist : float = followDistance * followDistance;
if ( sqrDist < sqrFollowDist )
{
isInRange = true;
}
else
{
isInRange = false;
}
}
function ReduceDistance()
{
followDistance -= reduceDistAmt;
}
function CheckMaxVisibleRange()
{
var sqrDist : float = (theEnemy.position - thePlayer.position).sqrMagnitude;
var sqrMaxDist : float = maxVisibleDistance * maxVisibleDistance;
if ( sqrDist < sqrMaxDist )
{
isInRange = true;
}
else
{
isInRange = false;
}
}
Perdona lo largo esas dos partes son el script que te nombre arriba con el que el enemigo me persigue y ataca...
EliminarLuego de confundirme un buen tiempo con tus script!!! no es la mejor forma de leer el codigo.. me puedo dar cuenta que quizas entre esos dos script no estás llamando a las mismas variables. favor indica cual script pertenece a que gameobject enemigo o player.
Eliminaramigos este lenguaje esta padre y lo puedo utilizar en html y en video juego esta padre
ResponderEliminarthx
ResponderEliminarY si solo quiero que me reste vida de un texto canvas que quiero agregar al jugador "player", como puedo hacer?
ResponderEliminar