433 lines
17 KiB
C#
433 lines
17 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.Rendering.HighDefinition;
|
||
using UnityEngine.Animations.Rigging;
|
||
using UnityEngine.Localization;
|
||
using UnityEngine.Localization.Settings;
|
||
|
||
public class FlashlightController : MonoBehaviour
|
||
{
|
||
[SerializeField] private Light _light;
|
||
HDAdditionalLightData lightData;
|
||
[SerializeField] private GameObject _flashlightMeshGO;
|
||
[HideInInspector] public float _flashlightLife = 100f;
|
||
public bool _IsOpen;
|
||
[SerializeField] private float intensityIncreaseRate = 550f; // Rate at which intensity increases per second
|
||
[SerializeField] private float intensityDecreaseRate = 800f; // Rate at which intensity increases per second
|
||
public float maxIntensity = 600f; // Maximum intensity value
|
||
[SerializeField] private float transitionDuration = 1;
|
||
private bool canPressButtonToOpenOrCloseFlashlight = true;
|
||
private bool shouldDisplayMessageFlashlightIsFull;
|
||
[HideInInspector] public bool canUseFlashlight = true;
|
||
|
||
public AudioSource flashlightAudioSource;
|
||
public AudioClip flashlightAudioClip;
|
||
|
||
[Header("Battery UI")]
|
||
[SerializeField] private GameObject batteryUIGroup;
|
||
[SerializeField] private GameObject[] _batteryUI;
|
||
|
||
[Header("Inverse Kinematics")]
|
||
[SerializeField] MultiAimConstraint multiAimConstraintPlayersRightHand;
|
||
private Coroutine TransitionWeightToAimingFlashlightCoroutine;
|
||
private Coroutine TransitionWeightToNotAimingFlashlightCoroutine;
|
||
|
||
public LocalizedString youUsedABatteryMessage;
|
||
public LocalizedString batteryMessage;
|
||
public LocalizedString youDontHaveAnyBatteriesText;
|
||
|
||
private static FlashlightController _instance;
|
||
public static FlashlightController GetInstance() { return _instance; }
|
||
|
||
private void Awake()
|
||
{
|
||
if (!_instance)
|
||
{
|
||
_instance = this;
|
||
}
|
||
|
||
//GameObject playerGo = PlayerManager.GetInstance().playerGameObj;
|
||
//if (_light == null)
|
||
//{
|
||
// _light = playerGo.transform.Find("Main Camera/Flashlight/WhiteLight").GetComponent<Light>();
|
||
//}
|
||
//else
|
||
//{
|
||
// Debug.LogError("No Light with name " + "WhiteLight" + " found in the scene.");
|
||
//}
|
||
//if(_flashlightMeshGO == null)
|
||
//{
|
||
// _flashlightMeshGO = playerGo.transform.GetComponentInChildren<FlashlightMesh>().gameObject;
|
||
//}
|
||
//else
|
||
//{
|
||
// Debug.LogError("No _flashlightMeshGO found in the scene.");
|
||
//}
|
||
//if (multiAimConstraintPlayersRightHand == null)
|
||
//{
|
||
// multiAimConstraintPlayersRightHand = playerGo.transform.Find("MainCharacter/Rig 1/FlashLight_MultiAimConstraint").GetComponent<MultiAimConstraint>();
|
||
//}
|
||
//else
|
||
//{
|
||
// Debug.LogError("No LmultiAimConstraintPlayersRightHand found in the scene.");
|
||
//}
|
||
}
|
||
|
||
private void Start()
|
||
{
|
||
GameObject playerGo = PlayerManager.GetInstance().playerGameObj;
|
||
if (_light == null)
|
||
{
|
||
_light = playerGo.transform.Find("Main Camera/Flashlight/WhiteLight").GetComponent<Light>();
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("No Light with name " + "WhiteLight" + " found in the scene.");
|
||
}
|
||
if (_flashlightMeshGO == null)
|
||
{
|
||
_flashlightMeshGO = playerGo.transform.GetComponentInChildren<FlashlightMesh>().gameObject;
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("No _flashlightMeshGO found in the scene.");
|
||
}
|
||
if (multiAimConstraintPlayersRightHand == null)
|
||
{
|
||
multiAimConstraintPlayersRightHand = playerGo.transform.Find("MainCharacter/Rig 1/FlashLight_MultiAimConstraint").GetComponent<MultiAimConstraint>();
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("No LmultiAimConstraintPlayersRightHand found in the scene.");
|
||
}
|
||
|
||
if (flashlightAudioSource == null)
|
||
{
|
||
flashlightAudioSource = GetComponent<AudioSource>();
|
||
}
|
||
lightData = _light.GetComponent<HDAdditionalLightData>();
|
||
|
||
if (_light.enabled)
|
||
{
|
||
_light.enabled = false;
|
||
}
|
||
|
||
if (_flashlightMeshGO.activeInHierarchy)
|
||
{
|
||
_flashlightMeshGO.SetActive(false);
|
||
}
|
||
|
||
if(_flashlightLife >= 100)
|
||
{
|
||
shouldDisplayMessageFlashlightIsFull = true;
|
||
}
|
||
|
||
//Closes battery UI.
|
||
batteryUIGroup.SetActive(false);
|
||
//StartCoroutine(AfterGameLoaded());
|
||
}
|
||
|
||
IEnumerator AfterGameLoaded()
|
||
{
|
||
yield return new WaitUntil(() => LoadManager.GetInstance() != null && !LoadManager.GetInstance().LoadingGame);
|
||
yield return new WaitUntil(() => GameProgressManager.GetInstance() != null);
|
||
}
|
||
|
||
// Update is called once per frame
|
||
void Update()
|
||
{
|
||
if (GameProgressManager.GetInstance().FlashlightIsObtained)
|
||
{
|
||
OpenCloseFlashlight();
|
||
ReloadBatteryUpdate();
|
||
|
||
if (_IsOpen) //If flashlight is open:
|
||
{
|
||
_flashlightLife -= Time.deltaTime * 0.5f;
|
||
//_light.enabled = true;
|
||
|
||
if (_flashlightLife <= 0f)
|
||
{
|
||
_light.enabled = false;
|
||
_IsOpen = false;
|
||
|
||
_batteryUI[0].SetActive(false);
|
||
_batteryUI[1].SetActive(false);
|
||
_batteryUI[2].SetActive(false);
|
||
_batteryUI[3].SetActive(false);
|
||
}
|
||
|
||
#region BatteryLife
|
||
if (_flashlightLife >= 70f)
|
||
{
|
||
_batteryUI[0].SetActive(true);
|
||
_batteryUI[1].SetActive(false);
|
||
_batteryUI[2].SetActive(false);
|
||
_batteryUI[3].SetActive(false);
|
||
}
|
||
else if (_flashlightLife <= 70f && _flashlightLife >= 50f)
|
||
{
|
||
_batteryUI[0].SetActive(false);
|
||
_batteryUI[1].SetActive(true);
|
||
_batteryUI[2].SetActive(false);
|
||
_batteryUI[3].SetActive(false);
|
||
}
|
||
else if (_flashlightLife <= 50f && _flashlightLife >= 25)
|
||
{
|
||
_batteryUI[0].SetActive(false);
|
||
_batteryUI[1].SetActive(false);
|
||
_batteryUI[2].SetActive(true);
|
||
_batteryUI[3].SetActive(false);
|
||
}
|
||
else if (_flashlightLife <= 25f && _flashlightLife >= 0.1f)
|
||
{
|
||
_batteryUI[0].SetActive(false);
|
||
_batteryUI[1].SetActive(false);
|
||
_batteryUI[2].SetActive(false);
|
||
_batteryUI[3].SetActive(true);
|
||
}
|
||
#endregion
|
||
|
||
if (_flashlightLife <= 0f)
|
||
{
|
||
PutFlashlightDown(); //It will also trigger the flashlight's Light animation in order to no longer project light.
|
||
_IsOpen = false;
|
||
}
|
||
|
||
if (shouldDisplayMessageFlashlightIsFull)
|
||
{
|
||
if (_flashlightLife < 100)
|
||
{
|
||
shouldDisplayMessageFlashlightIsFull = false;
|
||
}
|
||
}
|
||
}
|
||
//else //If flashlight is closed:
|
||
//{
|
||
// if (_flashlightLife <= 0f)
|
||
// {
|
||
// PutFlashlightDown(); //It will also trigger the flashlight's Light animation in order to no longer project light.
|
||
// //_light.enabled = false;
|
||
// }
|
||
//}
|
||
|
||
RaycastHit hit;
|
||
Vector3 forward = FlashlightRaycast.GetInstance().flashlightRaycast.forward;
|
||
if (_IsOpen)
|
||
{
|
||
if (Physics.Raycast(FlashlightRaycast.GetInstance().flashlightRaycast.transform.position, forward, out hit, 0.5f, FlashlightRaycast.GetInstance().collisionLayer, QueryTriggerInteraction.Ignore))
|
||
{
|
||
FlashlightRaycast.GetInstance().flashlightCurrentCollider = hit.collider.transform;
|
||
|
||
if (hit.collider)
|
||
{
|
||
if (!PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.GetBool("IsWallInFront"))
|
||
{
|
||
TransitionWeightToNotAimingFlashlightCoroutine = StartCoroutine(TransitionWeightAimingFlashlight(multiAimConstraintPlayersRightHand.weight, 0, 2)); //Make Transition to 0.
|
||
if (TransitionWeightToAimingFlashlightCoroutine != null)
|
||
{
|
||
StopCoroutine(TransitionWeightToAimingFlashlightCoroutine);
|
||
TransitionWeightToAimingFlashlightCoroutine = null;
|
||
}
|
||
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("IsWallInFront", true);
|
||
}
|
||
}
|
||
//print("Found an object - distance: " + hit.distance);
|
||
}
|
||
else
|
||
{
|
||
FlashlightRaycast.GetInstance().flashlightCurrentCollider = null;
|
||
if (PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.GetBool("IsWallInFront"))
|
||
{
|
||
TransitionWeightToAimingFlashlightCoroutine = StartCoroutine(TransitionWeightAimingFlashlight(multiAimConstraintPlayersRightHand.weight, 1, 2)); //Make Transition to 1.
|
||
if (TransitionWeightToNotAimingFlashlightCoroutine != null)
|
||
{
|
||
StopCoroutine(TransitionWeightToNotAimingFlashlightCoroutine);
|
||
TransitionWeightToNotAimingFlashlightCoroutine = null;
|
||
}
|
||
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("IsWallInFront", false);
|
||
}
|
||
}
|
||
//Vector3 forward = transform.TransformDirection(Vector3.forward) * 0.5f;
|
||
Debug.DrawRay(transform.position, forward * 0.5f, Color.green);
|
||
}
|
||
}
|
||
}
|
||
|
||
public void OpenCloseFlashlight()
|
||
{
|
||
float DpadVertical = Input.GetAxis("DpadVertical");
|
||
|
||
if ((Input.GetKeyDown(KeyCode.F) || (DpadVertical >= 0.1) /*Up Dpad*/) && UIManager.GetInstance().userInterfaceIsOnScreen == false)
|
||
{
|
||
if (canUseFlashlight)
|
||
{
|
||
if (canPressButtonToOpenOrCloseFlashlight)
|
||
{
|
||
if (!_IsOpen && _flashlightLife >= 1f)
|
||
{
|
||
TurnFlashlightON();
|
||
//StartCoroutine(WaitSecToClose());
|
||
}
|
||
else if (_IsOpen)
|
||
{
|
||
PutFlashlightDown();
|
||
_IsOpen = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// Call this method from other script if you want to use the flashlight if it has battery.
|
||
/// </summary>
|
||
public void UseFlashlight()
|
||
{
|
||
if (!_IsOpen && _flashlightLife >= 1f)
|
||
{
|
||
TurnFlashlightON();
|
||
//StartCoroutine(WaitSecToClose());
|
||
}
|
||
}
|
||
|
||
IEnumerator WaitSecToClose()
|
||
{
|
||
yield return new WaitForSeconds(1f);
|
||
//_IsOpen = false;
|
||
}
|
||
|
||
public void ReloadBatteryUpdate()
|
||
{
|
||
if (Input.GetKeyDown(KeyCode.R) || Input.GetKeyDown(KeyCode.JoystickButton2)/*X button*/)
|
||
{
|
||
ReloadBattery();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Call this method whenever you want the player to reload the flashlight.
|
||
/// </summary>
|
||
public void ReloadBattery()
|
||
{
|
||
if (BatteryManager.GetInstance().batteriesCollected >= 1 && _flashlightLife <= 99)
|
||
{
|
||
BatteryManager.GetInstance().batteriesCollected -= 1;
|
||
_flashlightLife = 100f;
|
||
shouldDisplayMessageFlashlightIsFull = true;
|
||
string localizedText = LocalizationSettings.StringDatabase.GetLocalizedString("Messages", "youUsedABatteryMessage");
|
||
UIManager.GetInstance().StartCoroutine(UIManager.GetInstance().DisplayMessage(youUsedABatteryMessage));
|
||
if (InventoryManager.GetInstance().batteryOnRingInventory.activeSelf == true && BatteryManager.GetInstance().batteriesCollected == 0)
|
||
{
|
||
RingInventory.GetInstance().RemoveItemByNameToKeysAndItemsInventory("Battery");
|
||
}
|
||
print("You used a battery");
|
||
}
|
||
//if (/*shouldDisplayMessageFlashlightIsFull &&*/ _flashlightLife >= 100)//θελω οταν πας να πατησεις το κουμπι για reload να σου εμφανίζει το μήνυμα οτι δεν έχεις άλλες μπαταρίες αν δεν έχεις.
|
||
//{
|
||
// UIManager.GetInstance().StartCoroutine(UIManager.GetInstance().DisplayMessage("Flashlight is full"));
|
||
//}
|
||
if (BatteryManager.GetInstance().batteriesCollected <= 0 && _flashlightLife < 100)
|
||
{
|
||
print("you don't have any batteries");
|
||
string localizedText = LocalizationSettings.StringDatabase.GetLocalizedString("Messages", "youDontHaveAnyBatteriesText");
|
||
UIManager.GetInstance().StartCoroutine(UIManager.GetInstance().DisplayMessage(youDontHaveAnyBatteriesText));
|
||
}
|
||
}
|
||
|
||
public void EnableFlashlightLight()
|
||
{
|
||
flashlightAudioSource.PlayOneShot(flashlightAudioClip);
|
||
StartCoroutine(GraduallyIncreaseIntensity());
|
||
}
|
||
|
||
public void DisableFlashlightLight()
|
||
{
|
||
flashlightAudioSource.PlayOneShot(flashlightAudioClip);
|
||
StartCoroutine(GraduallyDecreaseIntensity());
|
||
}
|
||
|
||
private IEnumerator GraduallyIncreaseIntensity()
|
||
{
|
||
//lightData.volumetricDimmer = 0.4f;
|
||
lightData.intensity = 0f;
|
||
_light.enabled = true;
|
||
float currentIntensity = lightData.intensity;
|
||
|
||
while (currentIntensity < maxIntensity)
|
||
{
|
||
currentIntensity += intensityIncreaseRate * Time.deltaTime;
|
||
lightData.intensity = currentIntensity;
|
||
yield return null;
|
||
}
|
||
|
||
lightData.intensity = maxIntensity;
|
||
}
|
||
|
||
private IEnumerator GraduallyDecreaseIntensity()
|
||
{
|
||
float currentIntensity = lightData.intensity;
|
||
|
||
while (currentIntensity >= 0)
|
||
{
|
||
currentIntensity -= intensityDecreaseRate * Time.deltaTime;
|
||
lightData.intensity = currentIntensity;
|
||
yield return null;
|
||
}
|
||
|
||
lightData.intensity = lightData.intensity;
|
||
_light.enabled = false;
|
||
}
|
||
|
||
public void TurnFlashlightON()
|
||
{
|
||
batteryUIGroup.SetActive(true);
|
||
_IsOpen = true;
|
||
_flashlightMeshGO.SetActive(true);
|
||
canPressButtonToOpenOrCloseFlashlight = false;
|
||
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("IsUsingFlashlight", true);
|
||
TransitionWeightToAimingFlashlightCoroutine = StartCoroutine(TransitionWeightAimingFlashlight(multiAimConstraintPlayersRightHand.weight, 1, 2));
|
||
if (TransitionWeightToNotAimingFlashlightCoroutine != null)
|
||
{
|
||
StopCoroutine(TransitionWeightToNotAimingFlashlightCoroutine);
|
||
TransitionWeightToNotAimingFlashlightCoroutine = null;
|
||
}
|
||
}
|
||
|
||
public void PutFlashlightDown()
|
||
{
|
||
batteryUIGroup.SetActive(false);
|
||
canPressButtonToOpenOrCloseFlashlight = false;
|
||
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("IsUsingFlashlight", false);
|
||
TransitionWeightToNotAimingFlashlightCoroutine = StartCoroutine(TransitionWeightAimingFlashlight(multiAimConstraintPlayersRightHand.weight, 0, 2));
|
||
if (TransitionWeightToAimingFlashlightCoroutine != null)
|
||
{
|
||
StopCoroutine(TransitionWeightToAimingFlashlightCoroutine);
|
||
TransitionWeightToAimingFlashlightCoroutine = null;
|
||
}
|
||
}
|
||
|
||
private IEnumerator TransitionWeightAimingFlashlight(float startWeight, float targetWeight, float speed)
|
||
{
|
||
float elapsedTime = 0f;
|
||
|
||
while (elapsedTime < transitionDuration)
|
||
{
|
||
elapsedTime += Time.deltaTime;
|
||
float t = Mathf.Clamp01(elapsedTime / transitionDuration);
|
||
multiAimConstraintPlayersRightHand.weight = Mathf.Lerp(startWeight, targetWeight, speed * t);
|
||
yield return null;
|
||
}
|
||
|
||
// Ensure the target weight is reached precisely
|
||
multiAimConstraintPlayersRightHand.weight = targetWeight;
|
||
canPressButtonToOpenOrCloseFlashlight = true;
|
||
if (!_IsOpen)
|
||
{
|
||
_flashlightMeshGO.SetActive(false);
|
||
}
|
||
}
|
||
}
|