Unity3d progress bar - c#

I am developing a game using unity3D and I need help making a progress time bar such that on collecting particular items time is added and thus the game continues.

Create a UI Image that is of type Filled. Use horizontal or vertical fill depending on your progress bar. Then from inside a script you can manipulate the value of the image. I will give you a very simple c# example. For the rest you can just use google and read the unity scripting API.
public class Example: MonoBehaviour {
public Image progress;
// Update is called once per frame
void Update ()
{
progress.fillAmount -= Time.deltaTime;
}
}

U could use a slider en slider.setvalue.
Example:
//to use this add first a slider to your canvas in the editor.
public GameObject sliderObject; //attachs this to the slider gameobject in the editor or use Gameobject.Find
Slider slider = sliderObject.GetComponent<Slider>();
float time;
float maxtime; //insert your maxium time
void start(){
slider.maxValue = maxtime;
}
void update()
{
time += Time.deltaTime;
if (time < maxtime)
{
slider.value = time;
}
else
{
Destroy(sliderObject);
//time is over, add here what you want to happen next
}
}

Related

How to make a non-UI countdown in Unity?

I'm trying to make a countdown attached to a sprite. The countdown will count down from 10 to zero, and won't be attached to the Canvas, so it won't be static on the screen. All of the tutorials for something like this have been for UI and don't allow 3D text. Anyone have any ideas on how to do this?
There are two ways to do this:
Use UI elements on a separate canvas set to World Space
Use the TextMesh element to put a 3D mesh of text in the world
I don't really know the pros and cons of each approach so go with whichever is easier for you to implement and keep the other in mind if you run into problems.
If you're looking for a detailed tutorial, anything explaining how to do popup damage numbers will be the same method, just with a different script telling it what text to display. There are a few good tutorials on the top of the YouTube results.
As for the countdown script, it's fairly simple.
//put this script on a GameObject prefab with a TextMesh component, or a canvas element
public class Countdown : MonoBehaviour
{
public TextMesh textComponent; //set this in inspector
public float time; //This can be set in inspector for this prefab
float timeLeft;
public void OnEnable()
{
textComponent = GetComponent<TextMesh>(); //in case you forget to set the inspector
timeLeft = time;
}
private void Update()
{
timeLeft -= Time.deltaTime; //subtract how much time passed last frame
textComponent.text = Mathf.CeilToInt(timeLeft).ToString(); //only show full seconds
if(timeLeft < 0) { gameObject.SetActive(false); } //disable this entire gameobject
}
}

Unity - C# - Power up a shot before firing

