Rework diapason with octo arms
This commit is contained in:
@@ -0,0 +1,357 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using Unheimlich.Audio;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
public class DiapasonEquipmentManager : MonoBehaviour
|
||||
{
|
||||
[Header("References")]
|
||||
[SerializeField] private OctoIkArmsImproved _armsSystem;
|
||||
[SerializeField] private GameObject _diapasonPrefab;
|
||||
[SerializeField] private int _equipmentArmIndex = 1;
|
||||
|
||||
[Header("Detection Settings")]
|
||||
[SerializeField] private LayerMask _soundEmitterLayer;
|
||||
[SerializeField] private float _detectionRadius = 0.15f;
|
||||
[SerializeField] private Transform[] _detectionPoints;
|
||||
|
||||
[Header("Visual Feedback")]
|
||||
[SerializeField] private GameObject _contactFeedbackPrefab;
|
||||
|
||||
[Header("Diapason Animation")]
|
||||
[SerializeField] private string _vibratingBoolParam = "IsVibrating";
|
||||
[SerializeField] private string _tapTriggerParam = "Tap";
|
||||
|
||||
[Header("Tap Settings")]
|
||||
[SerializeField] private AudioClip _tapSound;
|
||||
[SerializeField] [Range(0f, 1f)] private float _tapVolume = 1f;
|
||||
[SerializeField] private float _vibrationDuration = 15f;
|
||||
|
||||
public bool IsEquipped => _isEquipped;
|
||||
public AudioListenable CurrentDetectedEmitter => _currentDetectedEmitter;
|
||||
public bool CanTap => _isEquipped && _currentDetectedEmitter != null && !_isVibrating && !_currentDetectedEmitter.HasBeenTapped;
|
||||
|
||||
public event Action<AudioListenable> OnEmitterDetected;
|
||||
public event Action<AudioListenable> OnEmitterLost;
|
||||
|
||||
private GameObject _spawnedDiapason;
|
||||
private bool _isEquipped = false;
|
||||
private AudioListenable _currentDetectedEmitter;
|
||||
private GameObject _contactFeedback;
|
||||
private bool _isVibrating = false;
|
||||
private AudioSource _audioSource;
|
||||
private Coroutine _vibrationCoroutine;
|
||||
private Animator _diapasonAnimator;
|
||||
private ParticleSystem _diapasonParticles;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if (_armsSystem == null)
|
||||
{
|
||||
_armsSystem = GetComponent<OctoIkArmsImproved>();
|
||||
if (_armsSystem == null)
|
||||
{
|
||||
Debug.LogError("[DiapasonEquipment] OctoIkArmsImproved not found!");
|
||||
}
|
||||
}
|
||||
|
||||
_audioSource = GetComponent<AudioSource>();
|
||||
if (_audioSource == null)
|
||||
{
|
||||
_audioSource = gameObject.AddComponent<AudioSource>();
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (_isEquipped && _armsSystem.GetArmState(_equipmentArmIndex) == ArmState.Equipped)
|
||||
{
|
||||
CheckForSoundEmitters();
|
||||
|
||||
if (Mouse.current != null && Mouse.current.leftButton.wasPressedThisFrame)
|
||||
{
|
||||
if (CanTap)
|
||||
{
|
||||
TapDiapason();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void EquipDiapason()
|
||||
{
|
||||
if (_isEquipped)
|
||||
{
|
||||
Debug.LogWarning("[DiapasonEquipment] Diapason already equipped!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_diapasonPrefab == null)
|
||||
{
|
||||
Debug.LogError("[DiapasonEquipment] Diapason prefab not assigned!");
|
||||
return;
|
||||
}
|
||||
|
||||
_spawnedDiapason = Instantiate(_diapasonPrefab);
|
||||
_spawnedDiapason.SetActive(true);
|
||||
|
||||
_diapasonAnimator = _spawnedDiapason.GetComponentInChildren<Animator>(true);
|
||||
if (_diapasonAnimator == null)
|
||||
{
|
||||
Debug.LogWarning("[DiapasonEquipment] No Animator found on spawned diapason");
|
||||
}
|
||||
else
|
||||
{
|
||||
_diapasonAnimator.enabled = false;
|
||||
}
|
||||
|
||||
_diapasonParticles = _spawnedDiapason.GetComponentInChildren<ParticleSystem>(true);
|
||||
if (_diapasonParticles == null)
|
||||
{
|
||||
Debug.LogWarning("[DiapasonEquipment] No ParticleSystem found on spawned diapason");
|
||||
}
|
||||
|
||||
_armsSystem.EquipObjectOnArm(_equipmentArmIndex, _spawnedDiapason, () => {
|
||||
_isEquipped = true;
|
||||
OnDiapasonEquipped();
|
||||
});
|
||||
}
|
||||
|
||||
public void UnequipDiapason()
|
||||
{
|
||||
if (!_isEquipped)
|
||||
{
|
||||
Debug.LogWarning("[DiapasonEquipment] Diapason not equipped!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_vibrationCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_vibrationCoroutine);
|
||||
_vibrationCoroutine = null;
|
||||
}
|
||||
|
||||
if (_currentDetectedEmitter != null)
|
||||
{
|
||||
_currentDetectedEmitter.SetConcentrating(false);
|
||||
_currentDetectedEmitter.StopListening(cancelConcentrationFade: false);
|
||||
_currentDetectedEmitter = null;
|
||||
}
|
||||
|
||||
_armsSystem.UnequipObjectFromArm(_equipmentArmIndex, () => {
|
||||
_isEquipped = false;
|
||||
_spawnedDiapason = null;
|
||||
OnDiapasonUnequipped();
|
||||
});
|
||||
}
|
||||
|
||||
private void CheckForSoundEmitters()
|
||||
{
|
||||
if (_detectionPoints == null || _detectionPoints.Length == 0)
|
||||
return;
|
||||
|
||||
AudioListenable closestEmitter = null;
|
||||
float closestDistance = float.MaxValue;
|
||||
|
||||
foreach (Transform detectionPoint in _detectionPoints)
|
||||
{
|
||||
if (detectionPoint == null)
|
||||
continue;
|
||||
|
||||
Collider[] hits = Physics.OverlapSphere(detectionPoint.position, _detectionRadius, _soundEmitterLayer);
|
||||
|
||||
foreach (Collider hit in hits)
|
||||
{
|
||||
AudioListenable emitter = hit.GetComponent<AudioListenable>();
|
||||
|
||||
if (emitter != null)
|
||||
{
|
||||
float distance = Vector3.Distance(detectionPoint.position, hit.transform.position);
|
||||
|
||||
if (distance < closestDistance)
|
||||
{
|
||||
closestDistance = distance;
|
||||
closestEmitter = emitter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closestEmitter != _currentDetectedEmitter)
|
||||
{
|
||||
if (_currentDetectedEmitter != null)
|
||||
{
|
||||
OnEmitterExited(_currentDetectedEmitter);
|
||||
}
|
||||
|
||||
_currentDetectedEmitter = closestEmitter;
|
||||
|
||||
if (_currentDetectedEmitter != null)
|
||||
{
|
||||
OnEmitterEntered(_currentDetectedEmitter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDiapasonEquipped()
|
||||
{
|
||||
if (_diapasonAnimator != null)
|
||||
{
|
||||
_diapasonAnimator.enabled = true;
|
||||
_diapasonAnimator.SetBool(_vibratingBoolParam, false);
|
||||
}
|
||||
|
||||
if (_diapasonParticles != null)
|
||||
{
|
||||
_diapasonParticles.Stop();
|
||||
var emission = _diapasonParticles.emission;
|
||||
emission.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDiapasonUnequipped()
|
||||
{
|
||||
_isVibrating = false;
|
||||
_diapasonAnimator = null;
|
||||
_diapasonParticles = null;
|
||||
}
|
||||
|
||||
public void TapDiapason()
|
||||
{
|
||||
if (!CanTap)
|
||||
{
|
||||
Debug.LogWarning("[DiapasonEquipment] Cannot tap: not equipped, no contact, or already tapped");
|
||||
return;
|
||||
}
|
||||
|
||||
ArmEquipment equipment = _armsSystem.GetArmEquipment(_equipmentArmIndex);
|
||||
if (equipment != null)
|
||||
{
|
||||
equipment.PlayTapAnimation();
|
||||
equipment.StartShake();
|
||||
}
|
||||
|
||||
if (_tapSound != null && _audioSource != null)
|
||||
{
|
||||
_audioSource.PlayOneShot(_tapSound, _tapVolume);
|
||||
}
|
||||
|
||||
if (_diapasonAnimator != null)
|
||||
{
|
||||
_diapasonAnimator.SetTrigger(_tapTriggerParam);
|
||||
_diapasonAnimator.SetBool(_vibratingBoolParam, true);
|
||||
}
|
||||
|
||||
if (_diapasonParticles != null)
|
||||
{
|
||||
var emission = _diapasonParticles.emission;
|
||||
emission.enabled = true;
|
||||
_diapasonParticles.Play();
|
||||
}
|
||||
|
||||
_isVibrating = true;
|
||||
|
||||
if (_currentDetectedEmitter != null)
|
||||
{
|
||||
_currentDetectedEmitter.StartListening(transform.position);
|
||||
}
|
||||
|
||||
if (_vibrationCoroutine != null)
|
||||
StopCoroutine(_vibrationCoroutine);
|
||||
_vibrationCoroutine = StartCoroutine(StopVibrationAfterDuration());
|
||||
}
|
||||
|
||||
private IEnumerator StopVibrationAfterDuration()
|
||||
{
|
||||
yield return new WaitForSeconds(_vibrationDuration);
|
||||
|
||||
if (_diapasonAnimator != null)
|
||||
{
|
||||
_diapasonAnimator.SetBool(_vibratingBoolParam, false);
|
||||
}
|
||||
|
||||
if (_diapasonParticles != null)
|
||||
{
|
||||
_diapasonParticles.Stop();
|
||||
var emission = _diapasonParticles.emission;
|
||||
emission.enabled = false;
|
||||
}
|
||||
|
||||
if (_currentDetectedEmitter != null)
|
||||
{
|
||||
_currentDetectedEmitter.StopListening();
|
||||
}
|
||||
|
||||
ArmEquipment equipment = _armsSystem.GetArmEquipment(_equipmentArmIndex);
|
||||
if (equipment != null)
|
||||
{
|
||||
equipment.StopShake();
|
||||
}
|
||||
|
||||
_isVibrating = false;
|
||||
_vibrationCoroutine = null;
|
||||
}
|
||||
|
||||
private void OnEmitterEntered(AudioListenable emitter)
|
||||
{
|
||||
|
||||
emitter.SetConcentrating(true);
|
||||
|
||||
if (_contactFeedbackPrefab != null && _contactFeedback == null)
|
||||
{
|
||||
_contactFeedback = Instantiate(_contactFeedbackPrefab, emitter.transform);
|
||||
_contactFeedback.transform.localPosition = Vector3.zero;
|
||||
}
|
||||
|
||||
OnEmitterDetected?.Invoke(emitter);
|
||||
}
|
||||
|
||||
private void OnEmitterExited(AudioListenable emitter)
|
||||
{
|
||||
emitter.SetConcentrating(false);
|
||||
|
||||
if (!emitter.HasBeenTapped)
|
||||
{
|
||||
emitter.StopListening();
|
||||
}
|
||||
|
||||
if (_contactFeedback != null)
|
||||
{
|
||||
Destroy(_contactFeedback);
|
||||
_contactFeedback = null;
|
||||
}
|
||||
|
||||
if (_diapasonAnimator != null)
|
||||
{
|
||||
_diapasonAnimator.SetBool(_vibratingBoolParam, false);
|
||||
}
|
||||
|
||||
if (_diapasonParticles != null)
|
||||
{
|
||||
_diapasonParticles.Stop();
|
||||
var emission = _diapasonParticles.emission;
|
||||
emission.enabled = false;
|
||||
}
|
||||
|
||||
_isVibrating = false;
|
||||
|
||||
OnEmitterLost?.Invoke(emitter);
|
||||
}
|
||||
|
||||
void OnDrawGizmosSelected()
|
||||
{
|
||||
if (_detectionPoints == null || !_isEquipped)
|
||||
return;
|
||||
|
||||
Gizmos.color = Color.yellow;
|
||||
|
||||
foreach (Transform detectionPoint in _detectionPoints)
|
||||
{
|
||||
if (detectionPoint != null)
|
||||
{
|
||||
Gizmos.DrawWireSphere(detectionPoint.position, _detectionRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user