- Home /
how to get GetAxisRaw to work with other buttons
Hi everyone,
im wondering how to make an axis work like a button im using a guitar hero controller and have set the 6 main button as a,b,c,d,e,f, and they work fine i set up the yaxis as a button and that works but they dont work together
"strum up" returns true on its own but if im holding another button down it stays false
how ever if i hold strum up true and press A or B then it does play the sounds
its like its backwards
many thanks in advance
using UnityEngine; using System.Collections;
[RequireComponent(typeof(AudioSource))]
public class GuitarSetup : MonoBehaviour {
public AudioClip Cdown;
public AudioClip Cup;
public AudioClip Emdown;
public AudioClip Emup;
public AudioClip Gdown;
public AudioClip Gup;
public AudioClip Ddown;
public AudioClip Dup;
public AudioSource source;
public bool a;
public bool b;
public bool c;
public bool d;
public bool e;
public bool f;
public bool strumup = false;
void Awake (){
source = GetComponent<AudioSource>();
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//if(Input.GetButtonDown("strum down")){
if( Input.GetAxisRaw("strum up") != 0)
{
if(strumup == false)
{
//noteonedown();
strumup = true;
noteonedown();
}
}
if( Input.GetAxisRaw("strum up") == 0)
{
strumup = false;
}
//noteonedown();
if(Input.GetButtonDown("joy 0")){
a = true;
}
if(Input.GetButtonDown("joy 1")){
b = true;
}
if(Input.GetButtonDown("joy 2")){
c = true;
}
if(Input.GetButtonDown("joy 3")){
d = true;
}
if(Input.GetButtonDown("joy 4")){
e = true;
}
if(Input.GetButtonDown("joy 5")){
f = true;
}
if(Input.GetButtonUp("joy 0")){
a = false;
}
if(Input.GetButtonUp("joy 1")){
b = false;
}
if(Input.GetButtonUp("joy 2")){
c = false;
}
if(Input.GetButtonUp("joy 3")){
d = false;
}
if(Input.GetButtonUp("joy 4")){
e = false;
}
if(Input.GetButtonUp("joy 5")){
f = false;
}
} void noteonedown(){ if(a == true) { CChord();
}
else
{
notetwodown();
}
}
void notetwodown(){
if(b == true)
{
EmChord();
}
else
{
notethreedown();
}
}
void notethreedown(){
if(c == true)
{
GChorddown();
}
else
{
notefourdown();
}
}
void notefourdown(){
if(d == true)
{
DChord();
}
else
{
notefivedown();
}
}
void notefivedown(){
if(e == true)
{
GChordUp();
}
else
{
notesixdown();
}
}
void notesixdown(){
if(f == true)
{
source.clip = Cup;
source.Play();
}
else
{
print("open strum");
}
}
public void CChord () {
source.PlayOneShot(Cdown);
}
public void CChordUp () {
source.PlayOneShot(Cup);
}
public void EmChord () {
source.PlayOneShot(Emdown);
}
public void EmChordup () {
source.PlayOneShot(Emup);
}
public void GChorddown () {
source.PlayOneShot(Gdown);
}
public void GChordUp () {
source.PlayOneShot(Gup);
}
public void DChord () {
source.PlayOneShot(Ddown);
}
public void DChordup () {
source.PlayOneShot(Dup);
}
}
Answer by Max_Bol · Dec 15, 2016 at 12:56 AM
First, I would say that using GetAxisRaw comes with a price that you should watch out for (if you haven't already). Make sure the "Dead" float for each "float" based button/triggers is relatively close to 0.3. The thing is that guitar axis-based strum can get loose over time and the error margin can reach even as high as 0.3 (meaning pressing the strum less than 1/3 either up or down doesn't return anything).
For this, I suggest you use GetAxis instead of GetAxisRaw and set a Dead zone manually with a float that can be set by the user in the options menu of your project. (Kinda like how steering wheel offers an internal option of adjusting the "center" of the wheel.) In terms of internal mecanism, GetAxisRaw does the exact same thing as GetAxis with a manual dead zone. (It does a if() statement where whenever GetAxis float is higher then Dead, it return 1, else return 0)
Personally, I would also avoid using so many if() statement for each notes. I know it's easy, but you can do something more simple and efficient.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GuitarSetup : MonoBehaviour
{
public AudioSource source;
public AudioClip[] NotesSounds;
public bool StrumIsActive = false;
public float DeadZoneStrum = 0.3f;
void Awake ()
{
source = GetComponent<AudioSource> ();
}
// Update is called once per frame
void LateUpdate ()
{
switch (StrumIsActive) {
default:
if (Input.GetAxis ("Stum up") <= DeadZoneStrum && Input.GetAxis ("Stum up") >= -DeadZoneStrum && StrumIsActive) {
StrumIsActive = false;
}
break;
case false:
if (Input.GetAxis ("Stum up") >= DeadZoneStrum || Input.GetAxis ("Stum up") <= -DeadZoneStrum) {
ManageKeyStroke(
Input.GetButton ("joy 0"),
Input.GetButton ("joy 1"),
Input.GetButton ("joy 2"),
Input.GetButton ("joy 3"),
Input.GetButton ("joy 4"),
Input.GetButton ("joy 5"));
}
StrumIsActive = true;
break;
}
}
void ManageKeyStroke (bool Key0, bool Key1, bool Key2, bool Key3, bool Key4, bool Key5)
{
int NoteToBePlayed = -1;
if(Key5){
NoteToBePlayed = 5;
}
if(Key4){
NoteToBePlayed = 4;
}
if(Key3){
NoteToBePlayed = 3;
}
if(Key2){
NoteToBePlayed = 2;
}
if(Key1){
NoteToBePlayed = 1;
}
if(Key0){
NoteToBePlayed = 0;
}
if(NoteToBePlayed >= 0){
//If only the stum is pressed, NoteToBePlayed will return its initial -1 value and will get ignored. It's what you called "Open strum".
PlayNote(NoteToBePlayed);
}
// If You got another script that manage if the right keys were pressed (based on the song), you could send a call from this function toward that script by implementing a "checker" function into that remotely accessible script.
}
void PlayNote(int Note){
if(NotesSounds[Note]){
source.PlayOneShot(NotesSounds[Note]);
}
else{
Debug.LogWarning("An unknown note is being requested : #" + Note);
//This will get called if the function return a sount that is not part of the NotesSounds array of soundclip.
}
}
}
This does more or less the same thing as you wrote, but in a more direct approach. The switch() statement is really useful when you know you don't need the "else" to be checked every time. In terms of memory, if() and else() gets read by the engine even if they aren't used, unlike switch() which is simply ignored (non-existant) in the engine memory unless its value returns true. (Which is why switch can't uses ambiguous values and things like floats should be avoided with it.
I made use of LateUpdate() instead of Update() for the input. Usually, it's suggested that Update() is used for inputs, but when you want something ultra precise that is based on both the UI display and user input, it's better to us LateUpdate(). Think of it as this : During the Update(), your UI is updated and the key color or whatever you're displaying is moving in THAT frame. So if the game perfectly press the button at the frame when the color dot (or whatever) is a the perfect position, his input will only be called onto the next frame (so 1 frame late). It might sound ridiculous, but it's noticeable for skilled players. By putting the input into the LateUpdate(), you push the "scan" for the input after the updated display of the UI, but before the next update of the UI. (between both) In a game where the player "avoid" being hit, Update give 1 frame "preview" of margin to the player. In a game where you want the player to press exactly at the right time when something is going on in the UI, you use LateUpdate(). If you ever played a game where you got this mini-game that requires you to press a button when 2 circles (one circle that is growing or shrinking and 1 "static" circle) touch each other, many devs does the mistake of checking it in the Update() which make it feels like you had to press "ahead" of the actual moment. This is why LateUpdate() is used in this particular setting.
You'll also notice I make use of an array instead of enumerating each SoundClip. This way, you can add more "notes" without altering too much your script. This also allow you to mix keys together for a different sound. (So, if Key 0 and Key 3 is both pressed, you get a different note than if you used Key 0 or Key 3.) But that requires you to manage the NoteToBePlayed integer accordingly. I made the script.
Now, depending on what kind of sound you uses for the Notes, this is not a complete script. It's more of a basic sketchup of a script based on what you wrote that should works. From your script, I guess you priories the early key/button ("joy 0" over "joy 1" over "joy 2", etc.) over the other keys for what sound it plays.
If you want to have dual keys, you'll have to put more soundclips to fills those dual keys sounds and that's where this script above shine the most and it all depends on how good you are a translating 5 bools inputs into a single int to get the right sound out of a clip array. (And also on how many notes sounds you have at your disposition.)
Hi, thank you for the reply...
this script has the same result as $$anonymous$$e how ever StrumIsActive Bool in the inspector is showing true then false then true when its running
with no sound
The first thing I would do, in this case, is test out how you Strum trigger returns values.
Something as simple as:
Debug.Log(Input.GetAxis ("Stum up")); And play with it with no other debug calls.
Check what values comes out of it then adjust the DeadZoneStrum based how the results. If you notice fluctuation where pressing the Strum return inconsistent values (like 1-1-1-0.8-0.3-0.4-1-1) as you keep pressing the strum, you might have to uses a different approach.
I tested out my script and it works 100% on my end (though there are many things I would add to it to make it more complete, but that's not the thing here.) I haven't tested it out with a Guitar Hero's guitar because I don't have one right now, but I tested it out with a 360 controller. (It was strange to "use", but it simulated the buttons and triggers).
The problem about the sound might come from something else that affects the AudioSource.
okay ive done some digging and checked to see whats happening
using void Update () { if( Input.GetAxis("Strum up") > 0) { Debug.Log(Input.GetAxis ("Strum up")); }
if( Input.GetAxis("Strum up") == 0) { Debug.Log(Input.GetAxis ("Strum up")); }
as it turns out the problem is the controller if i hold the button up it returns 1 witch is right however if i press any button on the controller it sets to 0 and wont detect the key press
accepted as working its the guitar hero controller at fault works with the PoV on the controller
Your answer
Follow this Question
Related Questions
How to detect inputs from a dance dance revolution carpet 1 Answer
Setting up inputs for multiple gamepads/controllers 1 Answer
MMD How to export model and animations to Unity as 3rd person controller? 2 Answers
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
Using DPad/Joystick in "new" InputSystem as digital rather than analog 1 Answer