projectEli/Assets/NeoFPS/Core/MotionGraphs/Behaviours/SurfaceAudioBehaviour.cs
2022-11-06 20:28:33 -05:00

182 lines
6.9 KiB
C#

#if !NEOFPS_FORCE_QUALITY && (UNITY_ANDROID || UNITY_IOS || UNITY_TIZEN || (UNITY_WSA && NETFX_CORE) || NEOFPS_FORCE_LIGHTWEIGHT)
#define NEOFPS_LIGHTWEIGHT
#endif
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NeoFPS.Constants;
using NeoFPS.CharacterMotion;
using NeoFPS.CharacterMotion.Parameters;
namespace NeoFPS.CharacterMotion.Behaviours
{
[MotionGraphElement("Audio/SurfaceAudio", "SurfaceAudioBehaviour")]
[HelpURL("https://docs.neofps.com/manual/motiongraphref-mgb-surfaceaudiobehaviour.html")]
public class SurfaceAudioBehaviour : MotionGraphBehaviour
{
[SerializeField, Tooltip("The surface audio library for the audio clips.")]
private SurfaceAudioData m_AudioData = null;
[SerializeField, Tooltip("When should the audio be played.")]
private When m_When = When.OnEnter;
[SerializeField, Tooltip("The direction to cast in to get the surface type.")]
private Direction m_CastDirection = Direction.Down;
[SerializeField, Tooltip("The direction vector for the ray to cast when detecting surface type.")]
private Vector3 m_CastVector = Vector3.down;
[SerializeField, Tooltip("The direction vector parameter for the ray to cast when detecting surface type. If none is selected, defaults to character down.")]
private VectorParameter m_VectorParameter = null;
[SerializeField, Tooltip("The downward raycast length for the ground surface test.")]
private float m_MaxRayDistance = 1f;
private ICharacterAudioHandler m_AudioHandler = null;
private RaycastHit m_Hit = new RaycastHit();
public enum Direction
{
Down,
LocalVector,
WorldVector,
WorldParameter,
WorldParameterInverse,
LocalParameter,
LocalParameterInverse
}
public enum When
{
OnEnter,
OnExit,
Both
}
public override void OnEnter()
{
// Get audio handler
if (m_AudioHandler == null)
m_AudioHandler = controller.localTransform.GetComponent<ICharacterAudioHandler>();
// Play the relevant audio clip
if (m_When != When.OnExit && m_AudioHandler != null && m_AudioData != null)
PlayAudio(GetGroundSurface());
}
public override void OnExit()
{
if (m_When != When.OnEnter && m_AudioHandler != null && m_AudioData != null)
PlayAudio(GetGroundSurface());
}
FpsSurfaceMaterial GetGroundSurface ()
{
FpsSurfaceMaterial result = FpsSurfaceMaterial.Default;
#if NEOFPS_LIGHTWEIGHT
// Get raycast direction
Vector3 direction = Vector3.down;
switch (m_CastDirection)
{
case Direction.LocalVector:
direction = controller.localTransform.rotation * m_CastVector;
break;
case Direction.WorldVector:
direction = m_CastVector;
break;
case Direction.WorldParameter:
if (m_VectorParameter != null)
direction = m_VectorParameter.value.normalized;
break;
case Direction.WorldParameterInverse:
if (m_VectorParameter != null)
direction = -m_VectorParameter.value.normalized;
break;
case Direction.LocalParameter:
if (m_VectorParameter != null)
direction = controller.localTransform.rotation * m_VectorParameter.value.normalized;
break;
case Direction.LocalParameterInverse:
if (m_VectorParameter != null)
direction = controller.localTransform.rotation * -m_VectorParameter.value.normalized;
break;
}
#else
// Get raycast direction
Vector3 direction = Vector3.zero;
switch (m_CastDirection)
{
case Direction.Down:
direction = -controller.characterController.up;
break;
case Direction.LocalVector:
direction = controller.localTransform.rotation * m_CastVector;
break;
case Direction.WorldVector:
direction = m_CastVector;
break;
case Direction.WorldParameter:
if (m_VectorParameter != null)
direction = m_VectorParameter.value.normalized;
else
direction = -controller.characterController.up;
break;
case Direction.WorldParameterInverse:
if (m_VectorParameter != null)
direction = -m_VectorParameter.value.normalized;
else
direction = -controller.characterController.up;
break;
case Direction.LocalParameter:
if (m_VectorParameter != null)
direction = controller.localTransform.rotation * m_VectorParameter.value.normalized;
else
direction = -controller.characterController.up;
break;
case Direction.LocalParameterInverse:
if (m_VectorParameter != null)
direction = controller.localTransform.rotation * -m_VectorParameter.value.normalized;
else
direction = -controller.characterController.up;
break;
}
#endif
// Get charactercontroller info
var cc = controller.characterController;
var radius = cc.radius;
var normalisedHeight = radius / cc.height;
// Raycast for surface type
if (cc.RayCast(normalisedHeight, direction * (m_MaxRayDistance + radius), Space.World, out m_Hit, PhysicsFilter.Masks.BulletBlockers, QueryTriggerInteraction.Ignore))
{
// Get surface ID from ray hit
Transform t = m_Hit.transform;
if (t != null)
{
BaseSurface s = t.GetComponent<BaseSurface>();
if (s != null)
result = s.GetSurface(m_Hit);
else
result = 0;
}
}
return result;
}
void PlayAudio(FpsSurfaceMaterial surface)
{
float volume = 1f;
AudioClip clip = m_AudioData.GetAudioClip(surface, out volume);
if (clip != null)
m_AudioHandler.PlayClip(clip, FpsCharacterAudioSource.Feet, volume);
}
}
}