383 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			383 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections;
 | |
| using System.Collections.Generic;
 | |
| using Unity.XR.CoreUtils;
 | |
| using UnityEngine;
 | |
| using UnityEngine.InputSystem;
 | |
| using UnityEngine.InputSystem.LowLevel;
 | |
| using UnityEngine.UI;
 | |
| 
 | |
| public class Menu : MonoBehaviour
 | |
| {
 | |
|     public GameObject MenuRotator;
 | |
|     public GameObject Floor1Panel;
 | |
|     public GameObject Floor2Panel;
 | |
|     public FloorButtonVisualizer Floor1Button;
 | |
|     public FloorButtonVisualizer Floor2Button;
 | |
|     public Camera Camera;
 | |
|     public Image PlayericonFloor1;
 | |
|     public Image PlayericonFloor2;
 | |
|     public GameObject PlayericonFloor1Parent;
 | |
|     public GameObject PlayericonFloor2Parent;
 | |
| 
 | |
|     public XROrigin Player;
 | |
|     public InputActionReference openMenuAction;
 | |
|     private Canvas canvas;
 | |
| 
 | |
|     public enum MenuTab
 | |
|         {
 | |
|             Map,
 | |
|             Options,
 | |
|             Credits
 | |
|         }
 | |
| 
 | |
|     public GameObject MapTab;
 | |
|     public GameObject OptionsTab;
 | |
|     public GameObject CreditsTab;
 | |
|     
 | |
|     private MenuTab currentTab;
 | |
| 
 | |
| 
 | |
|     public Button mapBookmark;
 | |
|     public Button optionsBookmark;
 | |
|     public Button creditsBookmark;
 | |
| 
 | |
|     // Values for setting the position of the player marker. Do not touch them without great cause.
 | |
|     private Vector2 rotatedPlayerPos = new Vector2();
 | |
|     private float worldToMapAngle = 130.0f;
 | |
|     private Vector2 VR_P1 = new Vector2(-77.4f, 10.1f); // - 71.2f (alumine punkt)
 | |
|     private Vector2 VR_P2 = new Vector2(95.7f, -82.8f);
 | |
|     private Vector2 IMG_P1 = new Vector2(-387.2f, 193.1f); // 
 | |
|     private Vector2 IMG_P2 = new Vector2(389.7f, -221.4f); // 
 | |
| 
 | |
|     protected static float cameraToMapIconRotationOffset = -50;
 | |
|     private float floor2UpperLimit = 9;
 | |
|     private float floorsMidpointLimit = 2.5f;
 | |
|     private float floor1LowerLimit = -5;
 | |
|     private bool activated = true;
 | |
| 
 | |
| 
 | |
|     private bool hasFloorButtonSoundInitialized = false;
 | |
|     private bool hasMapButtonSoundInitialized = false;
 | |
|     
 | |
| 
 | |
|     private void Awake()
 | |
|     {
 | |
|         openMenuAction.action.Enable();
 | |
|         openMenuAction.action.performed += ToggleMenu;
 | |
|         InputSystem.onDeviceChange += OnDeviceChange;
 | |
|         canvas = GetComponent<Canvas>();
 | |
|         setCanvasVisibility(false);
 | |
| 
 | |
|         mapBookmark.onClick.AddListener(activateMapPanel);
 | |
|         optionsBookmark.onClick.AddListener(activateOptionsPanel);
 | |
|         creditsBookmark.onClick.AddListener(activateCreditsPanel);
 | |
|         activateMapPanel();
 | |
|         
 | |
|     }
 | |
|     public void DeactivateMenu() // Makes the ToggleMenu inable to toggle.
 | |
|     {
 | |
|         canvas.enabled = false;
 | |
|         activated = false;
 | |
|     }
 | |
|     public void ReactivateMenu() // Makes the ToggleMenu able to toggle again.
 | |
|     {
 | |
|         activated = true;
 | |
|     }
 | |
| 
 | |
|     private void activateMapPanel()
 | |
|     {
 | |
|         if (hasMapButtonSoundInitialized)  //if statement to check if the button sound instance was initiated in the beginning, thie applies to Map and Floor click sounds.
 | |
|             AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Click, gameObject);
 | |
|         else
 | |
|             hasMapButtonSoundInitialized = true;
 | |
| 
 | |
|         SetActiveTab(MenuTab.Map);
 | |
|     }
 | |
| 
 | |
|     private void activateOptionsPanel()
 | |
