- Home /
Camera.main.WorldToViewportPoint & GuiTexture
Hey, I'm using a gui texture for a health bar and having it hover above an enemy when I mouse over it. I'm trying to get it to disappear when the mouse comes away but it it seems to glitch out and stick to the screen.
I've literally being trying to solve this for the past 3-4 hours and I can't figure it out for the life of me. I'm using two JS. Both are attached to the enemy called EnemyHealth1 and the other is EnemyMouseOver.
Could anyone tell me a better way of doing this or something similar? All I want is for the healthbar to show up when I mouse over then fade o.0
Here is my EnemyHealth1 Script
var hp:float;
var maxHp:float;
var healthBarWidth:int;
var myHealthBar:GameObject;
var myHb:GameObject;
var posX:float;
var posY:float;
function Start () {
healthBarWidth = 20;
myHb = Instantiate(myHealthBar, transform.position, transform.rotation);
}
function Update () {
myHb.transform.position = Camera.main.WorldToViewportPoint(transform.position);
myHb.transform.position.x -= posX;
myHb.transform.position.y -= posY;
myHb.transform.localScale = Vector3.zero;
var healthPercent:float = hp / maxHp;
if(healthPercent < 0){
healthPercent = 0;
}
if(healthPercent > 100){
healthPercent = 100;
}
healthBarWidth = healthPercent * 20;
myHb.guiTexture.pixelInset = Rect (10, 10, healthBarWidth, 5);
}
This is the EnemyMouseOver
var healthEnabled = false;
function Update () {
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if(Physics.Raycast(ray, hit, 10))
{
if(hit.collider.gameObject.tag == "Enemy")
{
if (healthEnabled == false)
{
gameObject.GetComponent(EnemyHealth1).enabled = true;
healthEnabled = true;
}
}
}
else
{
gameObject.GetComponent(EnemyHealth1).healthBarWidth = 0;
if (healthEnabled == true){
gameObject.GetComponent(EnemyHealth1).healthBarWidth = 0;
gameObject.GetComponent(EnemyHealth1).enabled = false;
healthEnabled = false;
}
}
}
Answer by aldonaletto · Aug 26, 2011 at 04:49 AM
You could simplify the mouse over script, and just control the healt bar visibility using
guiText.material.color.a:
EDITED: Now that I'm completely awake, these scripts are correct and working. The idea is to make the health bar disappear by reducing its alpha to 0. When the mouse pointer is over any enemy, it recharges the health bar alpha (variable show) to 1 each frame, so the bar appears solid over the enemy. When the mouse isn't over the enemy anymore, the show variable is decremented to zero in duration seconds, making the bar vanish nicely.
This is the EnemyHealth1.js script:
var hp:float = 100; // health value, 0..maxHp var maxHp:float = 100; var healthBarWidth:int = 20; var myHealthBar:GameObject; private var myHb:GameObject; var posX:float; var posY:float; var show: float = 0; // health bar appears when show > 0 var duration: float = 0.6; // health bar vanishes for duration seconds
function Start () { myHb = Instantiate(myHealthBar, transform.position, transform.rotation); }
function Update () { if (show>=0){ myHb.guiTexture.color.a = show; // variable show controls the bar alpha show -= Time.deltaTime/duration; // fades out health bar unless show is recharged myHb.transform.position = Camera.main.WorldToViewportPoint(transform.position); myHb.transform.position.x -= posX; myHb.transform.position.y -= posY; myHb.transform.localScale = Vector3.zero; // <- this does nothing var healthPercent:float = Mathf.Clamp(hp / maxHp, 0, 1); myHb.guiTexture.pixelInset = Rect (10, 10, healthBarWidth * healthPercent, 5); } } This is the mouse over script:
function Update () { var ray = Camera.main.ScreenPointToRay (Input.mousePosition); var hit : RaycastHit; if(Physics.Raycast(ray, hit, 10)) { if(hit.collider.tag == "Enemy") { // while mouse over enemy recharges variable show hit.collider.GetComponent(EnemyHealth1).show = 1; } } }
Thanks for the reply :) I't doesn't seem to be working it's doing the same as before apart from not getting stuck to the camera straight away.
Also were you supposed to put guiText.material.color.a = show; // fades out health bar unless show is recharged
Its a guiTexture. I had to change it to myHealthBar.guiTexture.color.a = show; to get it to compile
I can see the alpha bar moving on on the health bar prefab its just not doing anything to it.
I was almost sleeping over the keyboard when I answered this question, so I didn't see that the first script isn't attached to a GUIText. Now that I'm awake, I see that it's attached to the enemy, and you're using a GUITexture... dear God! I'll revise the whole thing and edit my answer asap.
After some coffe cups, I got alert enough to see how many stupid things I did in these scripts. Now they are fixed and working fine. I tried to keep most of your logic - just modified the way the health bar was hidden and simplified the $$anonymous$$ouseOverEnemy detection. Take a look at the edited answer.
I'm not sure if I am doing this wrong but it's still not working :( The alpha is moving correctly its just not showing up on my screen.
Answer by SilverTabby · Aug 26, 2011 at 05:40 AM
I'm seeing that the main difference between what you are doing and what I would do is that you are using a physical GUITexture when I would just use GUI.Box to create it by hand.
I would
Use two scripts like you do, but have the enemy script be nothing but a hold it's health.
In the first script, Raycast test to find and acquire the current health of the enemy. Just like you do in your 2nd script right now.
Position your health bar AT THE CURSOR (or slightly offset to make it look nice)
Then create a GUI.Box or GUI.DrawTexture or what ever makes your health look nice.
Creating a GUI by hand has been, in my experience, easier and more reliable. I don't trust code I can't see, so I prefer this. It seems to work for me.
Also, you are calling GetComponent Waaaaaaaaaaaaaaaaaaaaay too often. It's an expensive operation, and the output of it doesn't change unless you do something crazy, so just call it once and store it in a var.
This seems to work for me, but it might not for you. I find that by reducing the number of things you have to worry about (example: WorldToScreenPoint) it will make things a lot easier for you in the long run.