Originally posted by alanr
Can we attach lights to moving objects - such as cars?
Lights are a property of scenery object (.nl2sco) files. Therefore lights can
only be attached to scenery objects. But those objects can be attached to trains using a script.
The following script will attach an object to the lead car on a coaster. It needs to be assigned to the scenery object file containing the light, and then the scenery object placed within 5 meters of the train.
import com.nolimitscoaster.*;
import nlvm.math3d.*;
public class attach_object extends Script
{
private SceneObject sco; // Scenery object handle.
private Train train; // Train handle.
private static final float range = 5; // Defines a range (in meters) within which the scenery object will attach to a train.
private Vector3f posOut = new Vector3f(0,0,0); // Will store the scenery object's position based on the car's position.
private Vector3f pitchHeadBankOut = new Vector3f(0,0,0); // Will store the scenery object's orientation based on the car's orientation.
private Matrix4x4f carOrientation = new Matrix4x4f(); // Will store the car's orientation.
//**************************************************************************************
// onInit is called when the scene object is loaded. Use this for initialization.
// onInit should return true if initialization succeeds, else false.
// If onInit returns false then the script will be disabled automatically and onNextFrame will never be called.
//**************************************************************************************
public bool onInit()
{
// ********************************************
// Get the scene object handle.
// ********************************************
sco = sim.getSceneObjectForEntityId(getParentEntityId());
if (sco == null)
{
System.err.println("Not a scene object.");
return false;
}
// ********************************************
// Determine whether there is a track within range of the scenery object.
// ********************************************
TrackPos trackPos = sim.findNearestCoasterTrack(sco.getTranslation(), range);
if (trackPos == null)
{
System.err.println("No track found within a range of " + range + " meters.");
return false;
}
// ********************************************
// Determine whether there is a train within range of the scenery object.
// ********************************************
Coaster coaster = trackPos.getCoaster();
train = coaster.findNearestTrain(sco.getTranslation(), range);
if (train == null)
{
System.err.println("No train found within a range of " + range + " meters.");
return false;
}
return true;
}
public void onNextFrame(float tick)
{
// ********************************************
// Obtain the orientation of the first car
// ********************************************
train.getCarMatrix(0, carOrientation);
// ********************************************
// Convert the matrix obtained from getCarMatrix()
// to the Euler angle vector used in setRotation()
// ********************************************
Tools.matrixToPitchHeadBankPos(carOrientation, pitchHeadBankOut, posOut);
// ********************************************
// Update the scene object's rotation and
// position for this frame.
// ********************************************
sco.setRotation(pitchHeadBankOut);
sco.setTranslation(posOut);
}
}
1. In the NL2SCO Editor, create a new .nl2sco object with a light. Save it with whatever name and in whatever location you like.
2. Create a plain text file named attach_object.nlvm
3. Copy/Paste the code above into the text file.
4. Save the script in the same directory as your .nl2sco file.
5. Back in the Scripts tab of the NL2SCO Editor, assign the script to the .nl2sco object (using the "Script Class" input)
6. Import the .nl2sco object into the scene and place near a train.
It should work out of the box with any object.