2
\$\begingroup\$

New developer here, looking to do some raycasting and controlling audio positioning in 3D space based on the raycasts' interactions with other objects.

I've got the raycast 'casting' and able to report back where it collides with other objects and managed to get audio to play back at that raycast point using AudioSource.PlayClipAtPoint()

However, PlayClipAtPoint doesn't allow me to change the audio's 3D attenuation settings as a one shot audio object is generated and then removed immediately and I can't find any parameters to control this new object apart from a volume 0-1 float value.

I came across this post by Aldonaletto:

function PlayClipAt(clip: AudioClip, pos: Vector3): AudioSource; { var tempGO = GameObject("TempAudio"); // create the temp object tempGO.transform.position = pos; // set its position var aSource = tempGO.AddComponent(AudioSource); // add an audio source aSource.clip = clip; // define the clip // set other aSource properties here, if desired aSource.Play(); // start the sound Destroy(tempGO, clip.length); // destroy object after clip duration return aSource; // return the AudioSource reference } 

But can't seem to get the local function to work in Unity as it complains about not using C# version 7 or above. If I upgrade the C# version in Visual Studio, I get compiler errors on Unity's side.

I'm a little bit stuck, and would appreciate some advice! Some code below, just not sure what to put into the result of the if statement to get this to work.

using System.Collections; using System.Collections.Generic; using UnityEngine; public class raycasting : MonoBehaviour { public float raycastlength = 3; public AudioClip playthis; public float ER_Volume = 1F; // Use this for initialization void Start() { //Debug.Log("I'm a sphere, yo!"); } // Update is called once per frame void Update() { RaycastHit hit; Ray forwardray = new Ray(transform.position, Vector3.forward); //draw the raycast in scene view Debug.DrawRay(transform.position, Vector3.forward * raycastlength, Color.white); if (Input.GetMouseButtonDown(0)) { //Debug.Log("We pressed the fire button!"); if (Physics.Raycast(forwardray, out hit, raycastlength)) { if (hit.collider.tag == "evil") { Debug.Log("Raycast Hit!"); Debug.Log("Distance to object:" + hit.distance); //Debug.Log("Object hit point:" + hit.point); //play a sound using playclipatpoint, but this doesn't allow us to change attenuation settings AudioSource.PlayClipAtPoint(playthis, hit.point, ER_Volume); } } } } } 
\$\endgroup\$
1
  • \$\begingroup\$ The example you're looking at is coded in UnityScript, a deprecated JavaScript-like language. If you've pasted it directly, that might be the source of your error - you'll need to translate it to Unity C# syntax. This should be a reasonably straightforward adjustment for which there are many existing guides, but feel free to post a question here if you need help with a particular part of the translation. \$\endgroup\$ Commented Mar 12, 2019 at 16:08

1 Answer 1

1
\$\begingroup\$

Thanks to DMGregory for putting me on to the Unity converter tool. The tool Unity have created seemed to struggle to convert the script for some reason. Instead, I tasked myself with breaking it down and re-creating the function in c~ by hand, and think I figured it out. For the people googling this in the future, I managed to get it to work with an empty prefab called 'playclipat' that has an AudioSource attached to it. The Vector3 in the Instantiate command is "hit.point" as that's part of the raycast. The newly cloned 'playclipat' object is then destroyed after the audio clip has finished.

GameObject playclipatclone = Instantiate(playclipat, hit.point, Quaternion.identity); AudioSource clonecliplength = GetComponent<AudioSource>(); Destroy(playclipatclone,clonecliplength.clip.length); 
\$\endgroup\$
1
  • \$\begingroup\$ Well done. :) For improved performance, you might want to consider 1) using a member variable of type AudioSource, so you can get a reference to the component directly from the Instantiate method without a separate GetComponent() search, and 2) using object pooling, to recycle a collection of these prefabs instead of repeatedly constructing & destroying them. \$\endgroup\$ Commented Mar 12, 2019 at 23:32

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.