Files
HauntedBloodlines/Assets/Scripts/CandleController.cs
2025-05-29 22:31:40 +03:00

401 lines
13 KiB
C#

using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.Playables;
using System.Collections;
using UnityEngine.Animations.Rigging;
using System.Text.RegularExpressions;
public class CandleController : MonoBehaviour
{
[Header("References")]
[SerializeField] private GameObject candleMesh;
public Light candleLight;
[SerializeField] private HDAdditionalLightData lightData;
[Header("Candle Settings")]
[SerializeField] private float maxCandleLife = 100f;
[SerializeField] private float lightIntensity = 200f;
[SerializeField] private float _candleLife;
[SerializeField] private float _candleSecondsToTurnOffWhenRunning = 0.3f;
public bool canUseCandle = true;
public bool isUsingCandle;
public bool canToggleCandle;
public bool isSettingOnFireCandle;
private bool _isCandleOn = false;
[SerializeField] private PlayableDirector candleLitPlayable;
[SerializeField] private GameObject matchGO;
[SerializeField] private ParticleSystem matchFlame;
[SerializeField] private ParticleSystem candleFlame;
Coroutine IsRunningTimerCoroutine;
[Header("Inverse Kinematics")]
[SerializeField] private float multiAimConstraintTransitionDuration = 1;
[SerializeField] MultiAimConstraint multiAimConstraintPlayersRightHand;
private Coroutine TransitionWeightToAimingCandleLightCoroutine;
private Coroutine TransitionWeightToNotAimingCandleLightCoroutine;
private static CandleController _instance;
public static CandleController GetInstance() => _instance;
public bool isCandleOn => _isCandleOn;
public float candleLife => _candleLife;
private void Awake()
{
if (_instance == null)
_instance = this;
}
private void Start()
{
_candleLife = maxCandleLife;
if (candleLight != null)
{
candleLight.enabled = false;
lightData = candleLight.GetComponent<HDAdditionalLightData>();
lightData.intensity = lightIntensity;
}
if (candleMesh != null)
{
candleMesh.SetActive(false);
}
matchGO.SetActive(false);
InitialSetup();
StartCoroutine(AfterGameLoaded());
}
void InitialSetup()
{
GameObject playerGo = PlayerManager.GetInstance().playerGameObj;
if (multiAimConstraintPlayersRightHand == null)
{
multiAimConstraintPlayersRightHand = playerGo.transform.Find("MainCharacter/Rig 1/CandleLight_MultiAimConstraint").GetComponent<MultiAimConstraint>();
}
else
{
Debug.LogError("No multiAimConstraintPlayersRightHand found in the scene.");
}
}
IEnumerator AfterGameLoaded()
{
yield return new WaitUntil(() => LoadManager.GetInstance() != null && !LoadManager.GetInstance().LoadingGame);
yield return new WaitUntil(() => PlayerManager.GetInstance() != null);
PlayerManager.GetInstance()._PlayerMovement.OnRunning += IsRunningStartCandleTurnOffTimer;
PlayerManager.GetInstance()._PlayerMovement.OnStoppedRunning += IsRunningStopCandleTurnOffTimer;
InitialSetup();
}
private void OnDisable()
{
PlayerManager.GetInstance()._PlayerMovement.OnRunning -= IsRunningStartCandleTurnOffTimer;
PlayerManager.GetInstance()._PlayerMovement.OnStoppedRunning -= IsRunningStopCandleTurnOffTimer;
}
private void Update()
{
if (GameProgressManager.GetInstance().CandleHolderIsObtained)
{
if (Input.GetKeyDown(KeyCode.F) && !isSettingOnFireCandle)
{
UseCandleHolder();
}
if (canToggleCandle && _candleLife > 0f)
{
if (Input.GetKeyDown(KeyCode.R))
{
if (_isCandleOn == false)
{
TransitionWeightToNotAimingCandleLight();
isSettingOnFireCandle = true;
candleLitPlayable.Play();
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("CandleIdle", false);
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("IsLitCandle", true);
//ToggleCandle();
CanNotToggleCandle();
print("Play candle lit playable");
}
//else
//{
// PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("IsUsingCandle", false);
// PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("IsLitCandle", false);
// _isCandleOn = false;
//}
}
}
if (_isCandleOn)
{
_candleLife -= Time.deltaTime;
if (_candleLife <= 0f)
{
_candleLife = 0f;
TurnOffCandle();
}
}
RaycastHit hit;
Vector3 forward = FlashlightRaycast.GetInstance().flashlightRaycast.forward;
if (isUsingCandle && canToggleCandle)
{
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"))
{
TransitionWeightToNotAimingCandleLight();
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"))
{
TransitionWeightToAimingCandleLight();
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 UseCandleHolder()
{
if (canUseCandle)
{
if (!isUsingCandle)
{
candleMesh.SetActive(true);
canToggleCandle = false;
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("IsUsingCandle", true);
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("CandleIdle", true);
StartCoroutine(CanUseAndToggleCandleAfterSeconds(true, true));
TransitionWeightToAimingCandleLight();
isUsingCandle = true;
canUseCandle = false;
}
else
{
canToggleCandle = false;
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("IsUsingCandle", false);
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("CandleIdle", false);
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("IsLitCandle", false);
StartCoroutine(CanUseAndToggleCandleAfterSeconds(true, false));
StopCandleFlameParticle();
TurnOffCandle();
isUsingCandle = false;
canUseCandle = false;
}
}
}
public void IsRunningStartCandleTurnOffTimer()
{
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("CandleIdleRunning", true);
if(IsRunningTimerCoroutine == null)
{
IsRunningTimerCoroutine = StartCoroutine(IsRunningTimer());
}
}
public void IsRunningStopCandleTurnOffTimer()
{
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("CandleIdleRunning", false);
if (IsRunningTimerCoroutine != null)
{
StopCoroutine(IsRunningTimerCoroutine);
print("Stopped Running timer turn off candle");
IsRunningTimerCoroutine = null;
}
}
IEnumerator IsRunningTimer()
{
yield return new WaitForSeconds(_candleSecondsToTurnOffWhenRunning);
TurnOffCandle();
print("Player sprinted for: " + _candleSecondsToTurnOffWhenRunning + " seconds so the candle turned Off");
}
IEnumerator CanUseAndToggleCandleAfterSeconds(bool canUseCandle, bool canToggleCandle)
{
yield return new WaitForSeconds(1f);
if (canToggleCandle)
{
CanToggleCandle();
}
else
{
CanNotToggleCandle();
}
if (canUseCandle)
{
CanUseCandle();
}
else
{
CanNotUseCandle();
}
}
public void PlayMatchFlameParticle()
{
matchGO.SetActive(true);
matchFlame.Play();
}
public void StopMatchFlameParticle()
{
matchFlame.Stop();
matchGO.SetActive(false);
}
public void PlayCandleFlameParticle()
{
candleFlame.Play();
}
public void StopCandleFlameParticle()
{
candleFlame.Stop();
}
public void CanToggleCandle()
{
canToggleCandle = true;
}
public void CanNotToggleCandle()
{
canToggleCandle = false;
}
public void CanUseCandle()
{
canUseCandle = true;
}
public void CanNotUseCandle()
{
canUseCandle = false;
}
public void SetAnimatorBoolCandleIdle(bool CandleIdle)
{
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("CandleIdle", CandleIdle);
}
public void SetAnimatorBoolIsLitCandle(bool IsLitCandle)
{
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("IsLitCandle", IsLitCandle);
isSettingOnFireCandle = false;
}
public void ToggleCandle()
{
if (_isCandleOn)
TurnOffCandle();
else
TurnOnCandle();
}
public void TurnOnCandle()
{
if (_candleLife <= 0f) return;
_isCandleOn = true;
candleLight.enabled = true;
TransitionWeightToAimingCandleLight();
if (candleMesh != null)
candleMesh.SetActive(true);
}
public void TurnOffCandle()
{
_isCandleOn = false;
candleLight.enabled = false;
candleFlame.Stop();
TransitionWeightToNotAimingCandleLight();
PlayerManager.GetInstance()._PlayerMovement._CharacterAnimator.SetBool("IsWallInFront", false);
}
public void TransitionWeightToAimingCandleLight()
{
TransitionWeightToAimingCandleLightCoroutine = StartCoroutine(TransitionWeightAimingCandleLight(multiAimConstraintPlayersRightHand.weight, 1, 2));
if (TransitionWeightToNotAimingCandleLightCoroutine != null)
{
StopCoroutine(TransitionWeightToNotAimingCandleLightCoroutine);
TransitionWeightToNotAimingCandleLightCoroutine = null;
}
}
public void TransitionWeightToNotAimingCandleLight()
{
TransitionWeightToNotAimingCandleLightCoroutine = StartCoroutine(TransitionWeightAimingCandleLight(multiAimConstraintPlayersRightHand.weight, 0, 2));
if (TransitionWeightToAimingCandleLightCoroutine != null)
{
StopCoroutine(TransitionWeightToAimingCandleLightCoroutine);
TransitionWeightToAimingCandleLightCoroutine = null;
}
}
public void ReduceCandleLife(float amount)
{
_candleLife = Mathf.Max(0f, _candleLife - amount);
if (_candleLife == 0f)
TurnOffCandle();
}
public void RefillCandle(float amount)
{
_candleLife = Mathf.Clamp(_candleLife + amount, 0f, maxCandleLife);
}
public void FullyRefillCandle()
{
_candleLife = maxCandleLife;
}
public float GetCandleLifePercent()
{
return _candleLife / maxCandleLife;
}
private IEnumerator TransitionWeightAimingCandleLight(float startWeight, float targetWeight, float speed)
{
float elapsedTime = 0f;
while (elapsedTime < multiAimConstraintTransitionDuration)
{
elapsedTime += Time.deltaTime;
float t = Mathf.Clamp01(elapsedTime / multiAimConstraintTransitionDuration);
multiAimConstraintPlayersRightHand.weight = Mathf.Lerp(startWeight, targetWeight, speed * t);
yield return null;
}
// Ensure the target weight is reached precisely
multiAimConstraintPlayersRightHand.weight = targetWeight;
//canPressButtonToOpenOrCloseFlashlight = true;
if (!isUsingCandle)
{
candleMesh.SetActive(false);
}
}
}