campfire/Assets/Scripts/CameraBobber.cs

93 lines
2.7 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public enum StepType {
Left,
Right
}
public class CameraBobber : MonoBehaviour {
public Options Options;
public Transform CameraTransform;
public AnimationCurve HeadBobCurve = AnimationCurve.Constant(0, 1, 0);
public float StepDuration;
public float BobMagnitude;
public bool Moving = false;
public bool InAir = false;
public AudioSource FootstepSource;
// TODO: Vary by ground material
public AudioClip[] LandingFootstepClips;
public AudioClip[] RightFootstepClips;
public AudioClip[] LeftFootstepClips;
[Header("Runtime values")]
public StepType LastStep;
private float StepTime = 0;
private bool WasMoving = false;
private bool WasInAir = false;
private Vector3 BasePosition;
private void Start() {
BasePosition = CameraTransform.localPosition;
}
private void Update() {
if (Moving) {
StepTime += Time.deltaTime;
if (StepTime >= StepDuration) {
StepTime -= StepDuration;
if (!InAir) {
AlternateStep();
PlayStepSound(GetClips(LastStep), 1f);
}
}
} else {
StepTime = 0;
}
Vector3 TargetPosition = BasePosition;
if (Options.CameraBobbing) {
if (InAir) {
TargetPosition = BasePosition + Vector3.up * HeadBobCurve.Evaluate(0.5f) * BobMagnitude;
} else {
TargetPosition = BasePosition + Vector3.up * HeadBobCurve.Evaluate(StepTime / StepDuration) * BobMagnitude;
}
}
CameraTransform.localPosition = Vector3.Lerp(CameraTransform.localPosition, TargetPosition, 10f * Time.deltaTime);
if (Moving != WasMoving && !InAir) {
AlternateStep();
PlayStepSound(GetClips(LastStep), 0.7f);
} else if (WasInAir != InAir) {
AlternateStep();
PlayStepSound(LandingFootstepClips, 1f);
}
WasMoving = Moving;
WasInAir = InAir;
}
private void AlternateStep() {
LastStep = LastStep == StepType.Left ? StepType.Right : StepType.Left;
}
private AudioClip[] GetClips(StepType stepType) {
switch (stepType) {
default:
case StepType.Left:
return LeftFootstepClips;
case StepType.Right:
return RightFootstepClips;
}
}
private void PlayStepSound(AudioClip[] clips, float volumeModifier) {
if (clips.Length > 0) {
FootstepSource.PlayOneShot(clips[Random.Range(0, clips.Length)], volumeModifier);
}
}
}