|
In this post, I'll show you how to script
a realistic splash when your whale enters and leaves the water. First, you need to add add another prim. This prim will point the Z axis down. Particles come out of the Z-axis in a prim. Add the following script to the new prim, and position it near the blow-hole of your whale. Click it first, then click the whale, and link them so you do not disturb the root prim. The box with the main scripts in it must be Yellow. |
![]() |
This script has several functions. It has an on/off switch. It sprays a water particle in a circle. The circle spins rapidly so that you see a ring of water. The script decides how high the whale is above the water. It then adjusts the spray position so that a ring of water spray rises up from the center of the whale that is always at water level. As the whale rises, the spray gets less.
Download |
|
// particles constants float maxsysage = 0.0; // particles spray forever float maxspeed = 0.3; // max speed 0.3 meters a second float minspeed = 0.15; // and min is about half that. float burstrad = 0.0; // no radius at all integer burstcount = 20; // spray 20 of them float burstrate = 0.01; // really fast.. lets swamp the viewer with particles and spray. float outangle = 0.075; // make a wide cone float inangle = 0; vector omega = <0.0,0.0,0.0>; // no rotation float startalph = 0.75; // start semi-transparent float endalph = 0.015; // end almost invisible vector startscale = <2.0,2.0,2.0>; // start at 2 X the size of the texture vector endscale = <4.0,4.0,4.0>; // and end up twice that float maxage = 1.7; // last for 1.7 seconds vector accel = <0.0, 0.0, 1.0>; // push in the Z axis string texture = ""; // global constants vector pos; vector vel; vector up; float ground = 0.0; float water = 0.0; float height = 0.0; float oscillation = 1.25; float start_mult = 0.1; // when we start up, this makes the water 'rise' over time float rad; integer oscillate = TRUE; integer started = FALSE;
Particles(integer part_on)
{
maxage = 0.001;
if (!part_on) jump particles;
vel = llGetVel() * 0.2;
ground = llGround(vel);
water = llWater(vel);
if (ground < water) {
maxspeed = 2.5;
minspeed = 1.25;
oscillation = 2.0;
endscale = <3.0,3.0,3.0>;
maxage = 2.0;
ground = water;
texture = "7f70a931-6300-8dbc-caca-8b09a9c2cf11";
} else {
maxspeed = 1.75;
minspeed = 0.875;
oscillation = 1.25;
endscale = <4.0,4.0,4.0>;
maxage = 1.75;
texture = "Water Particle - Mist";
}
pos = llGetPos() + vel;
up = llRot2Up(llGetRot());
height = pos.z - ground - 0.5;
height += (1.0 - up.z) * height;
if (height < 6.0 && height > -1.0) {
rad = 1.5 + (oscillate * oscillation);
outangle = PI - llAtan2(rad, height);
inangle = outangle + 0.15;
burstrad = rad / llSin(outangle);
startalph = ((llFabs(height) / -8.57) + 0.8 - (!oscillate * 0.15)) * start_mult;
endalph = ((llFabs(height) / -200.0) + 0.04) * start_mult;
maxsysage = 0.0;
part_on = TRUE;
} else {
maxsysage = 0.01;
part_on = FALSE;
}
@particles;
llParticleSystem([PSYS_PART_FLAGS,
PSYS_PART_INTERP_COLOR_MASK |
PSYS_PART_INTERP_SCALE_MASK |
//PSYS_PART_FOLLOW_VELOCITY_MASK |
PSYS_PART_WIND_MASK,
PSYS_SRC_PATTERN,
PSYS_SRC_PATTERN_ANGLE_CONE,
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,
PSYS_PART_START_ALPHA, startalph,
PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>,
PSYS_PART_END_ALPHA, endalph,
PSYS_PART_START_SCALE, startscale,
PSYS_PART_END_SCALE, endscale,
PSYS_PART_MAX_AGE, maxage,
PSYS_SRC_ACCEL, accel,
PSYS_SRC_TEXTURE, texture,
PSYS_SRC_BURST_RATE, burstrate,
PSYS_SRC_ANGLE_BEGIN, inangle,
PSYS_SRC_ANGLE_END, outangle,
PSYS_SRC_BURST_PART_COUNT, burstcount,
PSYS_SRC_BURST_RADIUS, burstrad,
PSYS_SRC_BURST_SPEED_MIN, minspeed,
PSYS_SRC_BURST_SPEED_MAX, maxspeed,
PSYS_SRC_MAX_AGE, maxsysage,
PSYS_SRC_OMEGA, omega
]);
if (!part_on)
{
llParticleSystem([]); // shut down, not on
} else {
if (started)
{
if (start_mult < 1.0)
start_mult += 0.075;
} else {
if (start_mult > 0.0)
start_mult -= 0.05;
else {
llSetTimerEvent(0.0);
llParticleSystem([]);
}
}
oscillate = !oscillate; // toggle this flag
}
}
default
{
state_entry()
{
llSetTimerEvent(0.0); // turn off particles and timers on boot up
Particles(FALSE);
}
touch_start(integer n)
{
started = TRUE; // if touched, start up
start_mult = 0.1;
llSetTimerEvent(0.01); // rapidly jab the timer
}
llMessageLinked(LINK_SET,0,"on",NULL_KEY); // part of another script
link_message(integer sender, integer num, string str, key id)
{
if (str == "on") {
started = TRUE;
start_mult = 0.1;
llSetTimerEvent(0.01);
} else if (str == "off") {
started = FALSE;
llParticleSystem([]);
Particles(FALSE);
}
}
timer()
{
Particles(TRUE);
}
}