I'm trying to launch a projectile which is simple enough using the UI Button's onClick property but what I also want to allow the player to do is charge up their shot. I have it working on the keyboard by using Input.GetButton("Fire") then I add Fire to the input manager and for the key I choose space. But what I'm trying to do now is add the same functionality to a virtual button for touch screen players. The problem is onClick can't check if the button is continuously pressed it can only be called once. So for that I'm trying to use the IPointer Up and Down Handlers in the button's script like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class FireButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
public bool buttonPressed;
public void OnPointerDown(PointerEventData eventData)
{
buttonPressed = true;
}
public void OnPointerUp(PointerEventData eventData)
{
buttonPressed = false;
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
The problem is there seems to be an infinite loop in my logic for the tank script. As soon as the Update() function is called and the if statement below for fire button.buttonPressed is true for some reason it loops there and doesn't continue. Here's the following code (I commented out the logic for the keyboard input):
using UnityEngine;
using UnityEngine.UI;
public class TankShooting : MonoBehaviour
{
public int m_PlayerNumber = 1; // Used to identify the different players.
public Rigidbody m_Shell; // Prefab of the shell.
public Transform m_FireTransform; // A child of the tank where the shells are spawned.
public Slider m_AimSlider; // A child of the tank that displays the current launch force.
public AudioSource m_ShootingAudio; // Reference to the audio source used to play the shooting audio. NB: different to the movement audio source.
public AudioClip m_ChargingClip; // Audio that plays when each shot is charging up.
public AudioClip m_FireClip; // Audio that plays when each shot is fired.
public float m_MinLaunchForce = 15f; // The force given to the shell if the fire button is not held.
public float m_MaxLaunchForce = 30f; // The force given to the shell if the fire button is held for the max charge time.
public float m_MaxChargeTime = 0.75f; // How long the shell can charge for before it is fired at max force.
FireButton firebutton;
private string m_FireButton; // The input axis that is used for launching shells.
private float m_CurrentLaunchForce; // The force that will be given to the shell when the fire button is released.
private float m_ChargeSpeed; // How fast the launch force increases, based on the max charge time.
private bool m_Fired; // Whether or not the shell has been launched with this button press.
private void OnEnable()
{
// When the tank is turned on, reset the launch force and the UI
m_CurrentLaunchForce = m_MinLaunchForce;
m_AimSlider.value = m_MinLaunchForce;
}
public void Start()
{
firebutton = FindObjectOfType<FireButton>();
// The fire axis is based on the player number.
m_FireButton = "Fire" + m_PlayerNumber;
// The rate that the launch force charges up is the range of possible forces by the max charge time.
m_ChargeSpeed = (m_MaxLaunchForce - m_MinLaunchForce) / m_MaxChargeTime;
}
public void Update()
{
// The slider should have a default value of the minimum launch force.
m_AimSlider.value = m_MinLaunchForce;
// If the max force has been exceeded and the shell hasn't yet been launched...
if(m_CurrentLaunchForce >= m_MaxLaunchForce && !m_Fired)
{
// ... use the max force and launch the shell.
m_CurrentLaunchForce = m_MaxLaunchForce;
Fire();
}
// Otherwise, if the fire button has just started being pressed...
//else if(Input.GetButtonDown(m_FireButton))
**//there is an infinite loop here needs fixing**
else if (firebutton.buttonPressed)
{
Debug.Log("Test1 " + firebutton.buttonPressed);
// ... reset the fired flag and reset the launch force.
m_Fired = false;
m_CurrentLaunchForce = m_MinLaunchForce;
// Change the clip to the charging clip and start it playing.
m_ShootingAudio.clip = m_ChargingClip;
m_ShootingAudio.Play();
}
// Otherwise, if the fire button is being held and the shell hasn't been launched yet...
//else if(Input.GetButton(m_FireButton) && !m_Fired)
else if (firebutton.buttonPressed && !m_Fired)
{
Debug.Log("Test2 " + firebutton.buttonPressed);
// Increment the launch force and update the slider.
m_CurrentLaunchForce += m_ChargeSpeed * Time.deltaTime;
m_AimSlider.value = m_CurrentLaunchForce;
}
// Otherwise, if the fire button is released and the shell hasn't been launched yet...
//else if(Input.GetButtonUp(m_FireButton) && !m_Fired)
else if (firebutton.buttonPressed && !m_Fired)
{
Debug.Log("Test3 " + firebutton.buttonPressed);
// ... launch the shell.
Fire();
}
}
public void Fire()
{
// Set the fired flag so Fire is only called once.
m_Fired = true;
// Create an instance of the shell and store a reference to it's rigidbody.
Rigidbody shellInstance =
Instantiate(m_Shell, m_FireTransform.position, m_FireTransform.rotation) as Rigidbody;
// Set the shell's velocity to the launch force in the fire position's forward direction.
shellInstance.velocity = m_CurrentLaunchForce * m_FireTransform.forward; ;
// Change the clip to the firing clip and play it.
m_ShootingAudio.clip = m_FireClip;
m_ShootingAudio.Play();
// Reset the launch force. This is a precaution in case of missing button events.
m_CurrentLaunchForce = m_MinLaunchForce;
}
}
Also if you think there's an easier way to do this by using the input manager or some other way please feel free to share. Happy to change all this logic and try something else, been working on it for 13 hours now. Thanks in advance!
I got it working! Dropped the whole UIButton approach and went with Input.touches
I couldn't see a fire rate logic which stops infinite shots. You can define a fire rate so it do not fire infinite logic might be
float fireRate = 0.25f;
float lastFireTime; // Must be global
if(Time.time - lastFireTime> fireRate)
{
Fire();
lastFireTime = Time.time;
}
End you may use Object Pool pattern instead of Instantiate for performance issues.
Rigidbody shellInstance =
Instantiate(m_Shell, m_FireTransform.position, m_FireTransform.rotation) as Rigidbody;

How can we do fade in fade out of unity3 in prefeb(prefeb contain two primitive types shape) using script

fade in fade out of unity3 in prefeb.I am using prefeb which consist two primitive game object cube and capsule, and I want to prefeb will be fade in fade out with time duration using C# script of unity3d.
First create a new material, apply that to the prefabs you would want to fade in out out.
Then throw a script on your prefab that looks something like this.
public class FadeScript : MonoBehaviour
{
public Material fadeMaterial;
public float fadeTime = 2f;
private float fadeTimer = 0f;
// Start is called before the first frame update
void Start()
{
fadeTimer = 0f;
}
// Update is called once per frame
void Update()
{
if (fadeTimer < fadeTime) fadeTimer += Time.deltaTime;
fadeMaterial.color = new Color(
fadeMaterial.color.r,
fadeMaterial.color.g,
fadeMaterial.color.b,
fadeTimer / fadeTime);
}
}
You can add a flag on it to start the fade, and mimic this code to accomplish the fade out. Make sure to attach your material onto the script.

No dynamic float visible for attachment in unity

I am trying attach a particle system's gravity modifier with a slider but it is not visible. Here is a screen shot of what I see.
Should I give this up and try to attach the value using a script instead ? ? ?
You cannot see it from the Editor because main.gravityModifier is a type of MinMaxCurve not float so you cannot assign the Slider value which is float to it from the Editor. There is a function that let's you do that from scripting. That's why it works from script.
Do that from code. It looks like you already got an answer but there are so many things to improve.
1.Don't use GameObject.Find every frame.
You are currently doing this 2 times in a frame with GameObject.Find("Slider") and GameObject.Find("Particle System"). Cache the Slider and the ParticleSystem components. Move those functions to the Start or Awake function.
2.Do not use the Slider value to modify main.gravityModifier every
frame.
Use the onValueChanged event to subscribe to the Slider so that you will only modify main.gravityModifier when the slider value changes. The Update function is no longer needed when you do this.
private ParticleSystem ps;
public Slider slider;
// Use this for initialization
void Start()
{
//Cache the Slider and the ParticleSystem variables
slider = GameObject.Find("Slider").GetComponent<Slider>();
ps = GameObject.Find("Particle System").GetComponent<ParticleSystem>();
}
void OnEnable()
{
//Subscribe to the Slider Click event
slider.onValueChanged.AddListener(delegate { sliderCallBack(slider.value); });
}
//Will be called when Slider changes
void sliderCallBack(float value)
{
Debug.Log("Slider Changed: " + value);
var main = ps.main;
main.gravityModifier = value;
}
void OnDisable()
{
//Un-Subscribe To Slider Event
slider.onValueChanged.RemoveAllListeners();
}
I got the scripting answer, but if any of you has a better solution you are welcome to share it.
using UnityEngine;
using UnityEngine.UI;
public class SliderScript : MonoBehaviour {
private double sf;
private ParticleSystem ps;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
sf = GameObject.Find("Slider").GetComponent<Slider>().value;
ps = GameObject.Find("Particle System").GetComponent<ParticleSystem>();
var main = ps.main;
main.gravityModifier = (float)sf;
print(sf );
}
}

