Not signed in (Sign In)

Discussion Tag Cloud

Categories

Vanilla 1.1.9 is a product of Lussumo. More Information: Documentation, Community Support.

    • CommentAuthorole
    • CommentTimeFeb 3rd 2014
     
    I saw a lot of coasters on NLE so far that poorly implemented onboard music. Most made the error of using static sounds instead of stream sounds. Static sounds are great for sound effects, but they are hard to handle right for onboard music. Also most coasters I saw only worked properly for one train and for the first row in the first car. I would like to take the opportunity to show you a solution that works best with least effort using stream sounds. There is a special API for attaching a stream sound to a train, that was designed for onboard music and the following script makes use of it. It will automatically mute the music when the player is off-ride and will automatically play at full volume with stereo when the player is on-ride. It works for all trains of a coaster and for all cars and seats. The only drawback is that the music will be muted when off-ride.

    What you need to use: A coaster with two trigger points. The first trigger point will switch the music on when the train passes the trigger. The second one is used to switch the music off. You also need a music file in the ogg format. Here is the code: Save it to a file called 'OnboardMusic.nlvm' (watch out, the filenames are case sensitive in scripting) and attach it to your coaster.

    The names of the triggers and the music file name can be customized inside the script to match your file and triggers, the corresponding constants are at line 5,6 and 7.


    import com.nolimitscoaster.*;

    public class OnboardMusic extends Script implements TrackTriggerListener
    {
    private static final String musicFile = "music.ogg";
    private static final String startMusicTriggerName = "startmusic";
    private static final String stopMusicTriggerName = "stopmusic";

    private TrackTrigger startMusicTrig;
    private TrackTrigger stopMusicTrig;

    public bool onInit()
    {
    Coaster coaster = sim.getCoasterForEntityId(getParentEntityId());
    if (coaster == null)
    {
    System.err.println("This script must be attached to a coaster");
    return false;
    }

    startMusicTrig = coaster.getTrackTrigger(startMusicTriggerName);
    if (startMusicTrig == null)
    {
    System.err.println("TrackTrigger not found: '" + startMusicTriggerName + "'");
    return false;
    }

    startMusicTrig.addTrackTriggerListener(this);

    stopMusicTrig = coaster.getTrackTrigger(stopMusicTriggerName);
    if (stopMusicTrig == null)
    {
    System.err.println("TrackTrigger not found: '" + stopMusicTriggerName + "'");
    return false;
    }

    stopMusicTrig.addTrackTriggerListener(this);

    for (int i=0; i<coaster.getTrainCount(); ++i)
    {
    StreamedSound music = StreamedSound.loadFromFile(musicFile);
    if (music == null)
    {
    System.err.println("Music file cannot be found or opened: '" + musicFile + "'");
    return false;
    }

    Train train = coaster.getTrainAt(i);

    train.setOnboardStreamedSound(music);
    }

    return true;
    }



    public void onTrainEntering(TrackTrigger trigger, Train train)
    {
    StreamedSound music = train.getOnboardStreamedSound();
    if (music != null)
    {
    if (trigger == startMusicTrig)
    {
    music.stop();
    music.play();
    }
    else if (trigger == stopMusicTrig)
    {
    music.stopFaded(5.0f);
    }
    }
    }

    public void onTrainLeaving(TrackTrigger trigger, Train train)
    {

    }

    }
    •  
      CommentAuthorgeforcefan
    • CommentTimeFeb 4th 2014
     
    Posted By: oleThe only drawback is that the music will be muted when off-ride.


    This was the main reason, why the community was looking for another solution.
    • CommentAuthorDTrigger05
    • CommentTimeFeb 6th 2014 edited
     
    Posted By: geforcefanThis was the main reason, why the community was looking for another solution.


    Personally I'm happy with that trade off. Optimally, I'd like it to effectively play in a bubble around the train (so it can be heard off-ride only as it passes, as in real life). But in my experience, in order to get the audio anywhere above a whisper it ended up being so loud the music could be heard anywhere in the park. (ie: hearing X2's music clearly while anywhere on Viper). But perhaps my scripting wasn't up to par...I'm not terribly well versed in it yet.
  1.  
    I've got an idea, don't know whether it's already done. But you can attach a scene object to the car with a script and attach sound to that scene object with a script.

    With the script that attaches the sound to the scene object you can edit the float distance and float falloff.

    This way you can control the 'buble' of sound around a train, and you could even control it per car or per seat

    I think I will try this tomorrow :P
    • CommentAuthorole
    • CommentTimeApr 3rd 2014
     
    "Attaching" basically means that you request the car's transformation (position and orientation) and apply that to a scene object. What you want is to "attach" a sound to a scene object, that basically means you take the position of the scene object and apply it to a sound. Of course you can do it, but you can do the same by simply taking the position of the car and apply it to the sound directly without using any scene object at all. Same result!
  2.  
    True but with an nl2sco attached you van easely chance the position of the sound and have it visible in the editor. Plus I want to add small speakers anyway.

    But I think I will give the direct way a try aswell. ;)

    But will this 'long way around' decrease performance? Apart from rendering the speaker 3ds offcourse.
  3.  
    Is there still no way to have the sound audible (from the train) in walk/fly view?
  4.  
    I just found out there is xD
    Forgot to read all the forums before posting, here is a script that will allow a sound to be placed in the environment and attaching it to the train.


    (it's in the comment by gforcefan posted on Jan 14th 2014)
    http://forum.nolimits-exchange.com/comments.php?DiscussionID=3147&page=1

    This way you can hear it from fly view and walk view when the train passes by
  5.  
    Nice! Thanks a lot.
    • CommentAuthorspinba11
    • CommentTimeApr 8th 2014
     
    Can we have different music for each train?
    • CommentAuthorole
    • CommentTimeApr 8th 2014 edited
     
    Yes you can have different music for each train. Here is a very basic example for 2 trains...


    public bool onInit()
    {
    ...
    StreamedSound music;
    Train train;

    music = StreamedSound.loadFromFile("file1.ogg");
    train = coaster.getTrainAt(0);
    train.setOnboardStreamedSound(music);

    music = StreamedSound.loadFromFile("file2.ogg");
    train = coaster.getTrainAt(1);
    train.setOnboardStreamedSound(music);
    ...
    }
    •  
      CommentAuthorXpress
    • CommentTimeApr 8th 2014 edited
     
    Not too difficult to figure out how to work this, I'm happy to say.

    Just implemented onboard audio on a ride I'm working on. But there is one thing, how do you control the fade out with the 'stopmusic' trigger? I want it to fade out quicker.

    EDIT, I figured it out. The "(5.0f)" value edits fade out time.
  6.  
    how can I play 2 separate sounds in 2 different places?
    • CommentAuthorTheBeatles
    • CommentTimeApr 13th 2014
     
    So.. I have an issue. My on-board audio consists of 3 (bare minimum, I'll probably have more) parts. They all start and stop at different times, and I can't seem to get them to work correctly. "Station" just keeps restarting every time it rolls over any of the six triggers detailed here:



    The three segments I have are:
    1. Station ambiance
    2. Safety spiel/restraint check
    3. On-board soundtrack (music)

    Can anyone help me figure out how to get all three of them working? If you can help me, I can provide all of the NL2 files for you.
    • CommentAuthorPePpO
    • CommentTimeApr 13th 2014
     
    Please copy your script here.
    • CommentAuthorTheBeatles
    • CommentTimeApr 13th 2014
     
    CODE FOR STATION AMBIANCE

    import com.nolimitscoaster.*;

    public class StationMusic extends Script implements TrackTriggerListener
    {
    private static final String stationFile = "station.ogg";
    private static final String startStationTriggerName = "startstation";
    private static final String stopStationTriggerName = "endstation";

    private TrackTrigger startStationTrig;
    private TrackTrigger stopStationTrig;

    public bool onInit()
    {
    Coaster coaster = sim.getCoasterForEntityId(getParentEntityId());
    if (coaster == null)
    {
    System.err.println("This script must be attached to a coaster");
    return false;
    }

    startStationTrig = coaster.getTrackTrigger(startStationTriggerName);
    if (startStationTrig == null)
    {
    System.err.println("TrackTrigger not found: '" + startStationTriggerName + "'");
    return false;
    }

    startStationTrig.addTrackTriggerListener(this);

    stopStationTrig = coaster.getTrackTrigger(stopStationTriggerName);
    if (stopStationTrig == null)
    {
    System.err.println("TrackTrigger not found: '" + stopStationTriggerName + "'");
    return false;
    }

    stopStationTrig.addTrackTriggerListener(this);

    for (int i=0; i<coaster.getTrainCount(); ++i)
    {
    StreamedSound music = StreamedSound.loadFromFile(stationFile);
    if (music == null)
    {
    System.err.println("Music file cannot be found or opened: '" + stationFile + "'");
    return false;
    }

    Train train = coaster.getTrainAt(i);

    train.setOnboardStreamedSound(music);
    }

    return true;
    }



    public void onTrainEntering(TrackTrigger trigger, Train train)
    {
    StreamedSound music = train.getOnboardStreamedSound();
    if (music != null)
    {
    if (trigger == startStationTrig)
    {
    music.stop();
    music.play();
    }
    else if (trigger == stopStationTrig)
    {
    music.stopFaded(2.0f);
    }
    }
    }

    public void onTrainLeaving(TrackTrigger trigger, Train train)
    {

    }

    }


    CODE FOR RESTRAINT CHECK/SAFETY SPIEL

    import com.nolimitscoaster.*;

    public class BarMusic extends Script implements TrackTriggerListener
    {
    private static final String barFile = "bar.ogg";
    private static final String startBarTriggerName = "startbar";
    private static final String stopBarTriggerName = "endbar";

    private TrackTrigger startBarTrig;
    private TrackTrigger stopBarTrig;

    public bool onInit()
    {
    Coaster coaster = sim.getCoasterForEntityId(getParentEntityId());
    if (coaster == null)
    {
    System.err.println("This script must be attached to a coaster");
    return false;
    }

    startBarTrig = coaster.getTrackTrigger(startBarTriggerName);
    if (startBarTrig == null)
    {
    System.err.println("TrackTrigger not found: '" + startBarTriggerName + "'");
    return false;
    }

    startBarTrig.addTrackTriggerListener(this);

    stopBarTrig = coaster.getTrackTrigger(stopBarTriggerName);
    if (stopBarTrig == null)
    {
    System.err.println("TrackTrigger not found: '" + stopBarTriggerName + "'");
    return false;
    }

    stopBarTrig.addTrackTriggerListener(this);

    for (int i=0; i<coaster.getTrainCount(); ++i)
    {
    StreamedSound music = StreamedSound.loadFromFile(barFile);
    if (music == null)
    {
    System.err.println("Music file cannot be found or opened: '" + barFile + "'");
    return false;
    }

    Train train = coaster.getTrainAt(i);

    train.setOnboardStreamedSound(music);
    }

    return true;
    }



    public void onTrainEntering(TrackTrigger trigger, Train train)
    {
    StreamedSound music = train.getOnboardStreamedSound();
    if (music != null)
    {
    if (trigger == startBarTrig)
    {
    music.stop();
    music.play();
    }
    else if (trigger == stopBarTrig)
    {
    music.stopFaded(2.0f);
    }
    }
    }

    public void onTrainLeaving(TrackTrigger trigger, Train train)
    {

    }

    }
    • CommentAuthorTheBeatles
    • CommentTimeApr 13th 2014
     
    CODE FOR ON-BOARD MUSIC

    import com.nolimitscoaster.*;

    public class OnboardMusic extends Script implements TrackTriggerListener
    {
    private static final String musicFile = "music.ogg";
    private static final String startMusicTriggerName = "startmusic";
    private static final String stopMusicTriggerName = "endmusic";

    private TrackTrigger startMusicTrig;
    private TrackTrigger stopMusicTrig;

    public bool onInit()
    {
    Coaster coaster = sim.getCoasterForEntityId(getParentEntityId());
    if (coaster == null)
    {
    System.err.println("This script must be attached to a coaster");
    return false;
    }

    startMusicTrig = coaster.getTrackTrigger(startMusicTriggerName);
    if (startMusicTrig == null)
    {
    System.err.println("TrackTrigger not found: '" + startMusicTriggerName + "'");
    return false;
    }

    startMusicTrig.addTrackTriggerListener(this);

    stopMusicTrig = coaster.getTrackTrigger(stopMusicTriggerName);
    if (stopMusicTrig == null)
    {
    System.err.println("TrackTrigger not found: '" + stopMusicTriggerName + "'");
    return false;
    }

    stopMusicTrig.addTrackTriggerListener(this);

    for (int i=0; i<coaster.getTrainCount(); ++i)
    {
    StreamedSound music = StreamedSound.loadFromFile(musicFile);
    if (music == null)
    {
    System.err.println("Music file cannot be found or opened: '" + musicFile + "'");
    return false;
    }

    Train train = coaster.getTrainAt(i);

    train.setOnboardStreamedSound(music);
    }

    return true;
    }



    public void onTrainEntering(TrackTrigger trigger, Train train)
    {
    StreamedSound music = train.getOnboardStreamedSound();
    if (music != null)
    {
    if (trigger == startMusicTrig)
    {
    music.stop();
    music.play();
    }
    else if (trigger == stopMusicTrig)
    {
    music.stopFaded(2.0f);
    }
    }
    }

    public void onTrainLeaving(TrackTrigger trigger, Train train)
    {

    }

    }
    • CommentAuthorspinba11
    • CommentTimeApr 15th 2014
     
    I've got it to work but I want different music on each train, I saw the reply that said how to do it but I can't get it to work, I don't know where to put the extra bit of script.
  7.  
    Where do you place the music file to make it work?
    • CommentAuthorsolomon123
    • CommentTimeJul 23rd 2014
     
    ^^in the same map as your parkfile is in
    • CommentAuthorbenhenryc
    • CommentTimeJan 21st 2015
     
    This script is phenomenal. Easy to use and learn from. Thank you! I have one question (and feel free to link me elsewhere if this question has been answered before... I've looked but I cannot find it).

    Let's say I have two sound cues that I'd like to play over the coarse of a coaster's run... for example: one on-board audio cue before a coaster's launch, and then a second on-board audio cue right after the launch.

    I've created two separate scripts (with distinct extension titles on the top line) and each cue has an on and off trigger (4 triggers in total). What happens is that my pre-launch audio plays twice... once where it should and a second where the after-launch cue should start.

    It makes me think that maybe the streaming audio is being cleared from the simulator's cache after the first play? Any suggestions?

    Many thanks!
    • CommentAuthorWomp83
    • CommentTimeAug 6th 2015
     
    So did anyone work out how to have multiple different on-board audio scripts running (using Ole's on-board music script up top) without having one audio track repeat itself at each different track trigger?
    I'm currently having the same issue that Beatles was having further up the page.. (and a few others as well by the looks of it)
    •  
      CommentAuthorbestdani
    • CommentTimeAug 6th 2015 edited
     
    I guess this could be caused by the train.getOnboardStreamedSound() method. I think using a single script that triggers the all sounds instead of one script per sound could solve this.
    • CommentAuthorWomp83
    • CommentTimeAug 6th 2015
     
    And is there such a script already floating around here by any chance?
    •  
      CommentAuthorbestdani
    • CommentTimeAug 6th 2015
     
    At least now it is.

    import com.nolimitscoaster.*;

    public class CoasterMusic extends Script implements TrackTriggerListener
    {
    private static final bool playsOnInit = false; //set this to true when the last music file should be playing by default on initialisation
    private StreamedSound[] music = new StreamedSound[]{
    //>>>>> enter the music file name(s) here, the name of the music file must exactly match the name specified between the quotes
    StreamedSound.loadFromFile("music1.ogg"),
    StreamedSound.loadFromFile("music2.ogg"),
    StreamedSound.loadFromFile("music3.ogg")
    };
    private static final String[] startMusicTriggerName = new String[]{
    //>>>>> enter the trigger file name(s) here, the name of the trigger must exactly match the name specified between the quotes
    "music1",
    "music2",
    "music3"
    };
    private static final String[] stopMusicTriggerName = new String[]{
    //>>>>> enter the stop trigger name(s) here that stop the music playback
    "stop"
    };

    private TrackTrigger[] startMusicTrig;
    private TrackTrigger[] stopMusicTrig;
    private StreamedSound curMusic;

    public bool onInit()
    {
    Coaster coaster = sim.getCoasterForEntityId(getParentEntityId());
    if (coaster == null)
    {
    System.err.println("This script must be attached to a coaster");
    return false;
    }

    if(startMusicTriggerName.length != music.length){
    System.err.println("The number of specified music files is not the same as the number of specified trigger names!");
    return false;
    }
    startMusicTrig = new TrackTrigger[startMusicTriggerName.length];
    for(int i=0; i<startMusicTriggerName.length; i++){
    startMusicTrig[i] = coaster.getTrackTrigger(startMusicTriggerName[i]);
    if (startMusicTrig[i] == null)
    {
    System.err.println("TrackTrigger not found: '" + startMusicTriggerName[i] + "'");
    return false;
    }
    //music[i] = StreamedSound.loadFromFile(startMusicTriggerName[i]+musicFileExt);
    if (music[i] == null)
    {
    System.err.println("Music file number "+(i+1)+" not found!");
    return false;
    }
    startMusicTrig[i].addTrackTriggerListener(this);
    }
    stopMusicTrig = new TrackTrigger[stopMusicTriggerName.length];
    for(int i=0; i<stopMusicTriggerName.length; i++){
    stopMusicTrig[i] = coaster.getTrackTrigger(stopMusicTriggerName[i]);
    if (stopMusicTrig[i] == null)
    {
    System.err.println("TrackTrigger not found: '" + stopMusicTriggerName[i] + "'");
    return false;
    }
    stopMusicTrig[i].addTrackTriggerListener(this);
    }
    for(int i=0; i<coaster.getTrainCount(); i++){
    if(playsOnInit) coaster.getTrainAt(i).setOnboardStreamedSound(music[music.length-1]);
    }
    return true;
    }

    public void onTrainEntering(TrackTrigger trigger, Train train)
    {
    for(int i=0; i<startMusicTrig.length; i++){
    if(startMusicTrig[i] == trigger){
    train.setOnboardStreamedSound(music[i]);
    train.getOnboardStreamedSound().play();
    return;
    }
    }

    for(int i=0; i<stopMusicTrig.length; i++){
    if(stopMusicTrig[i] == trigger){
    train.getOnboardStreamedSound().stop();
    return;
    }
    }
    }

    public void onTrainLeaving(TrackTrigger trigger, Train train)
    {

    }

    }
    • CommentAuthorWomp83
    • CommentTimeAug 7th 2015
     
    ^ Awesome. Thank you so much for that Dan, that's exactly what i was after.
    Small question about it. How would i modify it so the audio fades out, rather than stops suddenly? Other than adding a carefully timed volume fade to the audio track itself..
    •  
      CommentAuthorrcth
    • CommentTimeAug 7th 2015
     
    music.stopFaded(2.0f);
    • CommentAuthorWomp83
    • CommentTimeAug 7th 2015 edited
     
    Cool, thanks for that, rcth.
  8.  
    Im Getting a Error that says "OnboardMusic.nlvm' in Line 1: Syntax Error