The name 'Microphone' does not exist in the current context unity - c#

The name 'Microphone' does not exist in the current context. getting this error when opening an unity(version 5.6.0f3) project is visual studio 2017 in window 8.
[RequireComponent (typeof (AudioSource))]
public class SingleMicrophoneCapture : MonoBehaviour
{
//A boolean that flags whether there's a connected microphone
private bool micConnected = false;
//The maximum and minimum available recording frequencies
private int minFreq;
private int maxFreq;
//A handle to the attached AudioSource
public AudioSource goAudioSource;
public AudioClip recordedAudioClip;
[HideInInspector]
public AudioClip myAudioClip;
//public Text fileExist;
bool startRecording = false;
public Sprite[] recordingSprites;
public int count =0;
//int recordedFileCount =0;
public bool isDefaultAudioPlaying = false;
[SerializeField]
public Sprite[] playSprites;
public GameObject forwardButton;
public GameObject backwardButton;
public GameObject playButton;
public GameObject replayButton;
//Use this for initialization
public AudioClip[] allAudioClips;
public string storyName;
float[] samples;
public Dictionary<int,float> recordedClipDict;
void Start()
{
//ReplayButtonClicked ();
//Check if there is at least one microphone connected
recordedAudioClip= null;
if(Microphone.devices.Length <= 0)
{
//Throw a warning message at the console if there isn't
Debug.LogWarning("Microphone not connected!");
}
else //At least one microphone is present
{
//Set 'micConnected' to true
micConnected = true;
//Get the default microphone recording capabilities
Microphone.GetDeviceCaps(null, out minFreq, out maxFreq);
//According to the documentation, if minFreq and maxFreq are zero, the microphone supports any frequency...
if(minFreq == 0 && maxFreq == 0)
{
//...meaning 44100 Hz can be used as the recording sampling rate
maxFreq = 44100;
}
//Get the attached AudioSource component
goAudioSource = this.GetComponent<AudioSource>();
// mainAudioSource = Camera.main.GetComponent<AudioSource> ();
}
}
how to solve this.

You are getting this error because you using a platform that do not support the Microphone API. One of the platforms that do not support the Microphone API is the WebGL. There might be other platforms other than WebGL without Microphone support.
Switch to a platform that supports the Microphone API from the Build Settings.
You can also use Unity's preprocessor directives to guard it and make sure that the Microphone API is not used when using platforms that do not support it or did not implement it.
#if !UNITY_WEBGL
//YOUR Microphone CODE HERE
#endif
If you really need Microphone in WebGL with Unity, make a plugin or use this one(Not free).

We can not see your using statements.
But it seems like your are missing
using UnityEngine.AudioModule;

Related

Unity 2018 - OnAudioFilterRead() realtime playback from buffer

Let me start by saying that this is my first time opening up a question here. If I'm unclear in my code formatting or have expressed myself poorly, please let me know and I'd be happy to adjust.
I'm doing conceptual design for a tool to be used in Unity (C#) to allow us to "stream" the output of an AudioSource, in real-time, and then have that same audio be played back from a different GameObject. In essence, we would have a parallel signal being stored in a buffer while the original AudioSource functions as one would expect, sending it's playing clip into the mixer just as is normal.
To achieve this I'm trying to use the audio thread and the OnAudioFilterRead() function. To extract the floating point audio data to pipe into OnAudioFilterRead() i'm using AudioSource.GetOutputData, storing that into an array and then supplying the array to the audio filter. I'm also creating an empty AudioClip, setting it's data from the same array and playing that AudioClip on the new GameObject.
Right now I have the audio being played from the new GameObject, but the result is very distorted and unpleasant, which i'm chalking up to one or more of the following;
The audio buffer is being written to/read from in an unsynched manner
Unitys samplerate is causing problems with the clip. Have tried both 44.1khz and 48khz with subpar results, as well as playing around with import settings on clips. Documentation for Unity 2018.2 is very weak and a lot of older methods are now deprecated.
Aliens.
Ideally, I would be able to stream back the audio without audible artefacts. Some latency i can live with (~30-50ms) but not poor audio quality.
Below is the code that is being used. This script is attached to the GameObject that is to receive this audio signal from the original emitter, and it has its own AudioSource for playback and positioning.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
[RequireComponent(typeof(AudioSource))]
public class ECO_receiver : MonoBehaviour {
public AudioSource emitterSend;
private AudioSource audioSource;
public AudioClip streamedClip;
public bool debugSampleData;
private float[] sampleDataArray;
public float sampleSize;
public float sampleFreq;
private int outputSampleRate;
public bool _bufferReady;
void Start () {
audioSource = GetComponent<AudioSource>();
sampleSize = emitterSend.clip.samples;
sampleFreq = emitterSend.clip.frequency;
sampleDataArray = new float[2048];
streamedClip = AudioClip.Create("audiostream", (int)sampleSize, 1, (int)sampleFreq, false);
audioSource.clip = streamedClip;
audioSource.Play();
_bufferReady = true;
}
private void FixedUpdate()
{
if (emitterSend.isPlaying && _bufferReady == true)
{
FillAudioBuffer();
}
else if (!emitterSend.isPlaying)
{
Debug.Log("Emitter is not playing!");
}
if (debugSampleData && sampleDataArray != null && Input.GetKeyDown("p"))
{
for (int i = 0; i < sampleDataArray.Length; i++)
{
Debug.Log(sampleDataArray[i]);
}
}
else if (sampleDataArray == null)
{
Debug.Log("No data in array!");
}
}
void FillAudioBuffer()
{
emitterSend.GetOutputData(sampleDataArray, 0);
streamedClip.SetData(sampleDataArray, 0);
_bufferReady = false;
}
void OnAudioFilterRead(float[] data, int channels)
{
if (!_bufferReady)
{
for (int i = 0; i < data.Length; i++)
{
data[i] = (float)sampleDataArray[i];
}
_bufferReady = true;
}
}
}
Greatly appreciate any wisdom I might be granted! Thank you!

Sync ParticleSystem across Clients and server, Unity3D

I am trying to switch a single player game into multiplayer using unity 5.6.4p2 and c#.
I have two particle systems:
"enginePS" set to play on-wake which appears on all sides (cliens + server).
"engineSpeedPS" which set to play when player moving forward.
The second particle system does not appear only for localplayer the one moving forward, so others does not see the particle system.
I am new to UNet so I would really appreciate your help. please check my code below:
using UnityEngine;
using UnityEngine.Networking;
public class MP_PlayerController : NetworkBehaviour
{
public ParticleSystem enginePS1, enginePS2, engineSpeedPS1, engineSpeedPS2,
engineSpeedPS3;
private float verticalCurrentValue;
private float movingX, movingZ;
private bool zAxis;
public bool isMovingForward = false;
public bool isMovingBackward;
public float currentPossition;
public GameObject player;
void Start()
{
engineSpeedPS1.Stop();
engineSpeedPS2.Stop();
engineSpeedPS3.Stop();
verticalCurrentValue = movingZ;
currentPossition = transform.position.z;
}
void Update()
{
if (!isLocalPlayer)
{
return;
}
movingX = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f;
movingZ = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f;
transform.Rotate(0, movingX, 0);
transform.Translate(0, 0, movingZ);
ChangeEngineParticle();
}
void ChangeEngineParticle()
{
if(!isLocalPlayer)
{
return;
}
if (Input.GetKey("up"))
{
if (isMovingForward == false)
isMovingForward = true;
}
else
{
if (isMovingForward == true)
isMovingForward = false;
}
if (isMovingForward)
{
if (!engineSpeedPS1.isPlaying)
{
engineSpeedPS1.Play();
engineSpeedPS2.Play();
engineSpeedPS3.Play();
}
}
else if (isMovingForward == false)
{
if (engineSpeedPS1.isPlaying)
{
engineSpeedPS1.Stop();
engineSpeedPS2.Stop();
engineSpeedPS3.Stop();
}
}
}
I tried using the [Command] attribute before CmdChangeEngineParticle(), but that made the engineSpeedPS to work at the server end only without being detected at the client end.
Any ideas??
OK so your second engineSpeedPS can be ignored in the networking code - just play that locally on the client using isClient or similar. It doesn't need to go over the network.
I'll talk just about setting the other ParticleEffect, which you want to play everywhere. It is on a Client object, meaning that object is controlled by the client. The client should tell the server that it's time to play the particles, and the server then tells all other connected clients.
The particles probably shouldn't play on awake, as everyone will awake at different times.
So you should have your own code that decides it's time to play the particles. When it does it tells the server with a Command. Note, this should be on the Player object - if not you'll need to Assign Client Authority.
[Command]
public void CmdStartParticles()
{
}
So the client in charge calls CmdStartParticles(). The [Command] tag means that it doesn't get executed locally, but on the server instead.
So what do we want the server to do? It should tell all Clients to play the particles, and also play them itself.
[ClientRpc]
public void RpcStartParticles()
{
DoStartParticles();
}
public void DoStartParticles()
{
particles.Play();
}
The first function can only be called by a server, and it acts on all the connected clients.
The second function is just a handy way to actually do the action
In the CmddStartParticles function, you would just call RpcStartParticles() and also DoStartParticles() (because you want the server to also play them, and RpcStartParticles only affects the clients ).
Rip off the Tanks Demo, which I believe has moving things with engines which play Particle Effects. It might be a bitt outdated, but should help still.

Audio doesn't play when instantiate new object

I'm facing audio problems in my project. There are three paddle game objects and one cube. Cube has Rigidbody2d or BoxCollider2d. And there is also a button script attach to cube which has button function when we click on button cube Kinematic becomes false and drop on the paddle. When it's collide with any paddle cube destroy and instantiate again with new prefab. When Cube is falling sound is play and cube is destroy. New cube is instantiate when again click on button then error came.
MissingReferenceException: The object of type AudioSource has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.
Scripts on all paddles:
public class Paddle : MonoBehaviour
{
[SerializeField]
private AudioSource source;
[SerializeField]
private AudioClip hit;
[SerializeField]
private BoxCollider2D collide;
[SerializeField]
private GameObject Clone;
void Awake()
{
collide.isTrigger = true;
}
void OnTriggerEnter2D(Collider2D target)
{
source.PlayOneShot(hit);
Destroy(target.gameObject);
Instantiate(Clone, new Vector3(0f, 4.51f, 0f), Quaternion.identity);
}
}
Cube Script:
public class Cube : MonoBehaviour
{
[SerializeField]
private AudioSource source;
[SerializeField]
private Rigidbody2D body;
[SerializeField]
private AudioClip play;
private Button bt;
private float pos;
public bool check;
void Start()
{
bt = GameObject.FindGameObjectWithTag("Button").GetComponent<Button>();
bt.onClick.AddListener(Fire);
body.isKinematic = true;
}
void Update()
{
if (check)
{
return;
}
Vector3 temp = transform.position;
pos = Camera.main.ScreenToWorldPoint(Input.mousePosition).x;
temp.x = Mathf.Clamp(pos, -6.25f, 6.25f);
body.position = temp;
}
public void Fire()
{
GameObject.FindGameObjectWithTag("Player").GetComponent<Cube>().check = true;
GameObject.FindGameObjectWithTag("Player").GetComponent<Rigidbody2D>().isKinematic = false;
source.PlayOneShot(play);
}
}
Cube image:
Paddles image:
New Export package:
https://drive.google.com/file/d/0B1H5fdK2PJAnSXVPdmE5Z3J1SUU
Problem in Video:
https://drive.google.com/file/d/0B1H5fdK2PJAnYzRfVnlQT1FyTlE
Your linked package works fine, it does play the sound every time I launch and destroy a cube.
Nonetheless, you should remove the method on destroy. Unity does not throw any error nor warning when a non-persistent listener is null, kinda weird but this is how it is. You should remove it manually:
void OnDestroy(){
bt.onClick.RemoveListener (Fire);
}
But your package does not throw any error when I run it.
Though, I would rethink your approach, instead of the cube assigning its Fire method to the Button event, I would have a script on the button containing the Fire method as well as the AudoiSource and clip. Then on Start, the Cube would pass itself so that the button could access its Cube and Rigidbody2D component.
Best would be to pass a class that contains those are members:
public class CubeArgument{
public readonly Rigidbody2D rg = null;
public readonly Cube cube = null;
public CubeArgument(Rigidbody2D rg, Cube cube){
this.rg = rg;
this.cube = cube;
}
}
then here goes your Cube start method:
void Start () {
bt = GameObject.FindGameObjectWithTag ("Button");
bt.GetComponent<ButtonController> ().Init(new CubeArgument(body, this));
body.isKinematic = true;
}
The ButtonController reference could even be made static since there is only one for the whole level.
and then on the button you have a ButtonController:
public class ButtonController : MonoBehaviour{
Cube currentCube = null;
Rigodbody2D currentRig = null;
public void Init(CubeArgument ca){
currentRig = ca.rg;
currentCube = ca.cube;
}
public void Fire(){
if(currentCube != null){ currentCube.check = true; }
if(currentRig != null) { currentRig.isKinematic = false; }
}
}
Fire is passed as listener to the Button onClick and this is it.
your problem can be from many different places. my guesses:
1)problem with your build: rebuild your code or export all of your package to new project and retest.
2)your target framework: latest version of unity(i have 5.1) just support to .net 3,5 and unity 4.x supports 2,5 i think. so chek your target framework to not to use functions that is not functional in your version
3)settings of your platform that your editor is running on: it can be volume of your platform to many other settings, first option to know that is run your project on other machine (maybe its a unity bug that part of code is not good for your hardware or driver on platform)
Edit: OP was using version 5.1.1. This error does not repeat after Unity 5.2.
Tried your package and it is working fine!
No errors. Audio played when instantiated.
Are you still facing errors? Weird, dude. Sounds like something is not clean enough.
Maybe there is some issue with your build.
Few things you could try:
1- Try restarting your Unity. Maybe this will force Clean things.
2- Create a new project and import your own package to test it!
3- I'm using Unity 5.3.0f4 what Unity version are you using? Try an update.
If none of above works, there is something wicked going on with your AudioSource reference and I can't help you with my actual knowledge. But still we can try to do different approaches for that.
Instead of physically referenced it (Dragging and dropping), do it at the start of your script.
Desperate approach 1
On Cube.cs:
First remove [SerializeField] located above of private AudioSource source; and add the following line on the Start() method:
source = gameObject.GetComponent<AudioSource> ();
Practically the same, but now the script is referencing the own object Audio Source for you. Do the same approach with Paddle.cs. [remember to check the audio name when applying the approach for Paddle script. On paddle the audio name is PlayOneShot (hit) not PlayOneShot (play)].
If this still trigger some error. Let's try another approach.
Desperate approach 2
On Cube.cs:
Remove/Comment the following line on Fire() method:
source.PlayOneShot (play);
Add the following line to Fire() method:
gameObject.GetComponent<AudioSource> ().PlayOneShot (play);
This will get your actual AudioSource on the go. Do the same approach on Paddle.cs [remember to check the audio name when applying the approach for Paddle script. On paddle the audio name is PlayOneShot (hit) not PlayOneShot (play)].