Unity Slider decrease as timer

I'm trying to make a countdown timer but using a Unity Slider instead of text but I've ran across a few issues. So my current code is:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class CountdownTimer : MonoBehaviour {
//public Text timeText;
public float startingTime = 100.0f;
public Slider Timer;
// Use this for initialization
void Start () {
Timer = GetComponent<Slider> ();
}
// Update is called once per frame
void Update () {
startingTime -= Time.deltaTime;
Timer.value = startingTime;
if (startingTime <= 0)
{
startingTime = 0;
Application.LoadLevel ("GameOver");
}
}
}
This code works if I were to replace the slider with the text but not vice versa. My second issue is when I attach this code to my player and link the slider from the hierarchy, it disappears when I start the game.
Last issue is when I try to add an On Value Changed, I can link it to my player to get the functions from the code but from doing my research there isn't really anything I can link it to since I only have start and update. Scrollbars can use private voids and receive the dynamic float that way but I haven't been able to yet with Sliders
Example:
On Change Value
It does not work on the slider you say, you need to pass the max value as 100 on the slider component, or it uses 1 until the value gets between 0 and 1.
A UI item has to be under a Canvas to be rendered, so attaching it to your player makes it discarded from rendering. You can put the Canvas with the slider as child under the player object. But I would keep the canvas separated for clarity(POV).
The picture you added shows that you passed an object, but now you need to assign a method. Click the No Function and it will display all the available methods.

Categories