Bugger Off! -Mobile-

The mobile version of Bugger Off!. More frogs, more bugs, more maps, UI optimized for mobile devices. Bugger off! is a tower defence game in a world where huge bugs are invading humanity and huge frogs are trained to exterminate these bugs. With the help of the frogs, save iconic cities from the invasion of bugs!!

The game emphasizes a charming and visually pleasing aesthetic with bright colours, endearing character designs, and recognizable landmarks from four distinct real-world locatiomons. Each level is meticulously designed to reflect the unique characteristics of its corresponding real-world location. This not only provides visual diversity but also introduces specific challenges tied to the environment.

My contributions

Project Info

  • My roles: Animator, UI/Ux design and implementation, Audio Implementation, Support
  • Team size: 5
  • Time frame: 4 months
  • Engine: Unity

Animator

My main main role in the team. Once I received the sprites from the artist, I rigged them and animate them according to the vision of the artist and designer. Once all the animations are completed I implemented the logic in the animator which then are triggered by the behavioral tree. In this role I had constant communication with the aertist, designers and programmers.

UI Designer

As the UI designer I created visual aids for the team members to understand better the structure and flow of the different screens and buttons. This provided a better idea of the flow of the game and made the implementation of the UI easier and faster.

Shaders and particle effects

For the project i also created some shaders and implemented some particles and post processing effects for the weather scenes.

Code Snippets

In the project I got to implement the sounds and some of the UI. The background music and SFX are being played in different channels that the player can conrol.

Controlling the background music depending on the selected scene.

                      
                        
                          public class BackgroundMusicController : MonoBehaviour
                          {
                              [SerializeField] AudioClip[] _backgroundMusic;
                          
                              private AudioSource _audioSource;
                              [SerializeField] public AudioMixer _audioMixer;
                          
                              private void Start()
                              {
                                  _audioSource = GetComponent();
                                  _audioSource.clip = GetSceneBackgroundMusic();
                                  _audioSource.Play();
                                  if (_audioMixer != null)
                                  {
                                      _audioMixer.SetFloat("BackgroundMusic", Mathf.Log10(PlayerPrefs.GetFloat("BackgroundMusic")) * 20);
                                      _audioMixer.SetFloat("Sfx", Mathf.Log10(PlayerPrefs.GetFloat("Sfx")) * 20);
                                  }        
                              }
                          
                              private AudioClip GetSceneBackgroundMusic()
                              {
                                  string sceneName = SceneManager.GetActiveScene().name;
                                  Debug.Log("Scene name int: " + sceneName);
                          
                                  int scene = 0;
                                  if (sceneName.Contains("London"))
                                  {
                                      scene = 1;
                                  }
                                  else if (sceneName.Contains("Cairo"))
                                  {
                                      scene = 2;
                                  }
                                  else if (sceneName.Contains("Kyoto"))
                                  {
                                      scene = 3;
                                  }
                                  else if (sceneName.Contains("World"))
                                  {
                                      scene = 4;
                                  }
                                          
                                  switch (scene)
                                  {
                                      case 0:
                                          return _backgroundMusic[0];
                                      case 1:
                                          return _backgroundMusic[1];
                                      case 2:
                                          return _backgroundMusic[2];
                                      case 3:
                                          return _backgroundMusic[3];
                                      case 4:
                                          return _backgroundMusic[4];
                                      default:
                                          return _backgroundMusic[_backgroundMusic.Length - 1];      
                                  }
                              }
                          }
                        
                      

Setting up the frog's information depending on what is selected.

                      
                        
                          public class FrogSelectionUI : MonoBehaviour, IPointerDownHandler
                          {
                              private FrogSO _frogSO;
                              private GameObject _frogWheel;
                              private GameObject _description;

                              FrogChangeSelection _frogChangeSelection;

                              private void Start()
                              {
                                  _frogChangeSelection = transform.parent.parent.parent.GetComponent();
                                  print(gameObject.name);
                              }
                              public void OnPointerDown(PointerEventData eventData)
                              {
                                  if(ChangeFrogUIManager.Instance.frogWheelSelection != null)
                                  {
                                      ChangeFrogUIManager.Instance.frogWheelSelection.frogSO = _frogSO;
                                      ChangeFrogUIManager.Instance.frogWheelSelection.ChangeInfo?.Invoke();
                                  }
                                  SetFrogTitle();
                                  SetFrogPrice();
                                  SetFrogStats();
                                  SetFrogDescription();
                                  _frogChangeSelection.OnFrogSelected(gameObject);
                              }

                              private void SetFrogDescription()
                              {
                                  _description.transform.GetChild(2).GetComponent().text = _frogSO.visualSO.userInterface.UIShopTextInfo;
                              }

                              private void SetFrogStats()
                              {
                                  GameObject[] stats = new GameObject[_description.transform.GetChild(1).childCount];

                                  for (int i = 0; i < stats.Length; i++)
                                  {
                                      stats[i] = _description.transform.GetChild(1).GetChild(i).gameObject;
                                  }

                                  stats[0].transform.GetChild(1).GetComponent().text = _frogSO.logicSO.discipline.ToString();
                                  stats[1].transform.GetChild(1).GetComponent().text = _frogSO.logicSO.damage.ToString();
                                  stats[2].transform.GetChild(1).GetComponent().text = _frogSO.logicSO.range.ToString();
                                  stats[3].transform.GetChild(1).GetComponent().text = _frogSO.logicSO.attackSpeed.ToString();
                              }

                              private void SetFrogPrice() 
                              {
                                  _description.transform.GetChild(0).GetChild(1).GetComponent().text = _frogSO.logicSO.cost.ToString();
                              }

                              public void SetFrogSO(FrogSO frogSO)
                              {
                                _frogSO = frogSO;
                              }

                              public void SetFrogWheel(GameObject frogWheel)
                              {
                                  _frogWheel = frogWheel;
                                  _description = frogWheel.transform.GetChild(0).GetChild(1).gameObject;
                              }

                              private void SetFrogTitle()
                              {
                                  _frogWheel.transform.GetChild(0).GetChild(0).GetComponent().text = _frogSO.logicSO.frogName;
                              }
                          }
                        
                      

Say Hello!

If you want to know more about me, my work or contact me, bellow are the main channels i use.

  • Linkedin icon with link to Santiago Sala's linkedin page.
  • GitHub icon with link to Santiago Sala's GitHub profile.
  • Youtube icon with link to Santiago Sala's Youtube page.