|     {
 | |
|         SetActiveTab(MenuTab.Options);
 | |
|         AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Click, gameObject);  //3d oneshot sound
 | |
|     }
 | |
| 
 | |
|     private void activateCreditsPanel()
 | |
|     {
 | |
|         SetActiveTab(MenuTab.Credits);
 | |
|         AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Click, gameObject);  //3d oneshot sound
 | |
|     }
 | |
| 
 | |
|     private void SetActiveTab(MenuTab tab)
 | |
|     {
 | |
|         currentTab = tab;
 | |
| 
 | |
|         MapTab.SetActive(tab == MenuTab.Map);
 | |
|         OptionsTab.SetActive(tab == MenuTab.Options);
 | |
|         CreditsTab.SetActive(tab == MenuTab.Credits);
 | |
| 
 | |
|         mapBookmark.GetComponent<HoverSlideButton>().SetOnState(tab == MenuTab.Map);
 | |
|         optionsBookmark.GetComponent<HoverSlideButton>().SetOnState(tab == MenuTab.Options);
 | |
|         creditsBookmark.GetComponent<HoverSlideButton>().SetOnState(tab == MenuTab.Credits);
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public void setCanvasVisibility(bool enabled)
 | |
|     {
 | |
|         canvas.enabled = enabled;
 | |
|     }
 | |
| 
 | |
|     private void ToggleMenu(InputAction.CallbackContext context)
 | |
|     {
 | |
|         if (!activated) return;
 | |
|         
 | |
|         updateMenuTransform();
 | |
| 
 | |
|         // Toggle the menu visibility
 | |
|         setCanvasVisibility(!canvas.enabled);
 | |
| 
 | |
|         AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.MapOpen, gameObject);
 | |
|     }
 | |
| 
 | |
|     public Transform updateMenuTransform()
 | |
|     {
 | |
|         // Gets the transform of the menu Updates the transform along the way
 | |
|         // Does not enable its visibility.
 | |
| 
 | |
| 
 | |
|         // Get the camera's local Y rotation relative to the parent of MenuRotator
 | |
|         float relativeYRotation = Camera.transform.localEulerAngles.y;
 | |
|         // Apply the relative Y rotation to MenuRotator while keeping X and Z unchanged
 | |
|         MenuRotator.transform.localEulerAngles = new Vector3(0, relativeYRotation, 0);
 | |
| 
 | |
|         // Set the menu position to match the camera's position in local space
 | |
|         MenuRotator.transform.position = Camera.transform.position;     
 | |
| 
 | |
|         return this.transform;
 | |
| 
 | |
|     }
 | |
| 
 | |
|     // Start is called before the first frame update
 | |
|     void Start()
 | |
|     {
 | |
|         Floor1Button.GetComponent<Button>().onClick.AddListener(DisplayFloor1);
 | |
|         Floor2Button.GetComponent<Button>().onClick.AddListener(DisplayFloor2);
 | |
|         DisplayFloor2();
 | |
|     }
 | |
|     private void DisplayFloor1()
 | |
|     {
 | |
|         AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Click, gameObject);  //3d oneshot sound
 | |
|         //Debug.Log("Dispaling floor 1");
 | |
|         Floor1Panel.gameObject.SetActive(true);
 | |
|         Floor2Panel.gameObject.SetActive(false);
 | |
| 
 | |
|         Button buttonComponent = Floor1Button.GetComponent<Button>();
 | |
| 
 | |
|         // Refresh the state of the button.
 | |
|         buttonComponent.interactable = false;
 | |
|         buttonComponent.interactable = true;
 | |
|     }
 | |
|     private void DisplayFloor2()
 | |
|     {   
 | |
| 
 | |
|     
 | |
|         if (hasFloorButtonSoundInitialized)
 | |
|             AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Click, gameObject);
 | |
|         else
 | |
|             hasFloorButtonSoundInitialized = true;
 | |
| 
 | |
|         //Debug.Log("Dispaling floor 2");
 | |
|         Floor1Panel.gameObject.SetActive(false);
 | |
|         Floor2Panel.gameObject.SetActive(true);
 | |
| 
 | |
|         Button buttonComponent = Floor2Button.GetComponent<Button>();
 | |
| 
 | |
|         // Refresh the state of the button.
 | |
|         buttonComponent.interactable = false;
 | |
|         buttonComponent.interactable = true;
 | |
|     }
 | |
|     private int DeterminePlayerCurrentFloor()
 | |
