Added extra sliders for audio (not audio logic not yet implemented) and got elevator outer buttons firing.

This commit is contained in:
2025-11-29 00:04:17 +02:00
parent 60b9f21a61
commit 187c700f9c
47 changed files with 2475 additions and 104 deletions

View File

@@ -0,0 +1,74 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
public class AudioSliderDragHandler : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public RectTransform sliderBackground; // Assign in Inspector
public float minValue = 0f;
public float maxValue = 1f;
public float slideareaOffsetMultiplier = 0.9f;
public float CurrentValue { get; private set; }
private RectTransform handleRect;
private Vector2 backgroundStart;
private float backgroundWidth;
void Awake()
{
handleRect = GetComponent<RectTransform>();
if (sliderBackground != null)
{
backgroundStart = sliderBackground.position;
backgroundWidth = sliderBackground.rect.width;
}
}
public void OnBeginDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
}
public void OnDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
}
public void OnEndDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
//notify FMOD
}
private void UpdateSlider(PointerEventData eventData)
{
Debug.Log("UpDating Slider");
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(sliderBackground, eventData.position, eventData.pressEventCamera, out localPoint);
float halfWidth = sliderBackground.rect.width * 0.5f;
// Only allow dragging within 90% of the slider width, centered
float limit = halfWidth * slideareaOffsetMultiplier;
float clampedX = Mathf.Clamp(localPoint.x, -limit, limit);
Vector3 newPosition = new Vector3(clampedX, handleRect.localPosition.y, handleRect.localPosition.z);
handleRect.localPosition = newPosition;
// Normalize within the limited 90% range
float normalized = (clampedX + limit) / (limit * 2f);
//Debug.Log(normalized);
CurrentValue = Mathf.Lerp(minValue, maxValue, normalized);
//Debug.Log(warningThreshholdValue);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d7aaef185c6472241ad9bb96b2e4ee6d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.XR.Interaction.Toolkit;
public class ContinuoslocomotionConfigurator : MonoBehaviour
{
public Button turnOffButton;
public Button turnOnButton;
public ContinuousMoveProviderBase locomotion;
// Events for listeners
public event Action<bool> OnLocomotionToggled; // true = enabled, false = disabled
public event Action<float> OnSpeedChanged; // sends new speed
void Start()
{
turnOnButton.onClick.AddListener(enableLocomotion);
turnOffButton.onClick.AddListener(disableLocomotion);
turnOffButton.gameObject.SetActive(false);
}
public void UpdateSpeed(float speed)
{
locomotion.moveSpeed = speed;
OnSpeedChanged?.Invoke(speed);
}
private void enableLocomotion()
{
AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Click, gameObject);
locomotion.enabled = true;
turnOnButton.gameObject.SetActive(false);
turnOffButton.gameObject.SetActive(true);
OnLocomotionToggled?.Invoke(true);
}
private void disableLocomotion()
{
AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Click, gameObject);
locomotion.enabled = false;
turnOnButton.gameObject.SetActive(true);
turnOffButton.gameObject.SetActive(false);
OnLocomotionToggled?.Invoke(false);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 26a0dd79a025e5041a41f576b1aa4968
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,42 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FloorButtonVisualizer : MonoBehaviour
{
public Sprite InactiveSprite;
public Sprite ActiveSprite;
public bool ActiveState;
private Image buttonImage;
// --- Static tracking for selection change ---
private static FloorButtonVisualizer lastActiveButton = null;
private static bool initialized = false;
void Start()
{
buttonImage = gameObject.GetComponent<Image>();
}
public void Activate()
{
this.ActiveState = true;
buttonImage.sprite = ActiveSprite;
AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Hover, gameObject);
// --- Only play hover if selection actually changed ---
//if (initialized && lastActiveButton != this)
//{
// AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Hover, gameObject);
//}
//lastActiveButton = this;
//initialized = true;
}
public void Deactivate()
{
this.ActiveState = false;
buttonImage.sprite = InactiveSprite;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3184e803032874740a854baa40883f49
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,54 @@
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.XR.Interaction.Toolkit;
public class GravityHandler : MonoBehaviour
{
public InputActionReference teleportAction;
public XRInteractorLineVisual TeleportRayLine;
public ActionBasedContinuousMoveProvider defaultGravity;
public bool isInSpace = false;
private void Awake()
{
teleportAction.action.Enable();
teleportAction.action.performed += OnTeleport;
}
private void Update()
{
if (isInSpace)
{
defaultGravity.useGravity = false; // Disable default gravity
}
else
{
defaultGravity.useGravity = true; // Enable default gravity
Physics.gravity = Vector3.down * 9.81f; // Reset to normal gravity
}
}
private void OnTeleport(InputAction.CallbackContext context)
{
if (isInSpace)
{
Quaternion newRotation = TeleportRayLine.reticle.transform.rotation;
Debug.Log("Teleport detected! Adjusting gravity... New rotation is: " + newRotation.eulerAngles);
//AdjustGravity(newRotation);
}
}
public void AdjustGravity(Quaternion rotation)
{
Vector3 newGravityDirection = rotation * Vector3.down; // Rotate gravity based on teleport direction
Physics.gravity = newGravityDirection.normalized * Physics.gravity.magnitude;
Debug.Log("New Gravity: " + Physics.gravity);
}
private void OnDestroy()
{
teleportAction.action.Disable();
teleportAction.action.performed -= OnTeleport;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9cdab728e7f1bc945ae623a3e5cc1645
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using System.Collections;
public class HoverSlideButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
public RectTransform buttonTransform;
public Vector2 offPosition = Vector2.zero;
public Vector2 onPosition = new Vector2(30f, 0f); // e.g., slide 30px to the right
public float slideDuration = 0.2f;
private Coroutine slideCoroutine;
private bool isOn = false;
private void Reset()
{
buttonTransform = GetComponent<RectTransform>();
}
public void OnPointerEnter(PointerEventData eventData)
{
SlideToPosition(onPosition);
AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Hover, gameObject); //3d oneshot sound
}
public void OnPointerExit(PointerEventData eventData)
{
if (!isOn) SlideToPosition(offPosition);
}
public void SetOnState(bool on)
{
isOn = on;
SlideToPosition(on ? onPosition : offPosition);
}
private void SlideToPosition(Vector2 target)
{
if (slideCoroutine != null)
StopCoroutine(slideCoroutine);
slideCoroutine = StartCoroutine(SmoothSlide(target));
}
private IEnumerator SmoothSlide(Vector2 target)
{
Vector2 startPos = buttonTransform.anchoredPosition;
float timeElapsed = 0f;
while (timeElapsed < slideDuration)
{
buttonTransform.anchoredPosition = Vector2.Lerp(startPos, target, timeElapsed / slideDuration);
timeElapsed += Time.deltaTime;
yield return null;
}
buttonTransform.anchoredPosition = target;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 926f667f37c3aed4d8c188d64dc8d882
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MenuReference : MonoBehaviour
{
public List<MenuTeleportButton> buttons;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 10d4b92fb83665e409f8d654c0a3295c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,147 @@
using FMOD.Studio;
using FMODUnity;
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.XR.CoreUtils;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Rendering;
using UnityEngine.UI;
using UnityEngine.XR.Interaction.Toolkit;
public class MenuTeleportButton : MonoBehaviour
{
public Sprite NormalSprite;
public Sprite HoverSprite;
public String TargetName;
public XRBaseControllerInteractor LeftXRInteractor; // Reference to XR controller interactor (e.g., Ray Interactor)
public XRBaseControllerInteractor RightXRInteractor;
public XROrigin Player;
public TeleportationProvider teleportationProvider; // Reference to TeleportationProvider
private Button button;
private TeleportLocation target; // Target teleport position
private EventInstance TeleportingSound;
FMOD.Studio.Bus SpecialBus; //FMOD bus variable
private static MenuTeleportButton lastSelectedButton = null;
private static bool initialized = false;
// External state: map must be held/visible
public static bool MapIsOpen = false;
private Menu menu;
private void Awake()
{
TeleportingSound = AudioManager.Instance.CreateInstance(FMODEvents.Instance.Teleport); //initialise the instance
SpecialBus = FMODUnity.RuntimeManager.GetBus("bus:/LogicalMute");
}
void Start()
{
button = GetComponent<Button>();
menu = FindObjectOfType<Menu>();
// Subscribe to button events
button.onClick.AddListener(TeleportPlayer);
TeleportLocation[] locations = FindObjectsOfType<TeleportLocation>(); // Fetch all teleport locations in the scene.
foreach (TeleportLocation location in locations) // Find the target location.
{
if (location.Name.Equals(TargetName))
{
target = location;
break;
}
}
if (target == null)
{
Debug.LogError("Teleport target of " + TargetName + " not found.");
}
}
public void SetStateSelected()
{
if (button != null && HoverSprite != null)
{
button.targetGraphic.GetComponent<Image>().sprite = HoverSprite;
// --- Only play hover sound if selection actually changed ---
//if (initialized && lastSelectedButton != this)
//{
// if (!Menu.IsMapOpen) return;
// if (!menu.MapTab.activeSelf) return; // ensures only map page buttons make sound
// AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Hover, gameObject);
//}
if (!Menu.IsMapOpen) return;
if (!menu.MapTab.activeSelf) return; // ensures only map page buttons make sound
AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Hover, gameObject);
//lastSelectedButton = this;
//initialized = true;
}
}
public void SetStateDefault()
{
// Refresh the button state.
button.interactable = false;
button.interactable = true;
if (NormalSprite != null)
{
button.targetGraphic.GetComponent<Image>().sprite = NormalSprite;
}
}
private void TeleportPlayer()
{
if (target == null || Player == null || teleportationProvider == null)
{
Debug.LogWarning("Teleportation failed: Target, Player, or TeleportationProvider is missing.");
return;
}
// Prepare teleport request
TeleportRequest request = new TeleportRequest
{
destinationPosition = target.transform.position,
destinationRotation = target.transform.rotation,
matchOrientation = MatchOrientation.TargetUpAndForward
};
// Queue teleport request
bool success = teleportationProvider.QueueTeleportRequest(request);
if (!success)
{
Debug.LogWarning("Teleport request failed to queue.");
}
// Refresh the button state
button.interactable = false;
button.interactable = true;
StartCoroutine(MuteBusForSeconds(2.0f));
TeleportingSound.start(); //playing 2d oneshot
}
private IEnumerator MuteBusForSeconds(float duration)
{
// Lower volume to 0 instantly
SpecialBus.setVolume(0f);
Debug.Log("[MenuTeleportButton] Muting LogicalMute bus...");
yield return new WaitForSeconds(duration);
// Restore volume
SpecialBus.setVolume(1f);
Debug.Log("[MenuTeleportButton] Unmuted LogicalMute bus.");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7a0fe998040c9bb4a9e7a67b111a2a1f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,388 @@
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;
public static bool IsMapOpen { get; private set; }
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);
IsMapOpen = canvas.enabled;
}
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;
IsMapOpen = 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);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d3a87fec250b5604fbb67042d08f8bc9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,84 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using TMPro;
public class MoveSliderDragHandler : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
{
public RectTransform sliderBackground; // Assign in Inspector
public float minValue = 2f;
public float maxValue = 5f;
public float slideareaOffsetMultiplier = 0.9f;
public TMP_Text warningText;
public float warningThreshholdValue = 0.65f;
public float CurrentValue { get; private set; }
public ContinuoslocomotionConfigurator configurator;
private RectTransform handleRect;
private Vector2 backgroundStart;
private float backgroundWidth;
void Awake()
{
handleRect = GetComponent<RectTransform>();
if (sliderBackground != null)
{
backgroundStart = sliderBackground.position;
backgroundWidth = sliderBackground.rect.width;
}
}
public void OnBeginDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
}
public void OnDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
}
public void OnEndDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
configurator.UpdateSpeed(CurrentValue);
EventSystem.current.SetSelectedGameObject(null);
}
private void UpdateSlider(PointerEventData eventData)
{
Debug.Log("UpDating Slider");
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(sliderBackground, eventData.position, eventData.pressEventCamera, out localPoint);
float halfWidth = sliderBackground.rect.width * 0.5f;
// Only allow dragging within 90% of the slider width, centered
float limit = halfWidth * slideareaOffsetMultiplier;
float clampedX = Mathf.Clamp(localPoint.x, -limit, limit);
Vector3 newPosition = new Vector3(clampedX, handleRect.localPosition.y, handleRect.localPosition.z);
handleRect.localPosition = newPosition;
// Normalize within the limited 90% range
float normalized = (clampedX + limit) / (limit * 2f);
//Debug.Log(normalized);
CurrentValue = Mathf.Lerp(minValue, maxValue, normalized);
// Displaying the warning.
if (CurrentValue > (warningThreshholdValue*(maxValue - minValue) + minValue)) warningText.gameObject.SetActive(true);
else warningText.gameObject.SetActive(false);
//Debug.Log(warningThreshholdValue);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a1dff6a2857e62b4d841d7bc2fb986e9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TeleportLocationCollider : MonoBehaviour
{
public TeleportLocation parent;
private void OnTriggerEnter(Collider other)
{
MenuReference reference = other.GetComponent<MenuReference>();
if (reference == null) return;
List<MenuTeleportButton> buttonsList = reference.buttons;
MenuTeleportButton button = findCorrespondingButton(buttonsList);
if (button != null)
{
button.SetStateSelected();
}
}
private void OnTriggerExit(Collider other)
{
MenuReference reference = other.GetComponent<MenuReference>();
if (reference == null) return;
List<MenuTeleportButton> buttonsList = other.GetComponent<MenuReference>().buttons;
MenuTeleportButton button = findCorrespondingButton(buttonsList);
if (button != null)
{
button.SetStateDefault();
}
//Debug.Log(other.name + " exited the area");
}
private MenuTeleportButton findCorrespondingButton(List<MenuTeleportButton> buttons)
{
foreach (MenuTeleportButton button in buttons)
{
if (button.TargetName.Equals(parent.Name))
{
return button;
}
}
Debug.Log("Teleport location of " + parent.Name + " was unable to find the button triggering it");
return null;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: becc71823bf144d48b8395ee9683eac4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TeleportLocation : MonoBehaviour
{
public string Name;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b4e4e4f3794a24045802f75a7e8eb81e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
using FMOD.Studio;
[RequireComponent(typeof(TeleportationProvider))]
public class TeleportationListen : MonoBehaviour
{
private TeleportationProvider teleportationProvider;
void Awake()
{
teleportationProvider = GetComponent<TeleportationProvider>();
}
void OnEnable()
{
// Subscribe to the event that fires when teleportation actually ends
teleportationProvider.endLocomotion += OnTeleportEnd;
}
void OnDisable()
{
teleportationProvider.endLocomotion -= OnTeleportEnd;
}
private void OnTeleportEnd(LocomotionSystem locomotionSystem)
{
AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.Steps, gameObject); //oneshot 3d event
Debug.Log("[TeleportationListen] Teleport sound played.");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6bdaa08e302fd9a4ab0f386f25762231
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,150 @@
using _PROJECT.NewHandPresence;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.XR.Interaction.Toolkit;
public class TutorialAudioListener : MonoBehaviour
{
[Header("References")]
[SerializeField] private TutorialController tutorialController;
[SerializeField] private ContinuoslocomotionConfigurator locomotionConfigurator;
private InputAction moveAction;
private InputAction turnAction;
private TeleportationProvider teleportationProvider;
private float lastStepTime;
[Header("Settings")]
[SerializeField] private float baseStepRate = 0.5f; // Step interval at joystick = 1 and slider = 1
[SerializeField] private float joystickThreshold = 0.1f; // Minimum stick movement to count as walking
private float settingsSpeedMultiplier = 1f; // From slider (1 = default)
private bool locomotionEnabled = false;
private Vector2 currentMoveVector;
private void Awake()
{
if (tutorialController == null)
tutorialController = FindObjectOfType<TutorialController>();
if (locomotionConfigurator == null)
locomotionConfigurator = FindObjectOfType<ContinuoslocomotionConfigurator>();
if (tutorialController != null)
{
moveAction = tutorialController.moveProvider.leftHandMoveAction.action;
turnAction = tutorialController.turnProvider.rightHandSnapTurnAction.action;
teleportationProvider = tutorialController.teleportProvider;
}
}
private void OnEnable()
{
if (moveAction != null)
{
moveAction.performed += OnMoveInput;
moveAction.canceled += OnMoveCanceled;
}
if (turnAction != null)
turnAction.performed += OnTurnPerformed;
if (teleportationProvider != null)
teleportationProvider.endLocomotion += OnTeleportEnd;
if (locomotionConfigurator != null)
{
locomotionConfigurator.OnLocomotionToggled += HandleLocomotionToggled;
locomotionConfigurator.OnSpeedChanged += HandleSpeedChanged;
}
}
private void OnDisable()
{
if (moveAction != null)
{
moveAction.performed -= OnMoveInput;
moveAction.canceled -= OnMoveCanceled;
}
if (turnAction != null)
turnAction.performed -= OnTurnPerformed;
if (teleportationProvider != null)
teleportationProvider.endLocomotion -= OnTeleportEnd;
if (locomotionConfigurator != null)
{
locomotionConfigurator.OnLocomotionToggled -= HandleLocomotionToggled;
locomotionConfigurator.OnSpeedChanged -= HandleSpeedChanged;
}
}
private void HandleLocomotionToggled(bool enabled)
{
locomotionEnabled = enabled;
}
private void HandleSpeedChanged(float newSpeed)
{
// Slider is allowed to range normally but we clamp for stability
settingsSpeedMultiplier = Mathf.Clamp(newSpeed, 0.4f, 1.2f);
}
private void OnMoveInput(InputAction.CallbackContext ctx)
{
currentMoveVector = ctx.ReadValue<Vector2>();
}
private void OnMoveCanceled(InputAction.CallbackContext ctx)
{
currentMoveVector = Vector2.zero;
}
private void Update()
{
TryPlayStep();
}
private void TryPlayStep()
{
if (!locomotionEnabled)
return;
float joystickMagnitude = currentMoveVector.magnitude;
if (joystickMagnitude < joystickThreshold)
return; // Not moving enough to walk
// --- NEW: Slider influence (very light touch) ---
float sliderInfluence = 1f + (settingsSpeedMultiplier) * 0.25f;
float effectiveMagnitude = joystickMagnitude * sliderInfluence;
// --- NEW: Step cooldown ---
float dynamicCooldown = baseStepRate / Mathf.Max(effectiveMagnitude, 0.01f);
dynamicCooldown = Mathf.Clamp(dynamicCooldown, 0.33f, 0.65f);
if (Time.time - lastStepTime < dynamicCooldown)
return;
lastStepTime = Time.time;
AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.StepOverall, gameObject);
}
private void OnTurnPerformed(InputAction.CallbackContext context)
{
// If magnitude above threshold = walking don't play spin sound
if (currentMoveVector.magnitude > joystickThreshold)
return;
// Otherwise play turning sound
AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.StepSpin, gameObject);
}
private void OnTeleportEnd(LocomotionSystem locomotionSystem)
{
// Optional teleport sound
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ca400fa6ff24b104190032fa85eedf91
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: