The objective is to create a small flying object that moves around in a realistic way. For this project, that means as if it were alive, and obeying the rules of physics. Everyone probably has a good idea of what that means, but it can be hard to describe exactly what we mean. In order to simulate something, you have to identify the behaviours that you want to simulate.
Let's take a look at a bird
It moves forward, in the direction it's facing.
Lots of flying objects have this behaviour. The thrust that moves them always pushes forward.
They take time to turn
And its often dependant on speed. Most flying creatures and vehicles cannot instantly change direction, they have a turning circle.
It stays approximately in the same x and y orientation.
Sure they may roll in turns and stick their nose in the air to go up, but most living things prefer to have gravity pointing down, most machines work better when gravity is always in the same direction. If you want to play with pitch and rolls, the vehicle code may be what you need. For this project, keeping the pet upraight is going to be good enough.
It moves further in the x-y plane.
Most flying things, perhaps with the exception of rockets tend to move more in a horizontal direction than in the vertical plane.
Why not use llMoveToTarget
llMoveToTarget fails the realism test. It moves the object in a direct straight line to the target. We want our object to move forward and turn. llMoveToTarget moves to a new location in so many seconds, we want our object to move to a target at a certain speed. Plus living things rarely move to an exact location, they go somewhere that is near enough where they want.
Choose random location based on its current location
We want our pet to stay in the rough area that it is rezzed in. So any location it moves to should be relative to its current position.
You know, like a bird.
Return to its owner if it strays too far
We dont want our pet wandering off. So the requirement is for it to stay near its owner and react to the owner moving.
Have a highly re-usable movement script
Having a good, reliable physical movement script has no end of uses. So we want to design it so that it can be resused.
The object of this example is to provide the very basic design for a flying creature. Since everyone will create different things, the design must be easy to expand.
The methods used in this example add a few limitations to the model. This example works best for small, light objects like small birds, droids and other irritating flying things.
Number of Primitives
Because the pet is going to be a physical
object, there is a limit on the number of primitives
the object can be made of. The object for the pet cannot have more than 32 prims. This is one more than for a vehicle
. This is because the pet doesn't have a driver.
However, this project needs one prim as part of the object avoidance system. So you're back to using 31 prims.
The object must be designed to move in the direction of its x axis and its top should be in the direction of the z axis. The movement code will be pushing the object in this direction. If your model isn't lined up correctly, it will fly wonky. To check your pet's axis orientation, edit it and make sure the "local axis" check box is selected. The arrows should now show the object's local orientation.
However, if you have real problems with this, the prim saved for the object avoidance can be as the parent
prim to line the model up correctly.
To make the pet actually hover, the buoyancy
function is going to be used. A buoyant object cannot float if it weighs over 90 kg. This is because the buoyancy uses up energy
. For this project, all you need to know is that your object cannot weigh more than 90kg. Use the llGetMass()
function to find the mass of your pet. If you have real problems getting the weight down, try hollowing your prims. The type of material
doesn't affect the mass.
LSL has a Finite State Machine
architecture. FSMs are great for game AI and autonomous agents
(Which is what our pet is). FSMs work best if each FSM (Or script) performs a single discrete function. We are going to take advantage of this by splitting the pet's code into three, each performing a specific function:
This script will decide what to do. It will decide whether to perform a random action or move to an new location. Once it has decided what to do, it will tell the other scripts to do it. It will keep track of where the owner is, and if the pet strays too far, tell the movement script to move towards the owner.
The movement script will wait for an order to move and then move the pet to that location. Once it has reached the location, it will tell the other scripts that it has happened. All the physics functions will be in here. It will have simple object avoidance.
Anything we occasionally want the pet to do, like say something, breath fire, say hallo to someone will be coded in this script. It will wait for the brain to tell it to do something, pick a random action and when it has finished, tell the brain script that it has finished. If it needs to move the pet, it will tell the movement script where to move to. This script will be very different for each pet.
One of the objectives is to create re-usable code. By making the movement script separate you can just drop into a new project and start working on your control script. Likewise, the brain script is going to have a lot of code that is going to be common across a range of projects. Plus, although it is small at the moment, it can grow as you design more functions.
By using three scripts, an entirely new pet can be created by dropping the brain and movement script into a new model, and then creating a new random events script.
to the Create a flying pet home page
to the Script Library