Я использую Unity 2019.2.14f1 для создания простой 3D-игры.
В этой игре я хочу воспроизводить звук в любое время, когда мой игрок сталкивается с gameObject с определенным тегом.
MainCamera имеет Audio Listener, и я использую Cinemachine Free Look, который следит за моим аватаром, внутри ThridPersonController (я использую тот, который входит в Стандартные активы - но я спрятал Итана и добавил свой собственныйперсонаж / аватар).
Объект gameObject с тегом, который я хочу уничтожить, имеет источник звука:
Чтобы звук воспроизводился при столкновении, я начал с создания пустого игрового объекта, который будет служить AudioManager, и добавил к нему новый компонент (скрипт C #):
using UnityEngine.Audio;
using System;
using UnityEngine;
public class AudioManager : MonoBehaviour
{
public Sound[] sounds;
// Start is called before the first frame update
void Awake()
{
foreach (Sound s in sounds)
{
s.source = gameObject.AddComponent<AudioSource>();
s.source.clip = s.clip;
s.source.volume = s.volume;
s.source.pitch = s.pitch;
}
}
// Update is called once per frame
public void Play (string name)
{
Sound s = Array.Find(sounds, sound => sound.name == name);
s.source.Play();
}
}
И создал скрипт Sound. .cs:
using UnityEngine.Audio;
using UnityEngine;
[System.Serializable]
public class Sound
{
public string name;
public AudioClip clip;
[Range(0f, 1f)]
public float volume;
[Range(.1f, 3f)]
public float pitch;
[HideInInspector]
public AudioSource source;
}
После этого в пользовательском интерфейсе Unity я зашел к Инспектору в gameObject AudioManager и добавил в скрипт новый элемент, который я назвал: CatchingPresent.
В сценарии персонажа от третьего лица, чтобы уничтожить игровой объект (с определенным тегом) при столкновении с ним, я добавил следующее:
void OnCollisionEnter(Collision other)
{
if (other.gameObject.CompareTag("Present"))
{
Destroy(other.gameObject);
count = count - 1;
SetCountText();
}
}
Этоработает правильно, так как этот конкретный объект исчезает при столкновении. Теперь, чтобы воспроизводить звук «CatchingPresent» в любое время, когда проигрыватель сталкивается с объектом с тегом, в данном случае, Present
, я попытался добавить следующее к if
в OnCollisionEnter
:
FindObjectOfType<AudioManager>().Play("CatchingPresent");
Но я получаю ошибку:
Не удалось найти тип или имя пространства имен 'AudioManager' (вы пропустилииспользуя директиву или ссылку на сборку?)
AudioManager.instance.Play("CatchingPresent");
Но я получаю ошибку:
Имя 'AudioManager 'не существует в текущем контексте
Поскольку все ошибки компилятора должны быть исправлены перед входом в Playmode, любые указания о том, как заставить воспроизводиться звук после столкновения между игроком и gameObjectс тегом Present
приветствуется.
Редактировать 1: Предполагая, что это полезно, здесь идет полный ThirdPersonUserControl.cs:
using System;
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.CrossPlatformInput;
namespace UnityStandardAssets.Characters.ThirdPerson
{
[RequireComponent(typeof (ThirdPersonCharacter))]
public class ThirdPersonUserControl : MonoBehaviour
{
public Text countText;
public Text winText;
private int count;
private ThirdPersonCharacter m_Character; // A reference to the ThirdPersonCharacter on the object
private Transform m_Cam; // A reference to the main camera in the scenes transform
private Vector3 m_CamForward; // The current forward direction of the camera
private Vector3 m_Move;
private bool m_Jump; // the world-relative desired move direction, calculated from the camForward and user input.
private void Start()
{
count = 20;
SetCountText();
winText.text = "";
// get the transform of the main camera
if (Camera.main != null)
{
m_Cam = Camera.main.transform;
}
else
{
Debug.LogWarning(
"Warning: no main camera found. Third person character needs a Camera tagged \"MainCamera\", for camera-relative controls.", gameObject);
// we use self-relative controls in this case, which probably isn't what the user wants, but hey, we warned them!
}
// get the third person character ( this should never be null due to require component )
m_Character = GetComponent<ThirdPersonCharacter>();
}
private void Update()
{
if (!m_Jump)
{
m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
}
}
// Fixed update is called in sync with physics
private void FixedUpdate()
{
// read inputs
float h = CrossPlatformInputManager.GetAxis("Horizontal");
float v = CrossPlatformInputManager.GetAxis("Vertical");
bool crouch = Input.GetKey(KeyCode.C);
// calculate move direction to pass to character
if (m_Cam != null)
{
// calculate camera relative direction to move:
m_CamForward = Vector3.Scale(m_Cam.forward, new Vector3(1, 0, 1)).normalized;
m_Move = v*m_CamForward + h*m_Cam.right;
}
else
{
// we use world-relative directions in the case of no main camera
m_Move = v*Vector3.forward + h*Vector3.right;
}
#if !MOBILE_INPUT
// walk speed multiplier
if (Input.GetKey(KeyCode.LeftShift)) m_Move *= 0.5f;
#endif
// pass all parameters to the character control script
m_Character.Move(m_Move, crouch, m_Jump);
m_Jump = false;
}
void OnCollisionEnter(Collision other)
{
if (other.gameObject.CompareTag("Present"))
{
Destroy(other.gameObject);
count = count - 1;
SetCountText();
//FindObjectOfType<AudioManager>().Play("CatchingPresent");
AudioManager.instance.Play("CatchingPresent");
}
}
void SetCountText()
{
countText.text = "Missing: " + count.ToString();
if (count == 0)
{
winText.text = "You saved Christmas!";
}
}
}
}
Редактировать 2: Иерархия в единстве: