Bugger Off!

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. The genre of the game is strategy puzzle. In the game player, the gets to defend iconic locations and cities around the world from the giant 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: Scrum master, Animator, Support, Implementing audio
  • Team size: 5
  • Time frame: 4 months
  • Engine: Unity

Scrum Master

As the scrum master my main objective was to conduct the daily and weekly scrum sessions and making sure that every team member is on the same page at the current state of the project. By performing this role, I have a better understanding on how to interact better with the team members, identify possible bottlenecks, a greater understanding of the Agile process and principles and over all general improvement of my collaboration, conflict resolution and adaptability skills.

Animator

As the the main animator of the team i rigged the sprites from scratch, added inverse kinatics and created the animations. I also help implementing the animations so they would be triggered depending the state of the character using the animator. I also implemented spline animations to the centipede.

Tutorial Scene

One of the feedbacks we got from our testing sessions was that the UX had to be improved. Players had some troubles understanding the UI. Therefore we decided to create a tutorial scene for first time players. I was appointed to create such tutorial, having to access the programmers code without breaking anything using the the observer pattern and animations to direct the players attention.

Code Snippets

In the project i got to implement the sounds and the tutorial scene. Bellow are some of the code I wrote.

Listening for events being triggered

                      
                        
                            using UnityEngine;
                            public class ListeningToMouseClicks : MonoBehaviour
                            {
                                void Start()
                                {
                                    Levels.instance.OnSideBarMoveOut += _onMouseClick_OnSideBarMoveOut;
                                    Levels.instance.OnFrogIsSelected += Instance_OnFrogIsSelected;
                                    Placing.OnPlacing += Placing_OnPlacing;
                                }
            
                                private void Instance_OnFrogIsSelected(object sender, System.EventArgs e)
                                {
                                    TutorialManager.Instance.ContinueButtonpressed();
                                    TutorialAnimation.Instance.PlayTutorialAnimation();
            
                                    Levels.instance.OnFrogIsSelected -= Instance_OnFrogIsSelected;
                                    Placing.OnPlacing -= Placing_OnPlacing;
                                }
            
                                private void Placing_OnPlacing(FrogSM obj)
                                {
                                    TutorialManager.Instance.DisableTutorialPanel();
                                    TutorialManager.Instance.ContinueButtonpressed();
                                    TutorialAnimation.Instance.PlayTutorialAnimation();
                                }
            
                                private void _onMouseClick_OnSideBarMoveOut(object sender, System.EventArgs e)
                                {
                                    TutorialManager.Instance.ContinueButtonpressed();
                                    TutorialAnimation.Instance.PlayTutorialAnimation();
            
                                    Levels.instance.OnSideBarMoveOut -= _onMouseClick_OnSideBarMoveOut;
                                }
            
                                public void OnDisable()
                                {
                                    Levels.instance.OnSideBarMoveOut -= _onMouseClick_OnSideBarMoveOut;
                                    Levels.instance.OnFrogIsSelected -= Instance_OnFrogIsSelected;
                                    Placing.OnPlacing -= Placing_OnPlacing;
                                }
                            }
                        
                      

