Wappidoo

Wappidoo is my third project during my internship at Mediaheads. Wappidoo is a game you play with a minimum of four players in two teams. A teammate swipes a number that will be subtracted at the end of the round, this varies from zero to three. You can also swipe a star or a question mark. The star is a multiplier that will double your score at the end of the round and the question mark will provide your team a question they have to answer. Within a given time the person with the phone must explain as many words as possible to his or her teammates to score points. The first team that achieves the maximum score is the winner.

Wappidoo is a game which was already developed by Mediaheads with Adobe Air. Together with three other trainees our task was to update and recreate the app in Unity. The parts of the game I developed were the tutorial and a Facebook plug-in. For the tutorial I had to create a swipe mechanic which was a challenge at first, but after asking some colleagues I managed to make it work. The Facebook plug-in was a lot more difficult. I never worked with Facebook before, therefor I had to follow some tutorials. The Facebook pug-in for Android was relatively easy to make. The Apple Facebook plug-in on the other hand, was a complex one. The standard plug-in was no longer supported by Apple and I had to remake this whole plug-in. After roughly four days I managed to get the plug-in working on Apple as well. Both the Apple and Android plug-in let the player like the Wappidoo Facebook page and/or share the Wappidoo Facebook page.

I really enjoyed working on this project because I got to develop parts of a game I had never made before. I’m mostly fond of the Facebook plug-in I created for both Android and Apple. By carrying on I managed to complete a complex task and learned that challenging work will always be rewarded and those who keep going will always persevere.

Wappidoo can be downloaded on Android and on IOS.

*These are just some of the scripts I created for this project, I cannot post all of them.*

