How to play audioclips in unity from script? - unity3d

So I am trying to get the sing method to play one of the audioclips I created up top. I know I need an audioSource, I just have no clue how it fits in with the audioClips. I don't currently have an audiosoure assigned to the object that this script is assigned to, so that might impact things. Thanks for your help.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Piano : MonoBehaviour {
private List<AudioClip> notes = new List<AudioClip>();
public string voice;
public AudioClip ash1, a1, b1, csh1, c1, dsh1, d1, e1, f1, fsh1, g1, gsh1;
// Use this for initialization
void Start () {
//octave1
notes.Add(a1); notes.Add(b1); notes.Add(ash1); notes.Add(c1); notes.Add(csh1);notes.Add(d1); notes.Add(dsh1);
notes.Add(e1); notes.Add(f1); notes.Add(g1); notes.Add(gsh1);
WarmUp(voice);
}
//consider adding countertenor, true alto (i am using mezzo soprano), and baritone.
void WarmUp(string vp)
{
//high and low end of voice parts
// 30 = c4 for example
int high;
int low;
ArrayList range = new ArrayList();
//c4 to c6
if (vp == "Soprano")
{
high = 0; //this is just a range to make the code shorter
low = 7;
for(int i = low; i < high; i++)
{
range.Add(notes[i]);
}
Sing(range);
}
}
/**
* #Param: range. the arraylist of range of notes.
* shift the pitch UP one half step if the up arrow key is pressed
* shift the pitch down one half step if the down arrow key is pressed
* shift the pitch up a third (4 half steps) if the left arrow key is pressed
* shift the pitch up a fifth (7 half steps) if the right arrow key is pressed
*/
void Sing(ArrayList range)
{
//how to play one of the audioclips in range here
}
// Update is called once per frame
void Update () {
}
}

If you attach an AudioSource component to the GameObject, then you could set an AudioSource variable to that component and then call the setter function clip(AudioClip x) to set the clip the source should play. At that point, you could just call Play() and wait for the length of the audio clip.
Code shouldn't be too difficult to figure out but if you have any more questions, don't hesitate to ask. Good luck!

Attach a AudioSource component to your GameObject.
In Sing:
yourAudioSource.clip = (AudioClip)range[Random.Range(0, range.Count)];
yourAudioSource.Play()
You might also consider changing ArrayList range to List<AudioClip> range or similar to avoid the cast

Take a variable of AudioSource _aSource and AudioClip _aClip and assign the audio source game object to the _aSource and clip to the _aClip on the inspector and where want to play the sound just write _aSource.PlayOneShot(a_Clip) that it.

Related

Using Unity's new input system how do I get the value from a 1d axis i have created?

Trying to figure out unity's new input system. I have set up the actions as a 1D axis where W is the positive direction and S is the negative direction. https://ibb.co/gTWGd2W. There is a "Player Input" component where the script for the actions is. https://ibb.co/ZzmsszV. The script is below. I am trying to get the value from the 1d axis and apply it to the paddle in update. but what value i am referencing with value.Get(); obviously isn't right since it is returning 0 at all times. I am not sure what i should be referencing or how to even find that information. I have spent hours searching and can't figure out what I need
using UnityEngine;
using UnityEngine.InputSystem;
public class PaddleBehaviour : MonoBehaviour
{
public GameObject leftPaddle;
public GameObject rightPaddle;
public float moveValueLeft;
public float moveValueRight;
public int moveSpeed = 10;
void Update()
{
leftPaddle.transform.Translate(new Vector3(0, moveValueLeft, 0) * moveSpeed * Time.deltaTime);
rightPaddle.transform.Translate(new Vector3(0, moveValueRight, 0) * moveSpeed * Time.deltaTime);
}
void OnMovement(InputValue value)
{
moveValueLeft = value.Get<float>();
moveValueRight = value.Get<float>();
}
}
I know I'm making a stupid mistake but not sure how to fix it. Thanks in advance for any help.
You can get the value in multiple ways, the easier is to link it thought inspector using the PlayerInput component and marking the behaviour field as Invoke Unity Events, then just drag and drop your components to answer the input (just remember that the method signature must be the same). You can read further about it here https://docs.unity3d.com/Packages/com.unity.inputsystem#1.0/manual/Components.html

I ask for code ideas, the reason why I write below

Hello everyone. I have a character like the picture below, I want when playing the game, this character collides with another character, this character will be hidden (Exactly hide the entire skin shirt, okay? , but the character still moves normally) after about 10 seconds, it will show the skin again as shown below.
I'm stuck in the code. I tried to enable skinnedmeshrenderer , but it forces the sence to reload and it doesn't work very well. If you have any ideas, please let me know. Thank you!!!!
So for this you need to look up how to use colliders. You might want a simple box collider, or even a mesh collider. Then you need to tag the colliders (Go to Learn.Unity or the YouTube website to look for some guides if you don't know about these).
Then use private void OnCollisionEnter(Collision col){} and check col.tag to see if it's what you want and set the character GameObject to innactive* character.SetActive(false);
Then, set a float timer to 10 timer=10; and in Update run
if (timer > 0)
{
timer -= Time.deltaTime;
if (timer <= 0)
{
character.SetActive(true);
}
}
which will reactivate your character after 10 seconds.
* Note
If you don't want to turn the gameObject off, you can instead save the mesh in a variable then set it to null for 10 seconds before restoring it
Alternate solution:
Script used:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
[SerializeField] SkinnedMeshRenderer skinnedMeshRenderer;
Mesh mesh;
float timer = 0;
// Start is called before the first frame update
void Start()
{
mesh = skinnedMeshRenderer.sharedMesh;
}
// Update is called once per frame
void Update()
{
if (timer > 0)
{
timer -= Time.deltaTime;
if (timer <= 0)
{
skinnedMeshRenderer.sharedMesh = mesh;
}
}
if (Input.GetMouseButtonDown(0))
{
skinnedMeshRenderer.sharedMesh = null;
timer = 10;
}
}
}
Model "Steve" thanks to Penny DeBylle

