- Home /
How to Fire Shells With Speech Recognition Input
Hey there. So, I want to make a Shoot function from a String input which I receive through a Speech Recognition system. The problem is, because it is in Update function, as long as the string variable is saying "fire", it keeps firing the rounds. And the input keep saying "fire" as long as I don't say another command like "move forward". But I have no idea how to receive the String input without using the Update function. I mean, it has to keep listening for the change of the input String right? Any help is appreciated.
public class Tembak : MonoBehaviour {
public float timer = 1;
public float timerMax = 1;
public float powerOfShot = 100;
public Rigidbody TankShell;
bool myCheck = false;
void Update ()
{
string move = GameObject.Find("Script").GetComponent<Client>().move;
if(move == "fire") {
myCheck = true;
Shoot();
}
}
void Shoot ()
{
if(!myCheck){
Rigidbody clone;
timer = 0;
clone = Instantiate(TankShell, transform.position, transform.rotation) as Rigidbody;
clone.velocity = transform.TransformDirection(Vector3.right * powerOfShot);
myCheck = false;
}
}
Here's the Java code I used to send the string Input into Unity through UDP Socket:
int port = 1000;
byte[] message = resultText.getBytes();
// Get the internet address of the specified host
InetAddress address = InetAddress.getLocalHost( );
//System.out.println(address);
// Initialize a datagram packet with data and address
DatagramPacket packet = new DatagramPacket(message, message.length,
address, port);
while(resultText!=temp){
// Create a datagram socket, send the packet through it, close it.
DatagramSocket dsocket = new DatagramSocket();
//System.out.println(packet);
dsocket.send(packet);
dsocket.close();
temp = resultText;
And here's the receiving code written in C#:
byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
move = returnData;
print(move);
Any help appreciated.
When does this 'send and receive' stuff happen? Is it every frame, on query, or is it triggered by new messages being received by your speech recognition stuff? There might be a workaround for this.
Answer by aldonaletto · Oct 26, 2011 at 01:26 AM
You can execute a command one time only, and reject all repetitions: if the command received is different from lastCmd, execute and assign it to lastCmd. This will shoot only once when "fire" is received. You must send a different command to change lastCmd and enable "fire" again. To use several "fire" in sequence, your speech recognition should send a blank or some other string when nothing is being recognized.
public class Tembak : MonoBehaviour {
public float timer = 1;
public float timerMax = 1;
public float powerOfShot = 100;
public Rigidbody TankShell;
string lastCmd = "";
void Update ()
{
string move = GameObject.Find("Script").GetComponent<Client>().move;
if (move != lastCmd){ // only accepts new command if different from the last one
lastCmd = move; // updates last command
if(move == "fire") {
Shoot();
}
}
}
void Shoot ()
{
Rigidbody clone;
clone = Instantiate(TankShell, transform.position, transform.rotation) as Rigidbody;
clone.velocity = transform.TransformDirection(Vector3.right * powerOfShot);
}
}
Thank you for your answer. It really help me in solving one of the problem. But as I was saying, The speech recognition I use is on another system and written in Java. It runs separately and send the result through UDP Socket to Unity. The problem is I need the system to keep sending the recognized result to make other command works (beside 'fire' of course). Take 'move forward' for example, I need the system to keep sending it to make the vehicle stays moving. If it only sends once then sends blank, the vehicle will stop.
I'll update the question to provide you with the UDP Socket sending and receiving.
It would be better to send the command only once, and interpret the commands in the Unity side. If the command is "move forward", for instance, start moving and stop only when receiving "stop", or other movement related command. If it's "fire", shoot once. The speech system have its own hard work to do, the command interpretation should be entirely a game job. If you can modify the speech recognition system, change it to this "one-shot" mode - it's a lot easier.
Answer by syclamoth · Oct 26, 2011 at 01:13 AM
Well, if you want it to only act when the input string changes, you can do something like this-
private string previousCommand = "";
//inside of update, after you get 'move'
if(move != previousCommand)
{
// do whatever you need to do
previousCommand = move;
}
This makes sure that it will only call the command once.
Of course, if the player calls 'Fire' twice in a row, this method will not register the second one! Is there some way of resetting your speech control algorithms? With the system as you have described it, I can't think of a way of getting around this problem.
Also, I'm not sure about the way you are calling the 'Shoot' method. Why do you have CancelInvoke("Shoot") after it? This won't do anything unless you are using InvokeRepeating or something to activate Shoot, which you are not. You would be better served just to call Shoot once, unless it is some kind of rapid-fire thing, in which case I would use some kind of Coroutine-
IEnumerator RapidFire(float timeBetweenShots, int shots)
{
canShoot = false;
while (shots > 0)
{
// instantiate a bullet, add force etc.
shots--;
yield return new WaitForSeconds(timeBetweenShots);
}
canShoot = true;
return null;
}
Then, to shoot ten bullets at 1/5 of a second intervals, do this-
if(canShoot)
{
StartCoroutine(RapidFire(0.2f, 10));
}
The 'canShoot' boolean prevents you from firing the gun if it is already shooting. Declare it at the head, with your public variables.
Thank you for your answer. And I'm sorry for the CancelInvoke function, indeed it done nothing and it's just a line I forgot to erase after experimenting with the code.
The answer that you've given solve half the problem but as you've said, I can't fire twice in a row. The speech recognition I use is on another system and written in Java. It runs separately and send the result through UDP Socket to Unity. I'll update the question with codes that I use to send data and receive in Unity so maybe you could help with the workaround.
Answer by meazant · Oct 28, 2011 at 06:00 PM
Thank you for both of your answers. It had been a big help. I've solved the problem by tinkering with the Speech Recognition code and make it send a "fire done" string only after it sends "fire". By doing this the game script will execute Shoot function and then receive another command instantly. this make it possible to fire twice in a row because the previous command will be "fire done", not "fire". Once again, thank you.
Answer by gringofxs · Dec 04, 2012 at 02:59 AM
It is possible to play an animation, With Speech Recognition Input.
When i said (PITOCO) the animation start to play and them stop. Any help?
Your answer
Follow this Question
Related Questions
How to add symbols to string? 2 Answers
firing my bullitprefab up and to the side 0 Answers
Create Texture2D and assign image to it through a script 1 Answer
health system and gui update 0 Answers
firing a shell from a tank turret 1 Answer