// Camera Follower
// Created by Water Rogers for IBM/Opensource
// Purpose
// --------------------------------------------------------------
// This script shows you how you can make an object physical, and
// have it follow your camera around.
// Requirements
// --------------------------------------------------------------
// A single prim is all that is necessary for this example.
// Usage
// --------------------------------------------------------------
// Permissions to track your camera are required for it to work
// correctly. Type "follow" to track the camera. Type "stop" to
// stop tracking the camera. Touching the object will also start
// tracking the camera.
// GLOBALS
// --------------------------------------------------------------
integer g_ListenChannel = 0; // This is the listen channel
float g_Timer = 0.10; // This is the timer call rate
// FUNCTIONS
// --------------------------------------------------------------
permissions()
{
// Since this block of code is used more then once in the main
// loop, it's a good idea to make it a function.
// Get the permissions
if(llGetPermissions() & PERMISSION_TRACK_CAMERA)
{
// Permissions were passed, so we make the object physical
// and start the timer
llSetStatus(STATUS_PHYSICS, TRUE);
llSetTimerEvent(g_Timer);
}
else
{
// Permissions were not passed, so we make the object static,
// set the timer to 0, and Request permissions.
llSetStatus(STATUS_PHYSICS, FALSE);
llSetTimerEvent(FALSE);
llRequestPermissions(llGetOwner(), PERMISSION_TRACK_CAMERA);
}
}
// EVENTS
// --------------------------------------------------------------
default
{
state_entry()
{
// Collision Sounds and Sprites can be replaced. We make them
// empty strings so there are no sounds or sprites if the camera
// happens to knock up against a wall.
llCollisionSound("", 0);
llCollisionSprite("");
// Make a listener to listen for commands the owner may use.
llListen(g_ListenChannel, "", llGetOwner(), "");
// Call the permissions() function block
permissions();
}
on_rez(integer start_param)
{
// The object was just rezzed out of inventory, so call up the
// permissions() function block
permissions();
}
touch_start(integer num_detected)
{
// The object was touched, so first we make sure that the owner
// touched the object, and if so... call the permissions()
// function block
if(llDetectedKey(0) == llGetOwner()) permissions();
}
listen(integer channel, string name, key id, string message)
{
// Turn all commands into lowercase using llToLower()
message = llToLower(message);
if(message == "stop")
{
// The owner said "stop", so we'll turn off the object by
// making the object static, and setting the timer to 0
llSetStatus(STATUS_PHYSICS, FALSE);
llSetTimerEvent(FALSE);
}
else if(message == "follow")
{
// The owner said "follow", so we call up the permissions()
// function block
permissions();
}
}
run_time_permissions(integer perm)
{
// Permissions were requested through the permissions() function
// block. Remember to use bitwise opperands when dealing with
// conditional statements for permissions.
if(perm & PERMISSION_TRACK_CAMERA)
{
// The owner granted permissions, so we set the object to
// physical, and fire up the timer.
llSetStatus(STATUS_PHYSICS,TRUE);
llSetTimerEvent(g_Timer);
}
}
timer()
{
// Here the timer uses llMoveToTarget() which simply moves the
// object to wherever the owner's camera is, and about 1 meter
// above (as to not obtruct the owner's view. The owner will
// not be able to see the object under most circumstances, so if
// the owner wants to get rid of the object, they must first say
// "stop" in chat to make the object stop moving. Then they can
// click on the object a lot easier to delete or take.
llMoveToTarget(llGetCameraPos() + <0.0, 0.0, 1.0>, 0.20);
// Since the object looks a bit awkward only moving to position and
// not rotating properly, we call a simple sensor looking for the
// owner's current position.
llSensor("", llGetOwner(), AGENT, 96, PI);
}
sensor(integer num_detected)
{
// After we get the owner's position, we'll have the object just
// look at the owner using it's forward axis. This gives a nice
// effect. If you wanted to track the owners actual camera rotations
// then you would have to use llGetCameraRot() and make the correct
// calculations. We do it this way for simplicity.
llLookAt(llDetectedPos(0), 0.32, 0.32);
}
}