No dynamic float visible for attachment in unity - c#

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 );
}
}

Related

FMOD parameter not changing through C# script

I'm currently trying to develop my first mini game (a VR musical experience).
I'm trying to have the value of a slider control an FMOD parameter, but nothing happens. Plus the function does not show in the On Value Changed of the slider...
I'm already using that slider to control the transparency of a material and if I try changing the FMOD parameter manually in the inspector it works just fine.
Here is the script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FMODParameters : MonoBehaviour
{
FMODUnity.StudioEventEmitter changeVolume;
FMOD.Studio.EventInstance bass;
public string bassVolumeParameter;
public Slider slider;
void Start()
{
changeVolume = GetComponent<FMODUnity.StudioEventEmitter>();
bass = FMODUnity.RuntimeManager.CreateInstance("event:/Beat/2D/2D Bass");
slider = GetComponent<Slider>();
}
// Update is called once per frame
void Update()
{
SetBassVolume();
}
void SetBassVolume()
{
bass.setParameterByName(bassVolumeParameter, slider.value / 250);
}
}
Thanks in advance for the help! :)
The problem is that you have to add the function in the onValueChanged () listener.
To do it:
Select the gameObject with the Slider component;
Click the "+" button in the OnValueChanged () listener below;
In the empty field, under "Runtime only", drag the gameObject with
this script;
Click the box that now has the name "No Function";
In the component list, place the cursor over the script name, and
under the "Dynamic parameters" category, the SetBassVolume () method.
But first you should tweak the method a bit, like so:
void SetBassVolume(float _value)
{
bass.setParameterByName(bassVolumeParameter, _value / 250);
}
Good work!

How do I add a restart function to a game in Unity?

I have followed and completed a Unity tutorial however once the tutorial is said and done, there was no function mentioned to restart the game.
Other than closing the application and re-opening, how would I go about adding something like this in?
There are do ways to restart game in Unity:
1.Reset every useful variables such as position, rotation, score to their default position. When you use this method, instead of #2, you will reduce how much time it take for your game to load.
Create a UI Button then drag it to the resetButton slot in the Editor.
//Drag button from the Editor to this
public Button resetButton;
Vector3 defaultBallPos;
Quaternion defaultBallRot;
Vector3 defaultBallScale;
int score = 0;
void Start()
{
//Get the starting/default values
defaultBallPos = transform.position;
defaultBallRot = transform.rotation;
defaultBallScale = transform.localScale;
}
void OnEnable()
{
//Register Button Event
resetButton.onClick.AddListener(() => buttonCallBack());
}
private void buttonCallBack()
{
UnityEngine.Debug.Log("Clicked: " + resetButton.name);
resetGameData();
}
void resetGameData()
{
//Reset the position of the ball and set everything to the starting postion
transform.position = defaultBallPos;
transform.rotation = defaultBallRot;
transform.localScale = defaultBallScale;
//Reset other values below
}
void OnDisable()
{
//Un-Register Button Event
resetButton.onClick.RemoveAllListeners();
}
2.Call SceneManager.LoadScene("sceneName"); to load the scene again. You can call this function when Button.onClick.AddListener is called..
Create a UI Button then drag it to the resetButton slot in the Editor.
//Drag button from the Editor to this
public Button resetButton;
void OnEnable()
{
//Register Button Event
resetButton.onClick.AddListener(() => buttonCallBack());
}
private void buttonCallBack()
{
UnityEngine.Debug.Log("Clicked: " + resetButton.name);
//Get current scene name
string scene = SceneManager.GetActiveScene().name;
//Load it
SceneManager.LoadScene(scene, LoadSceneMode.Single);
}
void OnDisable()
{
//Un-Register Button Event
resetButton.onClick.RemoveAllListeners();
}
The decision to which method to use depends on how much Objects in your scene and how much time it takes your scene to load. If the scene has a huge world with baked light maps and HQ textures then go with #1.
For example you can reload main scene for restart game.
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);

Unity SetActive(true) not working after setting it to false at first?

