#how to use AudioClips?

1 messages · Page 1 of 1 (latest)

thorn fjord
#

im trying to pass array of AudioClips to this script, but it wont show up in the editor. Is this the wrong AudioClip class?

You can see the old C# script that im converting to TS (it's disabled). You can see it has a public AudioClips array that shows in editor. That's how the new TS script should be too.

lost rapids
#

Audio clips are at runtime in the browser just urls. So you'll receive string[]
AudioClipModel is a special type from the timeline

#

Make sure to make using serializable() a habit too

@serializable()
audioClips : string[];

@serializable(Object3D)
myObjectReference : Object3D;

@serializable(Object3D)
myObjects : Object3D[]
#

you can omit the type parameter in serializable() for strings, numbers, bools (js primitive types) and for arrays it's the array content type (see third example above 🙂 )

#

If you want to use codegen with audioclips you can do a little trick like this:

// declare custom AudioClip type somewhere
type AudioClip = string;
// in your script:
@serializable()
myClips : AudioClip[]; // < the component compiler will use known types, in this case it'll know AudioClip from UnityEngine.AudioClip
thorn fjord
#

Ahh amazing i think that will work. Is there a certain folder assets should go in for a Needle project? I ask because when AudioClip tries to play i get this error here.

Also, i see in the web project assets folder that these assets did transfer from unity, so im a bit confused why they are not found

lost rapids
#

Are you trying to use them directly? Then try call resolveUrl(this.sourceIdentifier, myAudioClipUrl) from your script

thorn fjord
#

was using them like this. I'll try resolveUrl if i can figure out what to put for the arguments

lost rapids
#

this.audioSource.play(this.audioClips[i]) should work as well

#

resolveUrl(this.sourceIdentifier, yourUrl) is what you use - but you dont have to if you use the AudioSource and set the clip there

thorn fjord
#

So there's a way to do it without AudioSource? How's that work? The resolveUrl stuff worked to fix those errors, but still didnt play audio. Just gave warning in console saying "failed getting sound." - I think may be due to bug in AudioSource. Right here it uses "this.Sound" but everywhere else it uses "this.sound"

#

here's warning in console in case that's useful

lost rapids
#

If you just want to play the clip you can use the three audio code yourself or just a html audio element 🙂 (depending on your needs)

thorn fjord
# lost rapids Can you share your code again?
import { AudioSource, Behaviour, GameObject, Text, resolveUrl, serializable } from "@needle-tools/engine"

type AudioClip = string;

export class SubtitleController extends Behaviour {

    @serializable()
    audioClips: AudioClip[]

    public subtitles: string[]
    @serializable()
    private audioSource: AudioSource
    private tMP_Text: Text
    public blankTimeAtEnd: number[]
    public upperDoor: GameObject
    public videoPanel: GameObject

    constructor() {
        super()
        this.audioClips = []
        this.subtitles = []
        this.blankTimeAtEnd = []
    }

    start() {
        this.audioSource = this.gameObject.getComponent(AudioSource) as any
        console.log('audioSource==', this.audioSource)
        this.tMP_Text = this.gameObject.getComponent(Text) as any

        if (this.gameObject.name !== "market down") {
            this.audio()
        }
    }

    async audio() {
        if (this.gameObject.name === "intro") {
            await new Promise(resolve => setTimeout(resolve, 2000))
        }
        for (let i = 0; i < this.audioClips.length; i++) {
            this.audioSource.clip = this.audioClips[i]
            this.tMP_Text.text = this.subtitles[i]
            // this.audioSource.play(this.audioSource.clip)
            this.audioSource.play(resolveUrl(this.sourceId, this.audioSource.clip))

            await new Promise(resolve => setTimeout(resolve, (this.audioClips[i].length + this.blankTimeAtEnd[i]) * 1000))

            if (i === this.audioClips.length - 1) {
                this.tMP_Text.text = ""
                if (this.gameObject.name === "intro") {
                    this.upperDoor.traverse((entity) => {
                        const audioComponent = entity.getComponent(AudioSource)
                        if (audioComponent) {
                            audioComponent.play()
                        }
                    })
                }
            }
        }
    }
}

thorn fjord
lost rapids
#

You dont need to do it for audiosource because it already matches the type name in unity (UnityEngine.AudioSource)

#

Its only relevant if your c# component is being generated from typescript btw

thorn fjord
lost rapids
#

If it doesnt find the type you can annotate it too, one second

thorn fjord
#

like this?

@serializable()
//@type UnityEngine.SceneManager
private sceneManager: SceneManager

Didnt seem to work. Also, that link doesnt work for me

lost rapids
#

Above @serializable i think

#

Oh strange, on second

#

When working in Unity or Blender then you will notice that when you create a new Needle Engine component in Typescript or Javascript it will automatically generate a Unity Csub component or a Blender panel for you.
This is thanks to the magic of the Needle component compiler that runs behind the scenes in an editor environment and watches ch...

thorn fjord
#

hmm thought this would work, but didnt:

// @type UnityEngine.SceneManagement.SceneManager
@serializable()
private sceneManager: SceneManager
lost rapids
#

@serializable(SceneManager)

#

Is what you need too of the scene manager is a component that you made

thorn fjord
#

ive never seen SceneManager used as a field, so maybe that's related. It's always used as SceneManager.LoadScene("scenename") - in c# at least

#

undefined in browser

lost rapids
#

Did you make a class named scene manager?

#

Otherwise what we have is a SceneSwitcher

lost rapids
thorn fjord
lost rapids
#

We dont export C# code so you cant import unity c# classes like that and use them in the browser - it only exports their data! Sorry if this was misleading