{TextMeshPro problem} Coin collecting system that increases coin counter when the player is in contact with the sphere - works with Debug.Log. [Unity]

I made a coin collecting system that increases the number on a counter when the player comes in contact with the "coin" > sphere. I used Debug.Log to make sure that the counter works. It does. However, When I use TextMeshPro to display that value, it is stuck at zero.
public float moneyStart;
public float unit;
public float moneyNow;
public float displayedMoney;
private TextMeshPro textsss;
void Start()
{
TextMeshPro textsss = GetComponent<TextMeshPro>();
}
void OnCollisionEnter(Collision C_Info)
{
if (C_Info.collider.tag == "Currency")
{
displayedMoney = moneyNow + unit;
textsss.text = displayedMoney.ToString("0");
}
}
Visual for the counter stuck at zero
The script is in the TextMeshPro Element
Am I using TextMeshPro correctly?
How can I use it better?
Are there any errors?
How do I fix it?
Don't pass any argument to the .ToString() method
textsss.text = displayedMoney.ToString();
And to answer your questions, you are using TextMeshPro correctly, updating the text every time the field displayedMoney is getting updated

Unity3D: Setting AudioSource volume dynamically using AnimationCurve

Newcomer to Unity here. For this project, I am reading in an outside AnimationCurve, and attempting to use it to adjust the volume of my GameObject every frame in the Update function. I have found documentation on how to access the volume of my AudioSource GameObject component (this is working), but I can't figure out how to use my evaluated curve to update the volume.
Screencap with imported AnimationCurve and evaluated values
My cs script is included below. Sorry if it's a bit opaque. This is for a neuroscience experiment, so I need to carefully control the animation curves. It reads in times and values (stored in currentCurveData) used to add keyframes to the new AnimationCurve (curveThisTrl) in the SetAnimationFrames() function.
The key part is in Update(). The initial tone.volume is correct, so I know it's reading that property from the GameObject. I can also see the correct curve values coming through in the Debug Log every frame, so I know the curve evaluation is working. It's just not changing the volume property of the GameObject as I want it to.
Hopefully this is enough information to spot a problem, but if not I can try to provide a test AnimationCurve for reproducibility. Thanks in advance for any help.
public class AnimationControl : MonoBehaviour {
private DataController dataControllerRef;
private CurveDataSingleTrial currentCurveData;
private float initTime;
public AnimationCurve curveThisTrl;
AudioSource tone;
void Awake()
{
initTime = Time.time;
}
// Use this for initialization
void Start ()
{
// Get references to key objects in scene
dataControllerRef = FindObjectOfType<DataController>(); // Has values from JSON
tone = GetComponent<AudioSource>();
Debug.Log(tone.volume);
// query the DataController for the current curve data
currentCurveData = dataControllerRef.GetCurrentCurveData();
SetAnimationFrames();
}
void SetAnimationFrames()
{
int numKeyFrames = currentCurveData.keyframeTimes.Length;
for (int c = 0; c < numKeyFrames; c++)
{
curveThisTrl.AddKey(currentCurveData.keyframeTimes[c], currentCurveData.keyframeVals[c]);
}
}
// Update is called once per frame
void Update ()
{
float currTime = Time.time - initTime;
tone.volume = curveThisTrl.Evaluate(currTime);
Debug.Log(tone.volume);
}
}

how to randomly initialize particles system in different places of scene in unity3d

I recently tried asking this question but I realized it was not a sufficient question. In my game the player is a fire fighter learner and i want to broke out fire randomly in my game (like not predictable by player), but i did not know how to implement this.
So far i have done this but nothing goes good.(I have a empty object called t in unity which have 3 to 5 particles systems, and all are set to dont awake at start)
code is here :
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
public ParticleSystem[] particles;
public int numOn = 3;
public int j;
void Start() {
for (int i = 0; i < particles.Length - 1; i++) {
j = Random.Range(i + 1, particles.Length - 1);
ParticleSystem t = particles[j];
particles[j] = particles[i];
particles[i] = t;
}
for (j = 0; j < numOn; j++ )
{
particles[j].Play();
}
}
}
help will be appreciated :-)
You could try using prefabs. Create a game object in the editor that has any particle systems and scripts your fire objects need. Once it's good, drag the object from the hierarchy into your project. This will create a prefab (you can now remove it from the scene). Now, on your spawning script, add a field of type GameObject and drag the prefab you made before into it. Now, when you need to create one, just call Instantiate(prefabVar) to create a copy of your prefab.
Edit:
For your specific case, since you only want one fire to be instantiated in a random location, you could have your spawning script look something like this:
public Transform[] SpawnPoints;
public GameObject FirePrefab;
void Start() {
Transform selectedSpawnPoint = SpawnPoints[(int)Random.Range(0, SpawnPoints.Count - 1)];
Instantiate(FirePrefab, selectedSpawnPoint.position, selectedSpawnPoint.rotation);
}
This solution would allow for you to potentially spawn more than one fire object if you needed. An alternative would be if you will only ever have exactly one fire object in the scene at all. Instead of instantiating from a prefab, the object is already in the scene and you just move it to one of your spawn points at the start of the scene. An example script on the fire object itself:
public Transform[] SpawnPoints;
void Start() {
Transform selectedSpawnPoint = SpawnPoints[(int)Random.Range(0, SpawnPoints.Count - 1)];
transform.position = selectedSpawnPoint.position;
transform.rotation = selectedSpawnPoint.rotation;
}