How do I access an updated variable between two scripts in Unity with C#?

Hopefully this isn't too much detail, I'm not used to asking programming questions.
I'm attempting to do the 3D Video Game Development with Unity 3D course that's on Udemy, though using C# instead of Javascript. I just finished up the tutorial that involves creating a space shooter game.
In it, a shield is created by the user when pressing a button. The shield has a "number of uses" variable that does not actually get used by the time the tutorial has finished. I'm trying to add it in, and have successfully managed to implement it so that with each use, we decrease the number of uses remaining, and no longer are able to instantiate the shield once that number is <=0.
This variable is stored on the player, and if I print it from the player, it returns the value I would expect.
However, I'm using a separate SceneManager.cs (this is where the tutorial placed the lives, and score, and timer variables ) where I print numbers into the GUI. My problem is that I cannot get my number of uses variable to stay current when I try to print it from the scene manager... it registers the initial value, but doesn't update after that.
Here is the Player Script
using UnityEngine;
using System.Collections;
public class player_script : MonoBehaviour {
// Inspector Variables
public int numberOfShields = 2; // The number of times the user can create a shield
public Transform shieldMesh; // path to the shield
public KeyCode shieldKeyInput; // the key to activate the shield
public static bool shieldOff = true; // initialize the shield to an "off" state
public int NumberOfShields
{
get{return numberOfShields;}
set{numberOfShields = value;}
}
// Update is called once per frame
void Update()
{
// create a shield when shieldKey has been pressed by player
if (Input.GetKeyDown (shieldKeyInput)) {
if(shieldOff && numberOfShields>0)
{
// creates an instance of the shield
Transform clone;
clone = Instantiate (shieldMesh, transform.position, transform.rotation) as Transform;
// transforms the instance of the shield
clone.transform.parent = gameObject.transform;
// set the shield to an on position
shieldOff = false;
// reduce the numberOfShields left
numberOfShields -=1;
}
}
print ("NumberOfShields = " + NumberOfShields);
}
public void turnShieldOff()
{
shieldOff = true;
}
}
when I run "print ("NumberOfShields = " + NumberOfShields);" I get the value I expect. (astroids trigger the turnShieldOff() when they collide with a shield.
Over in my Scene Manager however... this is the code I'm running:
using UnityEngine;
using System.Collections;
public class SceneManager_script : MonoBehaviour {
// Inspector Variables
public GameObject playerCharacter;
private player_script player_Script;
private int shields = 0;
// Use this for initialization
void Start ()
{
player_Script = playerCharacter.GetComponent<player_script>();
}
// Update is called once per frame
void Update ()
{
shields = player_Script.NumberOfShields;
print(shields);
}
// GUI
void OnGUI()
{
GUI.Label (new Rect (10, 40, 100, 20), "Shields: " + shields);
}
}
Any idea what I'm doing wrong that prevents shields in my SceneManager script from updating when NumberOfShields in my player_script updates?
I think you might have assigned a prefab into playerCharacter GameObject variable instead of an actual in game unit. In this case it will always print the default shield value of prefab. Instead of assigning that variable via inspector try to find player GameObject in Start function. You can for example give your player object a tag and then:
void Start() {
playerCharacter = GameObject.FindGameObjectWithTag("Player");
}

OnGui elements interacting with other OnGui elements

Within my 2d game i wsih to have a number of OnGui elements there for the user to select, however, the cursor that im using is another ongui element(using kinect to navigate) is this possible by any chance, at the moment im using planes but i will be zooming in and out of the camera so ill essentially need them attatched to the screen. Any ideas, suggestions or workarounds.
THis is currently my cursor.
using UnityEngine;
using System;
using System.Collections;
public class PillarAgent : MonoBehaviour {
public SkeletonWrapper sw;
public Vector3 distance;
public float progress =0f;
public Texture2D cursor;
public Texture2D load;
public Camera mainCam;
public float startTime;
private int roundedRestSecounds;
// Use this for initialization
float differencex = 0;
float differencey = 0;
void Start () {
distance =new Vector3(0f,0f,0f);
}
float translate(float value, float leftMin, float leftMax,
float rightMin,float rightMax)
{
float leftSpan = leftMax - leftMin;
float rightSpan= rightMax - rightMin;
float valueScaled = (value-leftMin)/(leftSpan);
return rightMin+(valueScaled * rightSpan);
}
// Update is called once per frame
void Update () {
if (sw.pollSkeleton())
{
distance.x=sw.bonePos[0,0].x - sw.bonePos[0,7].x;//5 is left shoulder
distance.y=sw.bonePos[0,0].y -sw.bonePos[0,7].y;
differencex=translate(distance.x,.6f,0,0,Screen.width);
differencey=translate(distance.y,-.5f,0,0,Screen.height);
//Debug.Log();
float width = sw.bonePos[0,5].x+ sw.bonePos[0,9].x;
float height =sw.bonePos[0,4].y- sw.bonePos[0,0].y;
float heightdiv= (height/2)+sw.bonePos[0,0].y;
}
}
void OnGUI() {
//left top width height
Rect r = new Rect(differencex,differencey,80,50);
GUI.Label(r,cursor);
GUI.BeginGroup(new Rect(differencex,differencey+50,50*Mathf.Clamp01(progress),15));
//Debug.Log(progress);
GUI.DrawTexture(new Rect(0,0,50,50),load);
GUI.EndGroup();
transform.position =mainCam.ScreenToWorldPoint(new Vector3(differencex,Screen.height-differencey,50));
//mainCam.fieldOfView()
}
void OnCollisionStay(Collision Other)
{
startTime+=Time.deltaTime;
if(Other.gameObject.GetComponent(typeof(TextControl)))
{
roundedRestSecounds=Mathf.CeilToInt(Time.time);
progress = Time.time *0.2f;
CurrentState=true;
}
else if(Other.gameObject.tag==("Scalpal")){
progress = startTime *0.5f;
//scallpall activated
//
}
}
void OnCollisionExit(Collision Other){
startTime =0f;
progress =0f;
}
public Boolean CurrentState{get;set;}
}
The next class is essentially the class in which i pick up my tools, currently this code doesnt work(not sure why), but what i wish to do is select some tools which show up on the screen so that i can use them,for e.g pick up paint brush start painting bricks or what not. at the moment i have my tools on a plane, i wish to always have them on the screen at all times when the camera moves.
using UnityEngine;
using System.Collections;
public class SelectTool : MonoBehaviour {
public Tools tools;
public float startTime;
public bool ScalpalSelected;
public GameObject selectedTool;
void Start()
{
tools = this.GetComponent<Tools>(); //in order to use this tools muyst be attached to the game object
//this is essentially saying with regards to this game object get the component named tools
}
void update()
{
}
void OnCollisionStay(Collision Other)
{
startTime +=Time.deltaTime;
if(startTime >5f){
if(Other.collider.tag==("Scalpal"))
{
selectedTool = Other.collider.gameObject;
Debug.Log(selectedTool+" What in gods good name is:" +tools.utilities[0]);
}
else {
selectedTool=null;
}
if(selectedTool){
for(int i=0;i<tools.utilities.Length;i++)
{
}
}
ScalpalSelected=true;
renderer.material.color = Color.yellow;
}
}
void OncollisionStay(Collision other){
startTime = 0f;
}
}
From the comment section to the question I will assume that you want to know how to do this:
"... you want your plane objects to move together with the camera ..." - Steven Mills
"thank you #StevenMills Do you have any example of how this can be done?" j bel
While the answer provided in the comments is to just manually add the planes as children of the camera (a very straightforward, manual approach), I will give another way to do this through scripting (in light of maybe this will help someone else out disregarding the likeliness of someone using this solution).
The idea of this is to create a script (thus following being attached to the MainCamera) that will search through all of the GameObject in the Object Hierarchy with the method GameObject.FindGameObjectsWithTag. Once we have all our GameObject with the associated Tag, we can then loop through the array and parent the attached script's GameObject to each.
public class ParentGameObjects : MonoBehaviour {
//The tag to search for on all game objects in the hierarchy
public String objectTag;
//The game objects that we will parent the main camera to
private GameObject[] children;
//It's not necessary to store references to the children but if you want to modify them at some point you will be able to
void Start() {
//Find all game objects with the tag we want
children = GameObject.FindGameObjectsWithTag(objectTag);
//Loop through all of the game objects found and parent this object's transform
for(int i = 0; i < children.Length; i++) {
children[i].transform.parent = transform;
}
}
}
Now, there are a few things you have to do for this script to work:
Attach this script to any GameObject that you want to parent other objects to.
In the Inspector of the GameObject that the script is attached to, enter in the name of the Tag you want to use.
For all GameObject(s) in the Hierarchy that should be added as children, assign the same Tag.
Of course there are other things you can do like, for example, instead of only searching for one Tag be able to search for multiple but that requires a bit (not exactly much) more work. Nonetheless, I hope this will at least be useful information to someone on how parenting works via scripting.

Categories