x


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;    
        }
     }
  }
more ▼

asked Aug 26 '11 at 03:38 AM

track01 gravatar image

track01
31 5 5 6

(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

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;  }  } } 
more ▼

answered Aug 26 '11 at 04:49 AM

aldonaletto gravatar image

aldonaletto
42.5k 16 43 202

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

Aug 26 '11 at 05:16 AM track01

I can see the alpha bar moving on on the health bar prefab its just not doing anything to it.

Aug 26 '11 at 05:24 AM track01

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.

Aug 26 '11 at 11:53 AM aldonaletto

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 MouseOverEnemy detection. Take a look at the edited answer.

Aug 26 '11 at 02:46 PM aldonaletto

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.

Aug 26 '11 at 04:29 PM track01
(comments are locked)
10|3000 characters needed characters left

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.

more ▼

answered Aug 26 '11 at 05:40 AM

SilverTabby gravatar image

SilverTabby
1.9k 3 6 18

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x3812
x3127
x2277
x37
x4

asked: Aug 26 '11 at 03:38 AM

Seen: 1763 times

Last Updated: Aug 26 '11 at 10:21 PM