Heirarchy structure
using UnityEngine;
using System.Collections;
public class Ball : MonoBehaviour {
private Rigidbody rigidbody;
public Vector3 LaunchVelocity;
private AudioSource audiosource;
// Use this for initialization
void Start ()
{
GameObject.Find("Touch Panel").SetActive(false);
rigidbody = GetComponent<Rigidbody>();
rigidbody.isKinematic = true;
// disable touch control
audiosource = GetComponent<AudioSource>();
}
// Update is called once per frame
void Update()
{
}
public void LaunchBall(Vector3 passedvelocity)
{
rigidbody.velocity = passedvelocity;
}
public void DropBall() // This is attached to a button
{
rigidbody.isKinematic = false;
GameObject.Find("Touch Panel").SetActive(true);
}
}
As you can see above I have disable "Touch Panel" at start function. But on DropBall function ( remember it is attached to a button), I have set it to active but it is not working.Can anyone help me with this.Thanks.
EDIT:- This script is attached on a "Ball". and ball is attached on a Button.
"Touch Panel" is child of Canvas.
Your problem is that when you disable your Touch Panel , GameObject.Find will not find it so you won't be able to enable it again.
From the documentation:
This function only returns active GameObjects.
You need to setup your Touch Panel as a public GameObject myPanel and assign it in the inspector then you can enable and disable it.
myPanel.SetActive(false);
myPanel.SetActive(true);

Unity slider controlling animation

I'd like to create a slider that displays the current frame of an animation within unity, and when you move the slider it updates the current frame within the animation.
So far I have (edited code)
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class NewAnimController : MonoBehaviour {
public Slider sliderScrubber;
public Animator animator;
void Start()
{
float t = animator
.GetCurrentAnimatorStateInfo(0)
.normalizedTime;
//animator.speed = 0.0001f;
//slider.onValueChanged.AddListener(OnValueChanged);
}
public void Update()
{
float animationTime = animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
Debug.Log("animationTime (normalized) is " + animationTime);
sliderScrubber.value = animationTime;
}
public void OnValueChanged(float changedValue)
{
animator.speed = 0.0001f;
animator.Play("Take 001", -1, sliderScrubber.normalizedValue);
}
}
At the moment this changes the current frame in the animation when you adjust the slider, but when the animation is played, the slider doesn't update.
How can I get this to work in both directions?
Many thanks
First be sure to delete all code lines
animation.speed = 0.0001f
which appear to be leftover from a tutorial or debugging.
What about
public void Update()
{
float animationTime = animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
// in case of a looping anime, animationTime = animationTime %1f;
Debug.Log("animationTime is " + animationTime);
// of course remove that in production
slider.value = animationTime;
}
Note of course set the scrubber min/max to 0f, 1f in the editor.
Note, you may prefer to make a "scrubber" for a joint position; also works nice.
Note, subtle issue: experienced programmers may prefer to set the animation speed to zero, while the user's finger is holding down the slider; probably OK without doing this.
NOTE take care to delete all references to animation.speed. It apears to be a carry-over from an incorrect tutorial.
Ok, so after much throwing things around to see what sticks, this is giving me the result I'm after.
I'd like to thank #JoeBlow for all his help.
Somebody buy that guy a drink.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class NewAnimController : MonoBehaviour {
public Slider sliderScrubber;
public Animator animator;
public void Update()
{
float animationTime = animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
Debug.Log("animationTime (normalized) is " + animationTime);
sliderScrubber.value = animationTime;
}
public void OnValueChanged(float changedValue)
{
animator.Play("Take 001", -1, sliderScrubber.normalizedValue);
}
}
I will update this again when I have a play pause button working and a slider that can change the speed of playback.
I think you almost got it just instead of assigning the value directly in the update function:
sliderScrubber.value = animationTime;
Use this:
sliderScrubber.Set(animationTime, false);
the false parameter is to call the OnValueChange() function in your case you don't want that.
Addionally you can check if the animation is being played to avoid unnecesary calls to the Set function:
http://answers.unity3d.com/questions/362629/how-can-i-check-if-an-animation-is-being-played-or.html
and check your slider.maxValue to adjust it to the animation length.

Unity3d progress bar

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
}
}

Categories