Power bar on Button Press c#

Powerbar on Button Press c#

void OnGUI() {
 
       GUI.backgroundColor = new Color(0,0,0,0);
       if (GUI.Button( new Rect(Screen.width - 175,Screen.height - 175,150,150), Firebtn)){
         GameObject go = GameObject.Find("FirePoint");
         SHOOT other = (SHOOT) go.GetComponent(typeof(SHOOT));
         other.Fire();
       }

I have also found this powerbar

using UnityEngine;
using System.Collections;
 
public class Progress : MonoBehaviour {
    public float barDisplay; //current progress
    public Vector2 pos = new Vector2(20,40);
    public Vector2 size = new Vector2(60,20);
    public Texture2D emptyTex;
    public Texture2D fullTex;
 
    void OnGUI() {
       //draw the background:
       GUI.BeginGroup(new Rect(pos.x, pos.y, size.x, size.y));
         GUI.Box(new Rect(0,0, size.x, size.y), emptyTex);
 
         //draw the filled-in part:
         GUI.BeginGroup(new Rect(0,0, size.x * barDisplay, size.y));
          GUI.Box(new Rect(0,0, size.x, size.y), fullTex);
         GUI.EndGroup();
       GUI.EndGroup();
    }
 
    void Update() {
       //for this example, the bar display is linked to the current time,
       //however you would set this value based on your desired display
       //eg, the loading progress, the player's health, or whatever.
       barDisplay = Time.time*0.05f;
//   barDisplay = MyControlScript.staticHealth;
    }
}

Also my SHOOT.cs script has a variable:

public int coconutSpeed= 50; //force of coconuts being shot

This is what I would like to change with the power bar

Any help would be appreciated Thanks

I would control the speed value from the shoot script, and not from the progress bar.

Have a variable in your shoot script which is consumed with each shot, and slowly regenerates.

public int maximumForce = 50; // your speed value
private float relativeForce = 1f;
private float regenerationSpeed = 0.1f;

// MAKE A SHOOT METHOD IN THE SHOOT SCRIPT, AND CALL IT FROM THE BUTTON //
// When you shoot, multiply the current force with the maximum force to get something between 0 and 50, depending on the regeneration
relativeForce * maximumForce;
// And consume the value
relativeForce = 0f;

// Regenerate the value in an update call
relativeForce += Time.deltaTime * regenerationSpeed;
relativeForce = Mathf.Clamp01(relativeForce);

// And send the value to your progressBar component, which will need a method to update the status
progressBar.SetProgress(relativeForce);

And you should not use “GameObject.Find” in your Button script.

// this is bad as it has to find the gameobject and grab its component every time you fire
GameObject go = GameObject.Find("FirePoint");
SHOOT other = (SHOOT) go.GetComponent(typeof(SHOOT));
other.Fire();


// better to cache the it, if you are always looking for the same component
private SHOOT shoot;

// only called once
void Awake()
{
    shoot = GameObject.Find("FirePoint").GetComponent<Shoot>();
}

If you have further problems with that, post the Shoot script.

Thanks for the help, and the advice on finding the gameObject. I am still unsure how to add method to update progress bar. I guess I need a var in progress script like “private float relativeForce” then on update barDisplay = relaticeForce.time; is that right?
Also here is my shoot script

using UnityEngine;
using System.Collections;

public class SHOOT : MonoBehaviour {
	
public AudioClip sound; //canon fire soundClip

public int coconutSpeed= 50; //force of coconuts being shot
 
public Rigidbody projectile; //coconut prefab goes here

public static int coconuts= 3; //amount of coconuts per "clip"

public int totalCoconuts= 3; //total amount of coconuts we have available

	
	
public void Fire(){
		if(coconuts > 0) { //if we have at least 1 coconut then we can fire

Rigidbody clone;// Instantiate the projectile at the position and rotation of this transform

clone = Instantiate(projectile, transform.position, transform.rotation) as Rigidbody;
 
clone.velocity = transform.TransformDirection (Vector3.forward * coconutSpeed);// Give the cloned object an initial velocity along the current
				
coconuts -=1; //subtracts one coconut per fire sequence
				
AudioSource.PlayClipAtPoint(sound, transform.position, 1);                     // object's Z axis
 

}


}
		

// if (GUI.Button( new Rect(Screen.width - 300,Screen.height - 300,200,200),btnTexture)){


		
}

Is this how it should look

using UnityEngine;
using System.Collections;

 

public class SHOOT : MonoBehaviour {
public AudioClip sound; //canon fire soundClip
public int coconutSpeed= 50; //force of coconuts being shot
public Rigidbody projectile; //coconut prefab goes here
public static int coconuts= 3; //amount of coconuts per "clip"
public int totalCoconuts= 3; //total amount of coconuts we have available
public int maximumForce = 50; // your speed value
private float relativeForce = 1f;
private float regenerationSpeed = 0.1f;

       

public void Fire(){
        if(coconuts > 0) { //if we have at least 1 coconut then we can fire
Rigidbody clone;// Instantiate the projectile at the position and rotation of this transform
clone = Instantiate(projectile, transform.position, transform.rotation) as Rigidbody;
clone.velocity = transform.TransformDirection (Vector3.forward * coconutSpeed);// Give the cloned object an initial velocity along the current
coconuts -=1; //subtracts one coconut per fire sequence
AudioSource.PlayClipAtPoint(sound, transform.position, 1);                     // object's Z axis
relativeForce * maximumForce;
relativeForce = 0f; // And consume the value
}
}

void Update () {
// Regenerate the value in an update call
relativeForce += Time.deltaTime * regenerationSpeed;
relativeForce = Mathf.Clamp01(relativeForce);
// And send the value to your progressBar component, which will need a method to update the status
progressBar.SetProgress(relativeForce); 

}
}

Once again thank you so much

This should work, but I didn’t test it!

Here’s a version of the GUI script with a function that will update the “progress bar”, based on the current “relativeForce” in the shoot script. I also removed the GUI Groups as you don’t need to put a single GUI element into a group.

/* GUI Script
*/

using UnityEngine;
using System.Collections;

public class Progress : MonoBehaviour
{
	// Tweakables
    public Vector2 pos = new Vector2(20,40);
    public Vector2 size = new Vector2(60,20);
    public Texture2D emptyTex;
    public Texture2D fullTex;

	// Private variables
	private float progress; // barDisplay, renamed
 
	public void SetProgress(float relativeForce)
	{
		progress = relativeForce;
	}
 
    void OnGUI()
	{
		GUI.Box(new Rect(pos.x, pos.y, size.x, size.y), emptyTex);
		GUI.Box(new Rect(pos.x, pos.y, size.x * progress, size.y), fullTex);
	}
}

And the shoot script. Not much changed, just put everything in place. Use (relativeForce * coconutSpeed) if you want the speed to be affected by the whole regeneration process.

/*	Shoot Script
*/

using UnityEngine;
using System.Collections;

public class SHOOT : MonoBehaviour
{
	public AudioClip sound; //canon fire soundClip
	public Rigidbody projectile; //coconut prefab goes here
	public int coconuts= 3; //amount of coconuts per "clip"
	public int coconutSpeed= 50; //force of coconuts being shot
	public int totalCoconuts= 3; //total amount of coconuts we have available
	public float regenerationSpeed = 2f; // regeneration speed, after a shot was fired

	private float relativeForce = 1f;
	private Progress progress;

	public void Fire()
	{
		if ((coconuts > 0)  (relativeForce > 0.1f)) // don't shoot if the force is below a certain threshold, otherwise you'll spawn projectiles with 0 speed
		{
			Rigidbody clone = Instantiate(projectile, transform.position, transform.rotation) as Rigidbody;

			//clone.velocity = transform.TransformDirection (Vector3.forward * relativeForce * coconutSpeed);
			clone.velocity = transform.forward * relativeForce * coconutSpeed; // don't think you need transformDirection

			AudioSource.PlayClipAtPoint(sound, transform.position, 1);

			relativeForce = 0f; // Sets the force to 0, so it needs to regenerate its full power
			coconuts--; // Same as coconuts -= 1;
		}
	}

	void Awake()
	{
		progress = GetComponent<Progress>();	// Assuming the progress component is on the same object as the shoot component. If not, use gameObject.Find("SomeObject").GetComponent<Progress>(); ...
	}
	
	void Update()
	{
		relativeForce += Time.deltaTime * regenerationSpeed; // this slowly increases the relative force each frame
		relativeForce = Mathf.Clamp01(relativeForce); // this clamps the relative force, so it stays between 0 and 1

		progress.SetProgress(relativeForce);  // update the progress bar with the current "relativeForce" value
	}
}

I tried that and I get error
Assets/Scripts/GameManager.cs(28,55): error CS0246: The type or namespace name `Shoot’ could not be found. Are you missing a using directive or an assembly reference?

here is the game manager script

using UnityEngine;
using System.Collections;

using MadLevelManager;

public class GameManager : MonoBehaviour {
	public GUIStyle customGuiStyle;  // custome guistyle for text you when or lose
	public string MenuLevelName;    // Which Menu Level to Load
	public int TotalPoints; // Custom var for total points need to beat level
	public Texture2D ballThreeToDisplay; // Shows 3 balls when no shots have been made
	public Texture2D ballTwoToDisplay;   // Shows 2 balls when no shots have been made
	public Texture2D ballOneToDisplay;   // Shows 2 balls when no shots have been made
	public Texture2D StarThreeToDisplay; // Shows 3 stars when points have been earned in 1 shot
	public Texture2D StarTwoToDisplay;   // Shows 2 stars when points have been earned in 2 shot
	public Texture2D StarOneToDisplay;   // Shows 1 stars when points have been earned in 3 shot
	public Texture MenubtnTexture;  // Menu Button
	public Texture NextbtnTexture;  // Next Level Button
	public Texture RetrybtnTexture;  // Retry Button
	public Texture Firebtn;  // Fire Button
	private SHOOT shoot;
	
	public MadText text;
    
    public MadSprite star1, star2, star3;
	
	// only called once
void Awake(){
    shoot = GameObject.Find("FirePoint").GetComponent<Shoot>();
}
	
	// Use this for initialization
	void Start () {
	Score.pointScore = 0;
	shoot.coconuts = 3;
	text.text = MadLevelProfile.recentLevelSelected;
	}
	
	// Update is called once per frame
	void OnGUI() {
		GUI.backgroundColor = new Color(0,0,0,0);
		
		if (GUI.Button( new Rect(Screen.width - 175,Screen.height - 175,150,150), Firebtn)){
				if (Score.pointScore < (TotalPoints)){
		 		GameObject go = GameObject.Find("FirePoint");
				SHOOT other = (SHOOT) go.GetComponent(typeof(SHOOT));
				other.Fire();
		}
		}
		//Display number of balls left to shoot
		if (shoot.coconuts == 3){
			GUI.Label(new Rect(Screen.width - 430, 10, ballThreeToDisplay.width, ballThreeToDisplay.height), ballThreeToDisplay);
		}
		
		if (shoot.coconuts == 2){
			GUI.Label(new Rect(Screen.width - 430, 10, ballTwoToDisplay.width, ballTwoToDisplay.height), ballTwoToDisplay);
		}
		
		if (shoot.coconuts == 1){
			GUI.Label(new Rect(Screen.width - 430, 10, ballOneToDisplay.width, ballOneToDisplay.height), ballOneToDisplay);
		}
		
			
	// Displays You Won 	
	if (Score.pointScore >= (TotalPoints)){
		 GUI.Label(new Rect(Screen.width/2-350,Screen.height/2 - 280, 100, 20), "YOU WON!!!", customGuiStyle);
			
		if (GUI.Button(new Rect(Screen.width/2-220, Screen.height/2 + 20, 150, 150), MenubtnTexture))
			//Application.LoadLevel(Application.loadedLevel + 1);
				Application.LoadLevel(MenuLevelName);
		
		if (GUI.Button(new Rect(Screen.width/2-70, Screen.height/2 + 20, 150, 150), RetrybtnTexture))
			//Application.LoadLevel(Application.loadedLevel + 1);
				Application.LoadLevel (Application.loadedLevel);
			
		if (GUI.Button(new Rect(Screen.width/2+80, Screen.height/2 + 20, 150, 150), NextbtnTexture))
			//Application.LoadLevel(Application.loadedLevel + 1);
				Application.LoadLevel (Application.loadedLevel + 1);
	
	//Displays number of stars earned
		if (shoot.coconuts == 2){
			GUI.Label(new Rect(Screen.width/2 - 280, Screen.height/2-120, StarThreeToDisplay.width, StarThreeToDisplay.height), StarThreeToDisplay);
			MadLevelProfile.SetPropertyEnabled(MadLevelProfile.recentLevelSelected, "star_1", true);
            MadLevelProfile.SetPropertyEnabled(MadLevelProfile.recentLevelSelected, "star_2", true);
            MadLevelProfile.SetPropertyEnabled(MadLevelProfile.recentLevelSelected, "star_3", true);
			MadLevelProfile.SetCompleted(MadLevelProfile.recentLevelSelected, true);
		}
		
		if (shoot.coconuts == 1){
			GUI.Label(new Rect(Screen.width/2 - 280, Screen.height/2-120, StarTwoToDisplay.width, StarTwoToDisplay.height), StarTwoToDisplay);
			MadLevelProfile.SetPropertyEnabled(MadLevelProfile.recentLevelSelected, "star_1", true);
            MadLevelProfile.SetPropertyEnabled(MadLevelProfile.recentLevelSelected, "star_2", true);
			MadLevelProfile.SetCompleted(MadLevelProfile.recentLevelSelected, true);
		}
		
		if (shoot.coconuts == 0){
			GUI.Label(new Rect(Screen.width/2 - 280, Screen.height/2-120, StarOneToDisplay.width, StarOneToDisplay.height), StarOneToDisplay);
			MadLevelProfile.SetPropertyEnabled(MadLevelProfile.recentLevelSelected, "star_1", true);
			MadLevelProfile.SetCompleted(MadLevelProfile.recentLevelSelected, true);
		}
	}
		
	// If you didn't win, display try again and main menu button, retry button
	else if  (shoot.coconuts == 0){
		 GUI.Label(new Rect(Screen.width/2-350,Screen.height/2 - 280, 100, 20), "Try Again!!!", customGuiStyle);
			
		    if (GUI.Button(new Rect(Screen.width/2-220, Screen.height/2 + 20, 150, 150), MenubtnTexture))
			    //load Menu Level
				Application.LoadLevel(MenuLevelName);
		
		    if (GUI.Button(new Rect(Screen.width/2-70, Screen.height/2 + 20, 150, 150), RetrybtnTexture))
				//reload level
				Application.LoadLevel (Application.loadedLevel);
			
}
	}
}

This is the script that has the button that calls the shoot script

Thanks again

I think its line 28, the component name was written in lowercase…needs to be upper case to match the class name.

shoot = GameObject.Find("FirePoint").GetComponent<SHOOT>();

And like I said before, you’re referencing the component to avoid the GameObject.Find call whenever you shoot. So this part: (line 44-46)

GameObject go = GameObject.Find("FirePoint");
SHOOT other = (SHOOT) go.GetComponent(typeof(SHOOT));
other.Fire();

can be changed to

shoot.Fire();

Ok that fixed the errors but I wanted to make it so that when you press a button it charges the progress bar then you release it fires.

so buttonDOWN
Load Progress bar

on buttonUP
shoot.Fire

Ok I have found that if I add a Var “public bool buttonUp;”
Then use this code

 if (GUI.Button( new Rect(Screen.width - 175,Screen.height - 175,150,150), Firebtn)){
				buttonUp = true;
                if (Score.pointScore < (TotalPoints)){
               	shoot.Fire();

The Cannon doesn’t shoot until buttonUp but How do I get it to start progress bar on buttonDown now it only starts on ButtonUp

Thank you so much

The default button only reports single clicks. You’ll either need to work with mouse / touch events and see if the input event hit the button you’re looking for, or use a GUI.RepeatButton. The mouse / touch events would actually be better as they already report Down, Up … events, but you would need to change some parts of your code…

With the repeatButton you’ll need to manually trigger start / end with booleans, which isn’t very pretty.

An untested(!) idea:

private bool isCharging;

void OnGUI()
{
       isCharging = (GUI.RepeatButton(new Rect(10, 450, 190, 50), "Button"));
}

private void Fire()
{
// fire code
relativeForce = 0f;
}

void Update()
{
       if (isCharging) // while the button is pressed, charge up
       {
              relativeForce += Time.detlaTime * regenerationSpeed;
              relativeForce = Mathf.Clamp01(relativeForce)
       } 
       else if (relativeForce > 0.1f) // if the button is not pressed, trigger the fire method (which consumes the charged force
       {
              Fire();
       }
}

I get the following error
Assets/Scripts/GameManager.cs(90,37): error CS0117: UnityEngine.Time' does not contain a definition for detlaTime’

Line 90 reads
relativeForce += Time.detlaTime * regenerationSpeed;

Thanks Again

        public float regenerationSpeed = 4f; // regeneration speed, after a shot was fired
	private float relativeForce = 1f;
	private bool isCharging;

         void OnGUI()

{

       isCharging = (GUI.RepeatButton(new Rect(10, 450, 190, 50), "Button"));

}

 

private void Fire()

{

// fire code

relativeForce = 0f;

}

 

void Update()

{

       if (isCharging) // while the button is pressed, charge up

       {

              relativeForce += UnityEngine.Time.deltaTime * regenerationSpeed;

              relativeForce = Mathf.Clamp01(relativeForce);

       } 

       else if (relativeForce > 0.1f) // if the button is not pressed, trigger the fire method (which consumes the charged force

       {

              Fire();

       }

With this code I get no errors but the cannon does not fire if I change Fire(); to shoot.Fire(); the cannon fires constantly

thanks

But the code works properly. Just put this in a Test.cs class and place it on an empty game object. It does exactly what you want. Charges up, updates the progress bar and only fires once, when released.

To prevent an initial shot, set the relativeForce to 0f when you declare it.

Now its up to you to implement it with the rest of your code. :wink: You can split the elements up and arrange them in different scripts, if you create methods for everything.

using UnityEngine;
using System.Collections;

public class Test : MonoBehaviour
{
	public float regenerationSpeed = 4f; // regeneration speed, after a shot was fired
	private float relativeForce = 0f;
	private bool isCharging;

	void OnGUI()
	{
		isCharging = (GUI.RepeatButton(new Rect(10, 450, 190, 50), "Button"));

		GUI.Label(new Rect(100,80,100,20), isCharging.ToString());
		GUI.Box(new Rect(100,100,100 * relativeForce, 20), ""); // progress bar
	}

	private void Fire()
	{
		Debug.Log("Fire");
		relativeForce = 0f;
	}

	void Update()
	{
		if (isCharging) // while the button is pressed, charge up
		{
			relativeForce += UnityEngine.Time.deltaTime * regenerationSpeed;
			relativeForce = Mathf.Clamp01(relativeForce);
		} 
		else if (relativeForce > 0.1f) // if the button is not pressed, trigger the fire method (which consumes the charged force
		{
			Fire();
		}
	}
}

Ok I got that to work but when I press fire it shoots all 3 balls at one time and also how do you make the progress bar go back down after fully charged? If you can just give me an example I can work it into my script

This is the Test.cs script I am using

using UnityEngine;

using System.Collections;



public class Test : MonoBehaviour

{

    public float regenerationSpeed = 4f; // regeneration speed, after a shot was fired

    private float relativeForce = 0f;

    private bool isCharging;
	
	private SHOOT shoot;
 
	
	void Awake(){

    shoot = GameObject.Find("FirePoint").GetComponent<SHOOT>();

}

    void OnGUI()

    {

        isCharging = (GUI.RepeatButton(new Rect(10, 450, 190, 50), "Button"));

 

        GUI.Label(new Rect(100,80,100,20), isCharging.ToString());

        GUI.Box(new Rect(100,100,100 * relativeForce, 20), ""); // progress bar

    }

 

    private void Fire()

    {

        Debug.Log("Fire");

        relativeForce = 0f;

    }

 

    void Update()

    {

        if (isCharging) // while the button is pressed, charge up

        {

            relativeForce += UnityEngine.Time.deltaTime * regenerationSpeed;

            relativeForce = Mathf.Clamp01(relativeForce);

        } 

        else if (relativeForce > 0.1f) // if the button is not pressed, trigger the fire method (which consumes the charged force

        {

            shoot.Fire();

        }
		
    }

}

Thanks

The relativeForce variable determines how “charged” the weapon is. If you want to make it go back, you have to set it to zero, like I did in the example (in the Fire() method)

        else if (relativeForce > 0.1f) // if the button is not pressed, trigger the fire method (which consumes the charged force
        {
            shoot.Fire();
            relativeForce = 0f; // reset the charge variable, resets the GUI progressBar and shooting - force.
        }

Dunno why its shooting 3 projectiles. Maybe some leftover code in the shoot class. But the “Fire()” method is called only once, so this end should be fine.

ok just adding that one line

relativeForce = 0f;

now it only shoots one projectile. Comment it out and it shoots 3. But it always shoots with the same force regardless of power bar.

Thanks