FacebookManager.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Facebook.Unity; public class FacebookManager : MonoBehaviour { private bool leftApp = false; private string linkToShare; private void Awake() { if (!FB.IsInitialized) { FB.Init(); } else { FB.ActivateApp(); } SetLinkToShare(); } void OnApplicationPause() { leftApp = true; } /// <summary> /// share a specific link with facebook. the app opens facebook and will automaticly start a new post with the link already present. /// </summary> public void Share() { #if (UNITY_IOS) Application.OpenURL("https://www.facebook.com/sharer/sharer.php?u=https%3A//www.facebook.com/Wappidoo"); #endif #if (UNITY_ANDROID) FB.ShareLink( contentURL: new System.Uri(linkToShare), //contentTitle: "Wappidoo made by Mediaheads", //contentDescription: "Here's a link to the Wappidoo Facebook page", callback: OnShare); #endif } /// <summary> /// open a specific page on the facebook app to like. /// </summary> public void Like() { #if (UNITY_IOS) //StartCoroutine(IOSOpenFacebookPage()); Application.OpenURL("https://www.facebook.com/Wappidoo"); #endif #if (UNITY_ANDROID) if (checkPackageAppIsPresent("com.facebook.katana")) { Application.OpenURL("fb://page/180749185397246"); //there is Facebook app installed so let's use it } else { Application.OpenURL("https://www.facebook.com/Wappidoo/"); // no Facebook app - use built-in web browser } #endif } private void SetLinkToShare() { #if (UNITY_IOS) linkToShare = "https://itunes.apple.com/nl/app/wappidoo/id573543640?mt=8"; #endif #if (UNITY_ANDROID) linkToShare = "https://play.google.com/store/apps/details?id=air.WappidooFree"; #endif } /// <summary> /// handles if the share is succesfull or if the user canceld the share. /// </summary> /// <param name="result"></param> private void OnShare(IShareResult result) { if (result.Cancelled || !string.IsNullOrEmpty(result.Error)) { Debug.Log("ShareLink error: " + result.Error); } else if (!string.IsNullOrEmpty(result.PostId)) { Debug.Log(result.PostId); } else { Debug.Log("Share success"); } } /// <summary> /// a check if a specific app is installed on an Android device. /// </summary> /// <param name="package"></param> /// <returns></returns> private bool checkPackageAppIsPresent(string package) { AndroidJavaClass up = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject ca = up.GetStatic<AndroidJavaObject>("currentActivity"); AndroidJavaObject packageManager = ca.Call<AndroidJavaObject>("getPackageManager"); //take the list of all packages on the device AndroidJavaObject appList = packageManager.Call<AndroidJavaObject>("getInstalledPackages", 0); int num = appList.Call<int>("size"); for (int i = 0; i < num; i++) { AndroidJavaObject appInfo = appList.Call<AndroidJavaObject>("get", i); string packageNew = appInfo.Get<string>("packageName"); if (packageNew.CompareTo(package) == 0) { return true; } } return false; } IEnumerator IOSOpenFacebookPage() { Application.OpenURL("fb://page/180749185397246"); yield return new WaitForSeconds(1.5f); if (leftApp) { leftApp = false; } else { Application.OpenURL("https://www.facebook.com/Wappidoo/"); } } }
SwipeManager.cs
using UnityEngine; using System.Collections; /// <summary> /// Sends messages to other MonoBehaviour scripts on the same object. /// The possible messages are as follows: /// - "RightMinTriggered" /// - "RightMaxTriggered" /// - "LeftMinTriggered" /// - "LeftMaxTriggered" /// - "UpMinTriggered" /// - "UpMaxTriggered" /// - "DownMinTriggered" /// - "DownMaxTriggered" /// - "HorizontalReset" /// - "VerticalReset" /// </summary> public class SwipeManager : MonoBehaviour { [SerializeField] private bool useRelativeDistance; [SerializeField] private float horizontalMinDistanceRelative; [SerializeField] private float horizontalMaxDistanceRelative; [SerializeField] private float verticalMinDistanceRelative; [SerializeField] private float verticalMaxDistanceRelative; [Space] [SerializeField] private float horizontalMinDistance; [SerializeField] private float horizontalMaxDistance; [SerializeField] private float verticalMinDistance; [SerializeField] private float verticalMaxDistance; public float HorizontalMinDistance { get { return horizontalMinDistance; } } public float HorizontalMaxDistance { get { return horizontalMaxDistance; } } public float VerticalMinDistance { get { return verticalMinDistance; } } public float VerticalMaxDistance { get { return verticalMaxDistance; } } private bool isDown; private bool minTriggeredHorizontal; private bool minTriggeredVertical; private bool positiveTriggered; private Vector3 startPos; [HideInInspector] public bool CanTrigger = true; public bool MinTriggeredHorizontal { get { return minTriggeredHorizontal; } } public bool MinTriggeredVertical { get { return minTriggeredVertical; } } public bool IsDown { get { return isDown; } } public bool PositiveTriggered { get { return positiveTriggered; } } public Vector3 StartPos { get { return startPos; } } private void Start() { if (useRelativeDistance) { horizontalMinDistance = Screen.width * horizontalMinDistanceRelative; horizontalMaxDistance = Screen.width * horizontalMaxDistanceRelative; verticalMinDistance = Screen.width * verticalMinDistanceRelative; verticalMaxDistance = Screen.width * verticalMaxDistanceRelative; } } private void TriggerDelay() { CanTrigger = true; } private void Update() { if (CanTrigger) { if (Input.GetMouseButton(0)) { if (!isDown) { // Touch has started isDown = true; startPos = Input.mousePosition; //this.SendMessage("PositionOnTouch"); Debug.Log("Houston, we have landed"); } } else { if (isDown) { isDown = false; // If touch is released while X was between min and max if (minTriggeredHorizontal) { minTriggeredHorizontal = false; this.SendMessage("HorizontalReset"); Debug.Log("HorizontalReset"); } // If touch is released while Y was between min and max else if (minTriggeredVertical) { minTriggeredVertical = false; //this.SendMessage("VerticalReset"); Debug.Log("VerticalReset"); } else { Debug.Log("Mouse Up"); } } } if (isDown) { if (minTriggeredHorizontal) { if (positiveTriggered) { // Touch X has reached the right trigger if (Input.mousePosition.x - startPos.x > horizontalMaxDistance) { isDown = false; CanTrigger = false; minTriggeredHorizontal = false; this.SendMessage("RightMaxTriggered"); Debug.Log("RightMaxTriggered, " + (Input.mousePosition.x - startPos.x)); } // Touch X has gone back below minimum else if (Input.mousePosition.x - startPos.x < horizontalMinDistance) { if (minTriggeredHorizontal) { minTriggeredHorizontal = false; this.SendMessage("HorizontalReset"); Debug.Log("HorizontalReset"); } } } else { // Touch X has reached the left trigger if (Input.mousePosition.x - startPos.x < -horizontalMaxDistance) { isDown = false; CanTrigger = false; minTriggeredHorizontal = false; this.SendMessage("LeftMaxTriggered"); Debug.Log("LeftMaxTriggered"); } // Touch X has gone back below minimum else if (Input.mousePosition.x - startPos.x > -horizontalMinDistance) { if (minTriggeredHorizontal) { minTriggeredHorizontal = false; this.SendMessage("HorizontalReset"); Debug.Log("HorizontalReset"); } } } } else if (minTriggeredVertical) { if (positiveTriggered) { // Touch Y has reached the up trigger if (Input.mousePosition.y - startPos.y > verticalMaxDistance) { isDown = false; CanTrigger = false; minTriggeredVertical = false; //this.SendMessage("UpMaxTriggered"); Debug.Log("UpMaxTriggered"); } // Touch Y has gone back below minimum else if (Input.mousePosition.y - startPos.y < verticalMinDistance) { if (minTriggeredVertical) { minTriggeredVertical = false; //this.SendMessage("VerticalReset"); Debug.Log("VerticalReset"); } } } else { // Touch Y has reached the down trigger if (Input.mousePosition.y - startPos.y < -verticalMaxDistance) { isDown = false; CanTrigger = false; minTriggeredVertical = false; //this.SendMessage("DownMaxTriggered"); Debug.Log("DownMaxTriggered"); } // Touch Y has gone back below minimum else if (Input.mousePosition.y - startPos.y > -verticalMinDistance) { if (minTriggeredVertical) { minTriggeredVertical = false; //this.SendMessage("VerticalReset"); Debug.Log("VerticalReset"); } } } } else { // Touch X has reached the minimum right trigger if (Input.mousePosition.x - startPos.x > horizontalMinDistance) { minTriggeredHorizontal = true; positiveTriggered = true; this.SendMessage("RightMinTriggered"); Debug.Log("RightMinTriggered"); } // Touch X has reached the minimum left trigger else if (Input.mousePosition.x - startPos.x < -horizontalMinDistance) { minTriggeredHorizontal = true; positiveTriggered = false; this.SendMessage("LeftMinTriggered"); Debug.Log("LeftMinTriggered"); } // Touch Y has reached the minimum up trigger else if (Input.mousePosition.y - startPos.y > verticalMinDistance) { minTriggeredVertical = true; positiveTriggered = true; //this.SendMessage("UpMinTriggered"); Debug.Log("UpMinTriggered"); } // Touch Y has reached the minimum down trigger else if (Input.mousePosition.y - startPos.y < -verticalMinDistance) { minTriggeredVertical = true; positiveTriggered = false; //this.SendMessage("DownMinTriggered"); Debug.Log("DownMinTriggered"); } } } } else { if (Input.GetMouseButtonUp(0)) { CanTrigger = true; } } } }
HelpPanelSlider.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class HelpPanelSlider : MonoBehaviour { public GameObject helpCanvas; public int panelInRow; public int panelCount; [SerializeField] private GameObject[] panels; private SwipeManager swipeManager; private RectTransform rect; private PageIndicator pageIndicatorScript; private float canvasWidth; private bool isMaxTransitioning; private bool isMinTransitioning; private bool isResetting; private bool areReferencesSet = false; // Use this for initialization void Start () { RectTransform canvasRectTransform = helpCanvas.GetComponent<RectTransform>(); canvasWidth = canvasRectTransform.rect.width; rect = this.GetComponent<RectTransform>(); panelCount = panelCount - 1; pageIndicatorScript = helpCanvas.gameObject.GetComponent<PageIndicator>(); swipeManager = this.GetComponent<SwipeManager>(); areReferencesSet = true; } // Update is called once per frame void Update () { //if true we want the panel to follow the position op the mouse or finger in the direction it moves. if (isMinTransitioning) { if (swipeManager.PositiveTriggered) { rect.anchoredPosition = new Vector2(-(canvasWidth * panelInRow) + Input.mousePosition.x - swipeManager.StartPos.x - swipeManager.HorizontalMinDistance, rect.anchoredPosition.y); } else { rect.anchoredPosition = new Vector2(-(canvasWidth * panelInRow) + Input.mousePosition.x - swipeManager.StartPos.x + swipeManager.HorizontalMinDistance, rect.anchoredPosition.y); } } //if the max trigger is reached we want the panel to move completely to the next location. else if (isMaxTransitioning) { rect.anchoredPosition = new Vector2(Mathf.Lerp(rect.anchoredPosition.x, -(canvasWidth * panelInRow), 0.15f), rect.anchoredPosition.y); } //resetting the position the the original position of the panel before the min trigger was reached. else if (isResetting) { rect.anchoredPosition = new Vector2(Mathf.Lerp(rect.anchoredPosition.x, -(canvasWidth * panelInRow), 0.10f), rect.anchoredPosition.y); } } /// <summary> /// if the min trigger on the right has been reached and the panels are not moving to a whole new location, we want to start following the touch position. /// </summary> public void RightMinTriggered() { isResetting = false; CancelInvoke("StopResetting"); if (!isMaxTransitioning) { isMinTransitioning = true; } } /// <summary> /// if the min trigger on the left has been reached and the panels are not moving to a whole new location, we want to start following the touch position. /// </summary> public void LeftMinTriggered() { isResetting = false; CancelInvoke("StopResetting"); if (!isMaxTransitioning) { isMinTransitioning = true; } } /// <summary> /// if the max trigger is reached on the left we want to start moving the panels to the next position /// </summary> public void LeftMaxTriggered() { isMinTransitioning = false; if (panelInRow <= panelCount) { isResetting = false; CancelInvoke("StopTransition"); panelInRow++; //PositionToMove = -(canvasWidth * panelInRow); isMaxTransitioning = true; Invoke("StopTransition", 0.6f); pageIndicatorScript.SetPageIndicatorPlus(); } else { isResetting = true; Debug.LogWarning("panel cant move more to the left"); } } /// <summary> /// if the max trigger is reached on the right we want to start moving the panels to the next position /// </summary> public void RightMaxTriggered() { isMinTransitioning = false; if (panelInRow >= 1) { isResetting = false; CancelInvoke("StopTransition"); panelInRow--; //PositionToMove = -(canvasWidth * panelInRow); isMaxTransitioning = true; Invoke("StopTransition", 0.6f); pageIndicatorScript.SetPageIndicatorMin(); } else { isResetting = true; Debug.LogWarning("panel cant move more to the right"); } } /// <summary> /// Set the location of the panels to its destination, so the Lerp won't go on for to long. /// </summary> public void StopTransition() { isMaxTransitioning = false; rect.anchoredPosition = new Vector2(-(canvasWidth * panelInRow), rect.anchoredPosition.y); } /// <summary> /// start the reseting of the panels back to its location before the min trigger was reached. /// </summary> public void HorizontalReset() { isMinTransitioning = false; isResetting = true; Invoke("StopResetting",1f); } /// <summary> /// Set the location back to the position in needs to reach for the reset so the Lerp won't go on for to long. /// </summary> public void StopResetting() { isResetting = false; rect.anchoredPosition = new Vector2(-(canvasWidth * panelInRow), rect.anchoredPosition.y); } /// <summary> /// reset the position of all the panels back to where they started. also resetting the pageIndicators to show we are at page one again. /// </summary> public void ResetPanelCount() { if (!areReferencesSet) { Start(); } panelInRow = 0; rect.anchoredPosition = new Vector2(0, rect.anchoredPosition.y); pageIndicatorScript.SetPageIndicatorZero(); } /// <summary> /// Activate all the panels /// </summary> public void ActivatePanels() { for (int i = 0; i < panels.Length; i++) { panels[i].SetActive(true); } } /// <summary> /// Deactivate all panels /// </summary> public void DeactivatePanels() { for (int i = 0; i < panels.Length; i++) { if (i == panelInRow) { panels[i].SetActive(true); } else { panels[i].SetActive(false); } } } }