campfire/Assets/Scripts/ItemVR.cs

120 lines
4.3 KiB
C#

using UnityEngine;
/*
* <summary>A replacement for the Item class in VR contexts.</summary>
*/
[RequireComponent(typeof(Burnable))]
public class ItemVR : MonoBehaviour {
public BurnQuality IgnitedQuality;
public float IgniteDuration;
public bool Ignited = false;
public bool Extinguished = false;
public float TorchDuration;
public float TorchWarnDuration;
public float MinDistanceFromTerrain;
public float FuelTickingMultiplierOnGround;
[Header("Burning indicators")]
public GameObject StickObject;
public GameObject DestroyedOnExtinguish;
public GameObject TorchObject;
public ParticleSystem FireParticles;
public Light TorchLight;
public Color WarnColor;
public GameObject FireVolume;
public AudioSource TorchSound;
public AudioClip[] FireClips;
[Header("Runtime values")]
public float TorchFuel;
private Burnable Burnable;
private int BurningSourceCount = 0;
private float IgnitionStartTime = -1;
private Color NormalColor;
private Terrain Terrain;
private Vector3 TorchLightBasePosition;
private void Start() {
Burnable = GetComponent<Burnable>();
NormalColor = TorchLight.color;
TorchObject.SetActive(Ignited);
StickObject.SetActive(!Ignited);
Terrain = GameObject.FindGameObjectWithTag("Main Terrain").GetComponent<Terrain>();
TorchLightBasePosition = TorchLight.transform.localPosition;
}
private void Update() {
if (Extinguished) {
return;
}
if (Ignited) {
float FuelTickAmount = Time.deltaTime;
TorchLight.transform.localPosition = TorchLightBasePosition;
Vector3 LightPosition = TorchLight.transform.position;
float MinHeight = (Terrain.SampleHeight(LightPosition) + Terrain.transform.position.y) + MinDistanceFromTerrain;
if (LightPosition.y < MinHeight) {
// The light is on ground, clamp it above round (so the light doesn't look weird)
// and start ticking fuel at a higher rate
LightPosition.y = MinHeight;
FuelTickAmount *= FuelTickingMultiplierOnGround;
}
TorchLight.transform.position = LightPosition;
TorchFuel -= FuelTickAmount;
if (TorchFuel < TorchWarnDuration) {
TorchLight.color = Color.Lerp(TorchLight.color, WarnColor, 5f * Time.deltaTime);
} else {
TorchLight.color = Color.Lerp(TorchLight.color, NormalColor, 5f * Time.deltaTime);
}
if ((TorchSound.clip.length - TorchSound.time) <= Time.deltaTime || !TorchSound.isPlaying) {
TorchSound.clip = FireClips[Random.Range(0, FireClips.Length)];
TorchSound.time = 0;
TorchSound.Play();
}
float FuelFactor = 1f / (Mathf.Max(0, TorchDuration + 0.5f - TorchFuel) * 4f + 1);
TorchSound.volume = 0.5f + 0.5f * FuelFactor - (TorchFuel < TorchWarnDuration ? 0.1f : 0);
if (TorchFuel <= 0) {
FireParticles.Stop();
FireVolume.layer = gameObject.layer;
TorchLight.range = Mathf.Lerp(TorchLight.range, 0, 10f * Time.deltaTime);
if (TorchLight.range < 0.01f) {
Destroy(DestroyedOnExtinguish);
Extinguished = true;
}
}
} else if (!Ignited && !Burnable.BurningInCampfire && IgnitionStartTime != -1 && Time.time - IgnitionStartTime >= IgniteDuration) {
Ignited = true;
TorchFuel = TorchDuration;
TorchObject.SetActive(true);
FireParticles.Play();
StickObject.SetActive(false);
Burnable.Quality = IgnitedQuality;
}
}
private void OnTriggerEnter(Collider collider) {
if (!Ignited && collider.gameObject.layer == LayerMask.NameToLayer("Fire")) {
if (BurningSourceCount == 0) {
IgnitionStartTime = Time.time;
}
BurningSourceCount++;
}
}
private void OnTriggerExit(Collider collider) {
if (!Ignited && collider.gameObject.layer == LayerMask.NameToLayer("Fire")) {
BurningSourceCount--;
if (BurningSourceCount == 0) {
IgnitionStartTime = -1;
}
}
}
}