Triggering animations depending on the current state.

                      
                        
                          using UnityEngine;
                          public class TutorialAnimation : MonoBehaviour
                          {
                              public static TutorialAnimation Instance;
                              private Animator _tutorialAnimator;
                              [SerializeField]
                              private Animator _tutorialPanelAnimator;
                              [SerializeField]
                              private Animator _tutorialContinueButtonAnimator;
                          
                              private int _currentAnimation;
                              private static readonly int Property = Animator.StringToHash("01");
                              private static readonly int Property1 = Animator.StringToHash("02");
                              private static readonly int Property2 = Animator.StringToHash("03");
                              private static readonly int Property3 = Animator.StringToHash("04");
                              private static readonly int TutorialContinueBlinking = Animator.StringToHash("TutorialContinueBlinking");
                              private static readonly int Panel01 = Animator.StringToHash("Panel01");
                              private static readonly int Property4 = Animator.StringToHash("05");
                              private static readonly int Panel02 = Animator.StringToHash("Panel02");
                              private static readonly int Property5 = Animator.StringToHash("06");
                              private static readonly int Property6 = Animator.StringToHash("07");
                              private static readonly int Property7 = Animator.StringToHash("08");
                          
                              private void Awake()
                              {
                                  if (Instance != null && Instance != this)
                                  {
                                      Destroy(this);
                                  }
                                  else
                                  {
                                      Instance = this;
                                  }
                              }
                          
                              private void Start()
                              {
                                  _tutorialAnimator = GetComponent();        
                              }
                          
                              public void PlayTutorialAnimation()
                              {
                                  _currentAnimation++;
                                  switch (_currentAnimation)
                                  {
                                      case 1:
                                          return;
                                      case 2:
                                          _tutorialAnimator.SetBool(Property, true);
                                          break;
                                      case 3:
                                          _tutorialAnimator.SetBool(Property1, true);
                                          break;
                                      case 4:
                                          _tutorialAnimator.SetBool(Property2, true);
                                          break;
                                      case 5:
                                          _tutorialAnimator.SetBool(Property3, true);
                                          _tutorialContinueButtonAnimator.SetBool(TutorialContinueBlinking, true);
                                          break;
                                      case 6:
                                          _tutorialPanelAnimator.SetBool(Panel01, true);
                                          _tutorialAnimator.SetBool(Property4, true);
                                          _tutorialContinueButtonAnimator.SetBool(TutorialContinueBlinking, false);
                                          break;
                                      case 7:
                                          _tutorialContinueButtonAnimator.SetBool(TutorialContinueBlinking, true);
                                          break;
                                      case 8:
                                          _tutorialPanelAnimator.SetBool(Panel02, true);
                                          _tutorialContinueButtonAnimator.SetBool(TutorialContinueBlinking, false);
                                          break;
                                      case 9:
                                          _tutorialPanelAnimator.SetBool(Panel02, false);
                                          break;
                                      case 14:
                                          _tutorialContinueButtonAnimator.SetBool(TutorialContinueBlinking, true);
                                          _tutorialAnimator.SetBool(Property5, true);
                                          break;
                                      case 15:
                                          _tutorialAnimator.SetBool(Property6, true);
                                          break;
                                      case 16:
                                          _tutorialAnimator.SetBool(Property7, true);
                                          break;
                                  }
                              }
                          }
                        
                      

Playing the background music depending on the scene.

                      
                        
                          using System.Collections.Generic;
                          using UnityEngine;
                          using UnityEngine.SceneManagement;

                          public class BackgorundMusic : MonoBehaviour
                          {
                              [SerializeField]
                              private AudioSource _backgroundAudioSource;
                              [SerializeField]
                              private List _backgroundMusics;

                              private string _currentScene;

                              private void Start()
                              {
                                  GetCurrentSceneName();
                                  ChooseCurrentBackgroundMusic();
                              }

                              private void ChooseCurrentBackgroundMusic()
                              {
                                  switch (_currentScene)
                                  {
                                      case "MainMenu":
                                          _backgroundAudioSource.clip = _backgroundMusics[0];
                                          _backgroundAudioSource.Play();
                                          break;
                                      case "London":
                                          _backgroundAudioSource.clip = _backgroundMusics[1];
                                          _backgroundAudioSource.Play();
                                          break;
                                      case "Cairo":
                                          _backgroundAudioSource.clip = _backgroundMusics[2];
                                          _backgroundAudioSource.Play();
                                          break;
                                      case "Kyoto":
                                          _backgroundAudioSource.clip = _backgroundMusics[3];
                                          _backgroundAudioSource.Play();
                                          break;
                                      case "LondonTutorial":
                                          _backgroundAudioSource.clip = _backgroundMusics[1];
                                          _backgroundAudioSource.Play();
                                          break;
                                      default:
                                          _backgroundAudioSource.clip = _backgroundMusics[0];
                                          _backgroundAudioSource.Play();
                                          break;
                                  }
                              }

                              private void GetCurrentSceneName()
                              {
                                  _currentScene = SceneManager.GetActiveScene().name;
                              }
                          }

                        
                      

Triggering SFX depending on the frogs state change.

                      
                        
                          using UnityEngine;
                          public class PlayFrogSFX : MonoBehaviour
                          {
                              FrogSM sm;
                              private void Start()
                              {
                                  sm = GetComponent();
                                  sm.OnAgentState += Sm_OnAgentState1;        
                              }
                              private void Sm_OnAgentState1(object sender, StateMachine.OnAgentStateEventArgs e)
                              {
                                  if (e.agentState == sm.attackingState)
                                  {
                                      AudioClip _currentSfx = sm.currentFrogSO.attack;
                                      FrogsSFX.Instance.PlaySFX(_currentSfx, sm.currentFrogSO.frogName);
                                  }
                              }
                              public void OnFrogJumps()
                              {
                                  AudioClip _jumpingSFX = sm.currentFrogSO.jump;
                                  FrogsSFX.Instance.PlaySFX(_jumpingSFX, sm.currentFrogSO.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.