|     {
 | |
|         float yPos = gameObject.transform.position.y;
 | |
|         if (yPos > floorsMidpointLimit && yPos < floor2UpperLimit) // Floor 2
 | |
|         {
 | |
|             return 2;
 | |
|         }
 | |
|         if (yPos > floor1LowerLimit && yPos <= floorsMidpointLimit) // Floor 1
 | |
|         {
 | |
|             return 1;
 | |
|         }
 | |
|         return -1; // If the player should not be on the map
 | |
|     }
 | |
| 
 | |
|     private void OnDeviceChange(InputDevice device, InputDeviceChange change) // To avoid bugs with controllers disconnecting.
 | |
|     {
 | |
|         switch (change)
 | |
|         {
 | |
|             case InputDeviceChange.Disconnected:
 | |
|                 openMenuAction.action.Disable();
 | |
|                 openMenuAction.action.performed -= ToggleMenu;
 | |
|                 break;
 | |
|             case InputDeviceChange.Reconnected:
 | |
|                 openMenuAction.action.Enable();
 | |
|                 openMenuAction.action.performed += ToggleMenu;
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     // Update is called once per frame
 | |
|     void Update()
 | |
|     {
 | |
|         if (transform.position.y < -50) // If the player has fallen off the platform.
 | |
|         {
 | |
|             if (!canvas.enabled) // If has menu not activated.
 | |
|             {
 | |
|                 ToggleMenu(new InputAction.CallbackContext()); // Activate menu.
 | |
|             }
 | |
|         }
 | |
|         if (MapTab.activeSelf) 
 | |
|         { 
 | |
|             UpdatePlayerIconPosition();
 | |
|             UpdatePlayerIconRotation();
 | |
|             UpdateActveFloor();
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
|     }
 | |
|     private void UpdatePlayerIconRotation()
 | |
|     {
 | |
|         float cameraRotationY = -Camera.transform.eulerAngles.y;
 | |
|         float iconRotation = cameraRotationY + cameraToMapIconRotationOffset;
 | |
|         if (PlayericonFloor1Parent.activeSelf)
 | |
|         {
 | |
|             PlayericonFloor1.transform.rotation = Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y, iconRotation);
 | |
|         }
 | |
|         if (PlayericonFloor2Parent.activeSelf)
 | |
|         {
 | |
|             PlayericonFloor2.transform.rotation = Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y, iconRotation);
 | |
|         }
 | |
|     }
 | |
|     private void UpdateActveFloor()
 | |
|     {
 | |
|         int playerCurrentFloor = DeterminePlayerCurrentFloor();
 | |
|         //Debug.Log("Player current floor is " + playerCurrentFloor);
 | |
|         switch (playerCurrentFloor)
 | |
|         {
 | |
|             case 1:
 | |
|                 if (!Floor1Button.ActiveState)
 | |
|                 {
 | |
|                     //Debug.Log("Activating floor 1 Button.");
 | |
|                     Floor1Button.Activate();
 | |
|                     Floor2Button.Deactivate();
 | |
|                 }
 | |
|                 if (!PlayericonFloor1Parent.activeSelf)
 | |
|                 {
 | |
|                     PlayericonFloor1Parent.SetActive(true);
 | |
|                     PlayericonFloor2Parent.SetActive(false);
 | |
|                 }
 | |
|                 break;
 | |
|             case 2:
 | |
|                 if (!Floor2Button.ActiveState)
 | |
|                 {
 | |
|                     //Debug.Log("Activating floor 2 Button.");
 | |
|                     Floor1Button.Deactivate();
 | |
|                     Floor2Button.Activate();
 | |
|                 }
 | |
|                 if (!PlayericonFloor2Parent.activeSelf)
 | |
|                 {
 | |
|                     Debug.Log("PlayericonFloor2Parent is inactive");
 | |
|                     PlayericonFloor1Parent.SetActive(false);
 | |
|                     PlayericonFloor2Parent.SetActive(true);
 | |
|                     Debug.Log(PlayericonFloor2Parent.activeSelf);
 | |
|                 }
 | |
|                 break;
 | |
|             default:
 | |
|                 if (PlayericonFloor1Parent.activeSelf || PlayericonFloor2Parent.activeSelf) 
 | |
|                 {
 | |
|                     //Debug.Log("Deactivating floor Buttons.");
 | |
|                     Floor1Button.Deactivate();
 | |
|                     Floor2Button.Deactivate();
 | |
|                 }
 | |
|                 if (PlayericonFloor1.enabled || PlayericonFloor2.enabled)
 | |
|                 {
 | |
|                     PlayericonFloor1Parent.SetActive(false);
 | |
|                     PlayericonFloor2Parent.SetActive(false);
 | |
|                 }
 | |
|                 break;
 | |
| 
 | |
|         }
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     private void UpdatePlayerIconPosition()
 | |
|     {
 | |
|         float worldToMapAngleRad = worldToMapAngle * Mathf.Deg2Rad;
 | |
| 
 | |
|         //Vector2 VR_Player = new Vector2(transform.position.x, transform.position.z);
 | |
|         Vector2 VR_Player = new Vector2(
 | |
|             Mathf.Cos(worldToMapAngleRad) * transform.position.x - Mathf.Sin(worldToMapAngleRad) * transform.position.z,
 | |
|             Mathf.Sin(worldToMapAngleRad) * transform.position.x + Mathf.Cos(worldToMapAngleRad) * transform.position.z
 | |
|         );
 | |
| 
 | |
|         VR_Player = VR_Player * new Vector2(1.0f, 1.0f);
 | |
| 
 | |
|         rotatedPlayerPos = VR_Player;
 | |
|         //Debug.Log(VR_Player);
 | |
| 
 | |
|         //Vector2 VR_P1 = new Vector2(-10, 102);
 | |
|         //Vector2 VR_P2 = new Vector2(-123, -19);
 | |
| 
 | |
|         /*Vector2 VR_P1 = new Vector2(-102.0f, 73.0f);
 | |
|         Vector2 VR_P2 = new Vector2(71.1f, 76.6f);
 | |
|         
 | |
| 
 | |
|         Vector2 IMG_P1 = new Vector2(-364.0f, -180.0f);
 | |
|         Vector2 IMG_P2 = new Vector2(394.0f, -225.0f);*/
 | |
| 
 | |
|         Vector2 VR_L = VR_P2 - VR_P1;
 | |
|         Vector2 IMG_L = IMG_P2 - IMG_P1;
 | |
| 
 | |
|         Vector2 IMG_Player = (VR_Player - VR_P1) / VR_L * IMG_L + IMG_P1;
 | |
|         if (PlayericonFloor1Parent.activeSelf)
 | |
|         {
 | |
|             PlayericonFloor1.GetComponent<RectTransform>().anchoredPosition = IMG_Player;
 | |
|             //Debug.Log(IMG_Player);
 | |
|         }
 | |
|         if (PlayericonFloor2Parent.activeSelf)
 | |
|         {
 | |
|             PlayericonFloor2.GetComponent<RectTransform>().anchoredPosition = IMG_Player;
 | |
|             //Debug.Log(IMG_Player);
 | |
|         }
 | |
| 
 | |
|         /*
 | |
|         float VR_X = transform.position.x;
 | |
|         float VR_Y = transform.position.y;
 | |
| 
 | |
|         float VR_X1 = -10;
 | |
|         float VR_X2 = -123;
 | |
|         float IMG_X1 = -364;
 | |
|         float IMG_X2 = 394;
 | |
| 
 | |
| 
 | |
|         float Lvr = VR_X2 - VR_X1;//(-138 - -10)
 | |
|         float Limg = IMG_X2 - IMG_X1;
 | |
| 
 | |
|         IMG_X = (VR_X - VR_X1) / Lvr * Limg + IMG_X1;
 | |
|         */
 | |
|         //IMG_Y = (VR_Y - VR_Y1) / Lvr * Limg + IMG_Y1;
 | |
|         //Playericon.transform.position.Set(IMG_X,0,0);
 | |
|         //Playericon.GetComponent<RectTransform>().anchoredPosition = new Vector2(IMG_X, IMG_Y);
 | |
|         //Debug.Log(IMG_X + " vs " + Playericon.GetComponent<RectTransform>().anchoredPosition.x);
 | |
|     }
 | |
|     private void OnDestroy()
 | |
|     {
 | |
|         openMenuAction.action.Disable();
 | |
|         openMenuAction.action.performed -= ToggleMenu;
 | |
|         InputSystem.onDeviceChange -= OnDeviceChange;
 | |
|         Floor1Button.GetComponent<Button>().onClick.RemoveListener(DisplayFloor1);
 | |
|         Floor2Button.GetComponent<Button>().onClick.RemoveListener(DisplayFloor2);
 | |
|     }
 | |
| }
 |