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); } } }