401 lines
13 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|