edit: The thread title should read keycombo script. sorry.
First of all thanks for taking a look at this thread whether you can help or not. I’m creating a mobile game and I want to implement a combo system into it. I’ve researched the topic extensively and the Unify wiki Keycombo script seems to be a popular one, but as of now it is scripted for keyboard use only. I have two guitextures in my game that are serving as buttons for combos that I have been trying to get working instead of keyboard buttons (joystick movement isn’t used for combos). I’ve tried several different iterations of the script and found some progress, but no real solution. I’ve reached out to multiple members of the community who have tried to do the same as I am now, but none of them seem to have had any luck, and have moved to different options that aren’t as fluid as the keycombo script. But they have expressed that if I find a way to implement that to please let them know. Seeing that I’m not the only one struggling to work this out, I’ve decided to post this here to see if the community as a whole could help. The final, working script will be posted on unify’s wiki page to help those following our footsteps. Again, thanks for looking over this thread, and if you have any suggestions, whether you’re unsure if it will work or not, please feel free to post it. Below I’m going to post the C# keycombo script and implementation from the Unify website, how to use guitextures as buttons for those who have only worked on keyboard games, and the closest script I’ve done that has come close to solving this problem. Thanks.
Here is the keycombo script. Note, this script doesn’t derive from Monobehaviour so it can’t and shouldn’t be put on an empty gameobject in the scene.
using UnityEngine;
public class KeyCombo
{
public string[] buttons;
private int currentIndex = 0; //moves along the array as buttons are pressed
public float allowedTimeBetweenButtons = 0.3f; //tweak as needed
private float timeLastButtonPressed;
public KeyCombo(string[] b)
{
buttons = b;
}
//usage: call this once a frame. when the combo has been completed, it will return true
public bool Check()
{
if (Time.time > timeLastButtonPressed + allowedTimeBetweenButtons) currentIndex = 0;
{
if (currentIndex < buttons.Length)
{
if ((buttons[currentIndex] == "down" Input.GetAxisRaw("Vertical") == -1) ||
(buttons[currentIndex] == "up" Input.GetAxisRaw("Vertical") == 1) ||
(buttons[currentIndex] == "left" Input.GetAxisRaw("Vertical") == -1) ||
(buttons[currentIndex] == "right" Input.GetAxisRaw("Horizontal") == 1) ||
(buttons[currentIndex] != "down" buttons[currentIndex] != "up" buttons[currentIndex] != "left" buttons[currentIndex] != "right" Input.GetButtonDown(buttons[currentIndex])))
{
timeLastButtonPressed = Time.time;
currentIndex++;
}
if (currentIndex >= buttons.Length)
{
currentIndex = 0;
return true;
}
else return false;
}
}
return false;
}
}
This is how it is utilized in the game. Note, this script is supposed to be attached to a gameobject.
using UnityEngine;
using System.Collections;
public class Test : MonoBehaviour {
private KeyCombo falconPunch= new KeyCombo(new string[] {"down", "right","right"});
private KeyCombo falconKick= new KeyCombo(new string[] {"down", "right","Fire1"});
void Update () {
if (falconPunch.Check())
{
// do the falcon punch
Debug.Log("PUNCH");
}
if (falconKick.Check())
{
// do the falcon punch
Debug.Log("KICK");
}
}
}
For those of you who develop for computer games. Using guitextures as buttons are generally used like this, or at least this is how I’ve found success.
using UnityEngine;
using System.Collections;
public class Guitextureimplementaion : MonoBehaviour {
public GUITexture attackButton; //assigned in the inspector
public GUITexture kickButton;//these are assigned in inspector
public GUITexture rollButton;//assigned in inspector
public bool roll;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(Input.touchCount > 0 )
{
for(int i = 0; i < Input.touchCount; i++)
{
Touch touch = Input.GetTouch(i);
if(touch.phase == TouchPhase.Ended attackButton.HitTest(touch.position))//if we hit the attack button
{
//example
Debug.Log ("you have hit the attackbutton guitexture on the screen");
}
}
}
SecondTouchimplementation ();
}
void SecondTouchimplementation(){
//with a charactercontroll on player, and roll being a boolean to execute a roll. if we hit the button when the player is grounded, roll will be true.
//foreach (Touch touch in Input.touches) {
// if (character.isGrounded touch.phase == TouchPhase.Began rollButton.HitTest (touch.position))
// roll = true;
//}
}
}
Finally, this is the closest I’ve gotten to implementing the keycomboscript. Instead of passing string variables as buttons, I’ve passed guitextures. Note that since the keycombo script can’t be place onto anobject on the scene(thus can’t be assigned in the inspector), the guitexture buttons had to be found by using getcomponent, and I made them static so they can be called on the usage script. Please note that while “touch” on line 38 isn’t used, touches on the whole screen are counted. Also, on line 49 I didn’t know how to implement it so I just edited it our for now.
using UnityEngine;
using System.Collections;
public class keycombo {
public GUITexture[] buttons;
//private Touch[] touch;
private int currentIndex = 0; //moves along the array as buttons are pressed
public static GUITexture attackButton;
public static GUITexture kickButton;
public float allowedTimeBetweenButtons = 0.3f; //tweak as needed
private float timeLastButtonPressed;
public keycombo(GUITexture[] b)
{
buttons = b;
}
void Awake(){
attackButton = GameObject.Find ("attackButton").GetComponent<GUITexture>();
kickButton = GameObject.Find ("kickButton").GetComponent<GUITexture> ();
}
void Update(){
Check ();
}
//usage: call this once a frame. when the combo has been completed, it will return true
public bool Check()
{
if (Time.time > timeLastButtonPressed + allowedTimeBetweenButtons) currentIndex = 0;
{foreach (Touch touch in Input.touches)
if (currentIndex < buttons.Length)
{
{
if ((buttons[currentIndex] == attackButton))// ||
// (buttons[currentIndex]== kickButton )))
//(buttons[currentIndex] != attackButton buttons[currentIndex] != kickButton Input.touches(buttons[currentIndex])))
// (buttons[currentIndex] != "down" buttons[currentIndex] != "up" buttons[currentIndex] != "left" buttons[currentIndex] != "right" Input.GetButtonDown(buttons[currentIndex])))
{
timeLastButtonPressed = Time.time;
currentIndex++;
}
if (currentIndex >= buttons.Length)
{
currentIndex = 0;
return true;
}
else return false;
}
}
}
return false;
}
}
This is how I’ve implemented the code. I’ve attached this to my player gameobject. The results are when I touch the screen, no matter where I touch it, The debug.log is posted, which is expected because there isn’t a hittest specified on the Keycombo script.
using UnityEngine;
using System.Collections;
public class combousage : MonoBehaviour {
private keycombo falconPunch = new keycombo(new GUITexture[] {keycombo.attackButton});
//private keycombo falconKick = new keycombo( new GUITexture[] {keycombo.kickButton, keycombo.kickButton});
void Awake(){
}
void Update () {
;
if (falconPunch.Check())
{
// do the falcon punch
Debug.Log("PUNCH");
}
//if (falconKick.Check())
//{
// do the falcon punch
// Debug.Log("KICK");
//}
}
}
if A hitest is added on the keycombo script on line 44 like posted below. Wherever the screen is touched it brings up a null reference.
if ((buttons[currentIndex] == attackButton (touch.phase == TouchPhase.Ended attackButton.HitTest(touch.position))))
I know this was a lot to read, so I just wanted to say thanks for reading this post. And thanks in advance for any and all help.