Суббота, 18.05.2024, 17:17
Secondrus
Приветствую Вас Гость | RSS

Меню сайта
Мини-чат
Управление LSL скриптами.
SecondLife включает средство для того, чтобы задать script в пределах существующих объектов. Чтобы создавать объект, 
щелнити правой кнопкой мыши на земле или воде и левым щелчком "Create" на круглом меню, которое появляется.
Когда Вы делаете это, "меню манипуляции объекта" откроется на левой стороне вашего экрана, и ваш курсор изменится на "волшебную палочку".
Левым щелчком еще раз на основании. Вы тогда услышите таинственный грохот, и объект появится.
Это будет некоторая 3-мерная геометрическая фигура, типа куба, конуса или сферы.
Цветные линии, происходящие от того объекта используются для того, чтобы делать определенные позиционные изменения в объекте.
Возвратитесь к меню манипуляции объекта и нажмите кнопку "More". В пределах расширенного меню, левым щелчком на "Object",
и Вы будете видеть варианты изменения объекта.
Левый щелчок на "Content" и Вы будете видеть список, связанный с объектом.
Левый щелчок на кнопке "New Script", и откроется окно редактирования "Script". Окно редактирования имеет  редактор скриптов,
где Вы можете напечатать или прикрепить новый script. Это будет выглядеть так:



Script по умолчанию:
default
{
state_entry()
{
llSay( 0, "Hello, Avatar!");
}

touch_start(integer total_number)
{
llSay( 0, "Touched.");
}
}
Левый щелчок на кнопке "Save". Вы увидите сообщение "Compile successful, saving...".
После короткой паузы Вы должны увидеть сообщение "Save complete". 
Сохраните script, дотроньтесь до объекта и Вы увидите сообщение "Hello, Avatar!".



Программа, которая изменяет цвет и размер объекта каждый раз,
когда до объекта дотронулись.

integer counter;

default
{
state_entry()
{
llSay( 0, "Hello, Avatar! Touch to change color and size.");
counter = 0;
}

touch_start(integer total_number)
{ // инструкции, когда объект затронут.
counter = counter + 1;

// выберирает три случайных компонента цвета RGB между 0. и 1.0.
float redness = llFrand( 1.0 );
float greenness = llFrand( 1.0 );
float blueness = llFrand( 1.0 );

// объединение цветных компонентов в вектор и использование этого вектора
// устанавливает цвет объекта.
vector prim_color = < redness, greenness, blueness >;
llSetColor( prim_color, ALL_SIDES ); // set object color to new color.

// выберает случайное число между 0. и 10. для использования как фактор масштаба.
float new_scale = llFrand(10.0) + 1.0;
llSetScale(< new_scale, new_scale, new_scale > ); // set object scale.
llSay( 0, "Touched by angel number " + (string)counter);
}
}

Изменение внешности объекта.
Вот программа, которая изменяет цвет и размер объекта каждые две секунды в течение 40 секунд, когда объект затронут.
integer counter;
integer second;

default
{
state_entry()
{
llSay( 0, "Hello, Avatar! Touch to change color and size.");
counter = 0;
}

touch_start(integer total_number)
{
counter = counter + 1;

llSay( 0, "Touched by angel number " + (string)counter);

llSetTimerEvent( 2 ); // create a "timer event" every 2 seconds.
}

timer()
{
second++;

// выбирает три случайных компонента цвета RGB между 0. и 1.0.
float red = llFrand( 1.0 );
float green = llFrand( 1.0 );
float blue = llFrand( 1.0 );

// объединение цветных компонентов в вектор и использование этого вектора
// чтобы установить цвет объекта.
vector prim_color = < red, green, blue >;
llSetColor( prim_color, ALL_SIDES );

// выбирание случайного числа между 0. и 10 для использования как фактор масштаба.
// запускает new_scale = llFrand (10.0);
llSetScale(< new_scale, new_scale, new_scale > );

if ( second > 19 ) // then time to wrap this up.
{
llSetColor( < 0, 0, 0 >, ALL_SIDES );

llSay( 0, "Object now resting and resetting script." );
llResetScript();
}
}
}

Изменение положения объекта.


Программа может изменить положение объекта при использовании llSetPos () функция.
Вот  script, который повторно помещает объект, используя llSetPos () каждую секунду в течение  20 секунд.
Новые положения выбирается, используя вектор, построенный в течение каждого повторения из 3 случайныхположений между 0.0 и 10.0 метров.
integer counter;
integer second;
vector startPosition;

default
{
state_entry()
{
llSay( 0, "Hello, Avatar! Touch to change position.");
counter = 0;
startPosition = llGetPos();
}

touch_start(integer total_number)
{
counter = counter + 1;

llSay( 0, "Touched by angel number " + (string)counter);

llSetTimerEvent( 1 ); // определяет Timer Event каждую секунду.
}

timer() // установите эту команду каждый раз,
// когдатаймер включается.
{
second++;

// выберите три случайных расстояния между 0. и 10.0.
float X_distance = llFrand( 10.0 );
float Y_distance = llFrand( 10.0 );
float Z_distance = llFrand( 10.0 );

// объединить эти компоненты расстояния в вектор ииспользовать
// его, чтобы увеличить исходную позицию.
vector increment = < X_distance, Y_distance, Z_distance >;
vector newPosition = startPosition + increment;
llSetPos( newPosition ); // снова установить объект.

if ( second > 19 ) // время оборота.
{
// и возвращение объекта на исходную позицию...
while ( llVecDist( llGetPos(), startPosition ) > 0.001)
{
llSetPos( startPosition );
}

llSay( 0, "Object now resting and resetting script." );
llResetScript();
}
}
}

Система простых частиц.
Возможно сгенерировать объект на испускние "частиц" под управлением сценария.
Например, объект может быть установлен, чтобы испустить пузырьки, искры, огонь, и т.д.
Чтобы видеть это в действии, Вы можете изменить сценарий в предыдущем разделе, чтобы испустить частицы, в то время как объект двигается.
llParticleSystem( 
[
PSYS_PART_FLAGS, PSYS_PART_WIND_MASK | PSYS_PART_EMISSIVE_MASK,
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_EXPLODE,
PSYS_PART_START_COLOR, <1,0,0>
] );
второй запрос :
llParticleSystem( [] );
Вот снимок автора, стоящего рядом с объектом, испускающим пылающии красные шары:



Каждая параметр отделен единственной запятой. Первый элемент - название параметра,
и второй элемент - значение, которое будет связано с тем параметром.
Например, цветом частицы управляет параметр PSYS_PART_START_COLOR, и посланное значение - <1, 0, 0>,
которое определяет "красный" цвет.
Некоторые параметры могут иметь несколько значений. Например
PSYS_PART_FLAGS, PSYS_PART_WIND_MASK | PSYS_PART_EMISSIVE_MASK
и PSYS_PART_WIND_MASK и PSYS_PART_EMISSIVE_MASK помещают в пределах параметра PSYS_PART_FLAGS.
(Вы можете установить сколько угодно значений по мере необходимости, отделяя их логическим символом OR (|) как показано выше.
Отметьте, что частицы сгенерированы в местном масштабе на каждом клиенте в пределах диапазона.
Это означает, что они не помещают большую загрузку в сервер и могут быть весьма реалистическими.

Вращение объекта.
Есть несколько способов представить вращательное движение.
Функция Euler использует вектор, где каждый компонент определяет движение в одном из 3 направлений - x,y,z.

В то время как функция Euler является довольно обладающей интуицией, вращательный момент может также быть представлен как "кватернионы".
Кватернионы (осуществлены через встроенный тип переменной, названный "rotation"),
которые составлены из 4 направлений- x, y, z, и s ( тип- число с плавающей точкой).
О первых 3 направлениях можно думать как определение оси, вокруг которой происходит вращение, в то время как 4-ое описывает количество вращения.

Вращение может быть определено, используя функцию Euler и затем преобразовано к представлению кватерниона через llEuler2Rot ().
Например, <0, 10, 0> определяет вращение 10 степеней вокруг оси Y, и может быть преобразован к форме кватерниона, используя запрос
llEuler2Rot( < 0, 10 * DEG_TO_RAD, 0 >)
приводящий к <0.00000, 0.08716, 0.00000, 0.99619>.

Когда вращение, описывающее "текущую ориентацию" объекта известно, новая ориентация может быть получена просто,
умножая одно вращение на другое. Вот - script примера, который иллюстрирует использование для петли,
чтобы моделировать непрерывное вращение объекта в одном месте. Используется llGetRot (),
чтобы начать вращение, описывающее текущую ориентацию и затем используется llSetRot (), чтобы переориентировать объект.
default
{
state_entry()
{
llSay( 0, "Hello, Avatar!");
vector startPoint = llGetPos();
}

touch_start(integer total_number)
{
llSay( 0, "Touched." );

// Define a rotation of 10 degrees around the Y-axis.
rotation Y_10 = llEuler2Rot( < 0, 10 * DEG_TO_RAD, 0 > );

integer i;
for( i = 1; i < 100; i++ )
{
// rotate object in the X-Z plane around its own Y-axis.
rotation newRotation = llGetRot() * Y_10;

llSetRot( newRotation );
}
llSay( 0, "Rotation stopped" );
}
}

 Вращение, определенное каждому клиенту.
Вращение может также моделироваться при использовании функции llTargetOmega ().
Движение, произведенное этой функцией произведено независимо каждым клиентом SecondLife, который может наблюдать двигающийся объект.
В результате движение намного более гладко, но поведение будет отличаться немного для каждого клиента.
Вот - пример, который вращает объект и вокруг Y и вокруг Z:
default
{
state_entry()
{
llTargetOmega( < 0, 1, 1 >, .2 * PI, 1.0 );
}
}
Отметьте, что этот подход менее гибок чем вращательное движение, произведенное, используя llSetRot ().


Вращение объекта по орбите.
Вот - сценарий, который делает орбиту объекта X-Y вокруг пункта <3, 3, 3> от его исходной позиции.
Орбитальное движение моделируется через для цикл, который снова устанавливает объект 15 степенями в течение каждой итерации.
Отметьте, что llSetPos () используется вместо llSetRot ().
default
{
state_entry()
{
llSay( 0, "Hello, Avatar!");
vector startPoint = llGetPos();
rotationCenter = startPoint + < 3, 3, 3 >;
}

touch_start(integer total_number)
{
llSay( 0, "Touched." );

// Define a "rotation" of 10 degrees around the z-axis.
rotation Z_15 = llEuler2Rot( < 0, 0, 15 * DEG_TO_RAD > );

integer i;
for( i = 1; i < 100; i++ ) // limit simulation time in case of
{ // unexpected behavior.
vector currentPosition = llGetPos();

vector currentOffset = currentPosition - rotationCenter;

// rotate the offset vector in the X-Y plane around the
// distant point of rotation.
vector rotatedOffset = currentOffset * Z_15;
vector newPosition = rotationCenter + rotatedOffset;

llSetPos( newPosition );
}
llSay( 0, "Orbiting stopped" );
}
}
Вот - снимок автора, едущего на большом оранжевом конусе, вращающемся под управлением кода выше используемого сценария, только представленных.
Конус вращается вокруг оси Y по кругу в отдалении от центра.



Отметьте, что также возможно объединить это движение по орбите с местным вращением,
произведенным при использовании llSetTargetOmega (), как показано в этом сценарии.
Это достигается запуская местное вращение наряду с таймером, который периодически выполняет команды, чтобы переместить вращающийся объект по орбите.
Этот подход может использоваться, чтобы моделировать лунное движение вокруг орбитальной планеты (если орбитальный объект - две связанных сферы).


Два примера, использования LSL- физики.
LSL включает способность моделировать некоторые из физических законов, управляющих энергией, гравитацией, вращающим моментом, и т.д.
Эта способность происходит из ряда встроенных функций, которые осуществляют эффекты этих законов.
Чтобы видеть "физику" в действии, создайте объект, откройте меню Объекта,
проверьте "Physics", измените высоту оси Z вашего объекта сделав на несколько метров выше основания, и затем закрыть окно Объекта.
Ваш объект должен тогда упасть, и если основание покатое, и ваш объект является достаточно сферическим,он может даже катиться по спуску.
Следующий подлинник устанавливает физику при использовании запроса функции
llSetStatus( 1, TRUE )
и затем, когда объект затронут, использует команду
llApplyImpulse( < 0.0, 0.0, z_force >, FALSE );
применяеться мгновенный вертикальный импульс:
default
{
state_entry()
{
llSay( 0, "Hello, Avatar! Touch to launch me straight up.");
llSetStatus( 1, TRUE ); // включите физику.
}

touch_start(integer total_number)
{
vector start_color = llGetColor( ALL_SIDES ); // сохраните текущий цвет.
llSetColor( < 1.0, 0.0, 0.0 > , ALL_SIDES ); // set color to red.

float objMass = llGetMass();
float Z_force = 20.0 * objMass;

llApplyImpulse( < 0.0, 0.0, Z_force >, FALSE );

llSay( 0, "Impulse of " + (string)Z_force + " applied." );
llSetColor( start_color , ALL_SIDES ); // set color to green.
}
}
Следующий пример применяет непрерывную восходящую вертикальную силу, используя команду
llSetForce( < 0.0, 0.0, Z_force >, FALSE )
на объекте. Этот запрос функции настраивает силу 0.0 Ньютонов по положительной Оси X, 0.0 Ньютона по положительной Оси Y,
и Ньютонам Z_force по положительной Оси Z.

Так как вес объекта равен массе времен объекта сила серьезности, или 9.8 метров в секунду в секунду,
сила, больше чем 9.8 * objMass должна преодолеть силу серьезности и поднять объект.
В этом подлиннике, Z_force собирается "10.2 * objMass", который должен поднять объект медленно.
Вы можете редактировать подлинник, чтобы изменить этот параметр и наблюдать различные поведения объекта.
vector startPos;
vector curPos;
vector curForce;
integer second;

default
{
state_entry()
{
llSay( 0, "Hello, Avatar! Touch to launch me straight up.");
llSetStatus( 1, TRUE );
startPos = < 0, 0, 0 >;
}

touch_start(integer total_number)
{
startPos = llGetPos();
curPos = startPos;
curForce = < 0, 0, 0 >;
second = 0;

llSetColor( < 1.0, 0.0, 0.0 > , ALL_SIDES ); // set color to red.

float objMass = llGetMass();
float Z_force = 10.2 * objMass;

llSetForce( < 0.0, 0.0, Z_force >, FALSE );

llSay( 0, "Force of " + (string)Z_force + " being applied." );
llSetTimerEvent(1);
}

timer()
{
second++;
curPos = llGetPos();
float curDisplacement = llVecMag( curPos - startPos );

if( ( curDisplacement > 30. ) && // then object is too far away, and
( llGetForce() != < 0.0, 0.0, 0.0 > ) ) // force not already zero,
{ // then let gravity take over, and change color to green.
llSetForce( < 0.0, 0.0, 0.0 >, FALSE );
llSetColor( < 0, 1.0, 0 >, ALL_SIDES );
llSay( 0, "Force removed; object in free flight." );
}

if ( second > 19 ) // then time to wrap this up.
{
// turn object blue and zero force to be safe....
llSetColor( < 0, 0, 1.0 >, ALL_SIDES ); // change color to blue.
llSetForce( < 0, 0, 0 >, FALSE );

// ...move object back to starting position...
// ...after saving current status of Physics attribute.
integer savedStatus = llGetStatus( 1 );
llSetStatus( 1, FALSE ); // turn physics off.
while ( llVecDist( llGetPos(), startPos ) > 0.001)
{
llSetPos( startPos );
}
llSetStatus( 1, savedStatus ); // restore Physics status.

//...and then turn color to black and Reset the script.
llSetColor( < 1, 1, 1 >, ALL_SIDES );
llSetTimerEvent( 0 ); // выключение таймера.
llSay( 0, "Done and resetting script." );
llResetScript(); // return object to ready state.
}
}
}
Отметьте, что может быть трудно управлять объектами в движении в SL.
Например, avatar очевидно теряeт контроль над объектами больше чем на расстоянии в 10 метров.
Script выше имеет две особенности, чтобы помочь поддерживать контроль.
Сначала, использует таймер, как показано в предыдущей программе, контролируя положение объекта, и предпринимая корректирующии действия.
В частности если объект перемещается больше чем на 30 метров от его стартового положения,
script  таймера устраняет приложенную силу при использовании функции llSetForce( < 0, 0, 0 >, FALSE ).
Во вторых, подлинник останавливает моделирование и возвращает объект к его стартовому положению после неподвижного числа событий таймера.
Отметьте, что этот script преднамеренно управляет восприимчивостью объекта к физическим силам.
В частности физика выключена, в то время как объект повторно помещен в его стартовое местоположение,
используя функции скрипта, которые не будут работать, когда физика включена.


Управление объектом через команды, вложенные в текст чата.
Script может быть настроен, чтобы "слушать" продолжающийся диалог чата и отвечать на команды, выпущенные через чат.
Вот - script, который прислушивается к сообщениям чата, прибывающим от владельца объекта, в котором содержиться script.
vector startPosition;
float groundLevel;

default
{
state_entry()
{
llListen( 0, "", llGetOwner(), "");

startPosition = llGetPos();
groundLevel = llGround( startPosition );

llSay( 0, "Control this object with chat commands like:" );
llSay( 0, "'up' or 'down' followed by a distance." );
}

listen( integer channel, string name, key id, string message )
{
// separate the input into blank-delmited tokens.
list parsed = llParseString2List( message, [ " " ], [] );

// get the first part--the "command".
string command = llList2String( parsed, 0 );

// get the second part--the "distance".
string distance_string = llList2String( parsed, 1 );
float distance = ( float )distance_string;

vector position = llGetPos();

if( command == "up" )
{
if( ( position.z + distance ) < (startPosition.z + 10.0 ) )
{
llSetPos( llGetPos() + < 0, 0, distance > ); // move up
llSetText( "Went up " + (string)distance, < 1, 0, 0 >, 1 );
}
else
{
llSetText( "Can't go so high.", < 1, 0, 0 >, 1 );
}
}
else if( command == "down" )
{
if( ( position.z - distance ) > groundLevel )
{
llSetPos( llGetPos() + < 0, 0, -distance > ); // move down
llSetText( "Went down " + (string)distance, < 1, 0, 0 >, 1 );
}
else
{
llSetText( "Can't go so low.", < 1, 0, 0 >, 1 );
}
}
}
}


Управление объектом через Диалоговое окно.
Для объекта является возможным представить ряд вариантов аватару, 
которые могут использоваться, чтобы управлять его поведением.
Вот - программа,которая продвигает объект вниз по оси Z под контролем диалога

integer dialog_channel= 427; // set a dialog channel
list menu = [ "Go up", "Go down" ];
vector startPosition;
float groundLevel;

default
{
state_entry()
{
// arrange to listen for dialog answers (from multiple users)
llListen( dialog_channel, "", NULL_KEY, "");

startPosition = llGetPos();
groundLevel = llGround( startPosition );
}

touch_start(integer total_number)
{
llDialog( llDetectedKey( 0 ), "What do you want to do?", menu,
dialog_channel );
}

listen(integer channel, string name, key id, string choice )
{
vector position = llGetPos();

// if a valid choice was made, implement that choice if possible.
// (llListFindList returns -1 if choice is not in the menu list.)
if ( llListFindList( menu, [ choice ]) != -1 )
{
if ( choice == "Go up" )
{
if( position.z < ( startPosition.z + 10.0 ) )
{
llSetPos( llGetPos() + < 0, 0, 1.0 > ); // move up
}
}
else if( choice == "Go down" )
{
if( position.z > ( groundLevel + 1.0 ) )
{
llSetPos( llGetPos() + < 0, 0, -1.0 > ); // move down
}
}
}
else
{
llSay( 0, "Invalid choice: " + choice );
}
}
}

Всякий раз, когда объект затронут, программа попросит, чтобы пользователь продвинулся вниз.
Диалоговое окно может запросить дополнительные варианты, которые появятся в Диалоговом окне.


Управление объектом командами с клавиатуры.
Также возможно позволить объекту ответить на команды с клавиатуры, которые обычно управляют вашим аватаром.
Например, следующий скрипт спросит разрешение переместить ваш аватар вперед.

vector startPosition;
float groundLevel;

default
{
state_entry()
{
// get permission to take over the avatar's control inputs.
llRequestPermissions( llGetOwner(), PERMISSION_TAKE_CONTROLS );

startPosition = llGetPos();
groundLevel = llGround( startPosition );
}

run_time_permissions( integer perm ) // event for processing
// permission dialog.
{
if ( perm & PERMISSION_TAKE_CONTROLS ) // permission has been given.
{
// go ahead and take over the forward and backward controls.
llTakeControls( CONTROL_FWD | CONTROL_BACK, TRUE, FALSE );
}
}

control( key id, integer held, integer change ) // event for processing
// key press.
{
vector position = llGetPos();

if ( change & held & CONTROL_FWD )
{ // the "move forward" control has been activated.
if( position.z < (startPosition.z + 10.0) )
{
llSetPos( llGetPos() + < 0, 0, 1.0 >); // move up
}
}
else if ( change & held & CONTROL_BACK )
{ // the "move backward" key has been activated.
if( position.z > groundLevel + 1.0 )
{
llSetPos( llGetPos() + < 0, 0, -1.0 >); // move down
}
}
}
}



Два объекта одним вызовом.

Когда Вы касаетесь Object2, llRezObject () будет вызван Object1, и Вы должны видеть, что копия Object1 появляется на 2 метра выше Object2.
default
{
state_entry()
{
llSay( 0, "Hello, Avatar!");
}

touch_start(integer total_number)
{
llSay( 0, "Touched.");

llRezObject("Object1", llGetPos() + < 0, 0, 2 >, ZERO_VECTOR,
ZERO_ROTATION, 42);
}
}



  Создание связанных наборов объектов.
LSL обеспечивает ряд функций для того, чтобы связать и управлять наборами примитивных объектов, иногда называемых "link_sets".
Примитивные объекты, которые соединены, будут вести себя как единственный объект.
Они могут также быть настроены, чтобы общаться друг с другом и передавать определенную информацию между собой.
Вот программа которая спрашивает разрешение связать другие объекты в связанный набор и создает два объекта,
только если получает разрешение связать их, как только они были созданы.
Как только редактирование установлено, подлинник тогда использует llSetLinkColor (), чтобы сделать недавно созданные объекты красными.
Недавно созданные и связанные объекты идентифицированы, используя числа связи "2" и "3" в течение обменов сообщения в пределах linkset,
но к ним можно также обратиться через константы LSL как "LINK_ALL_CHILDREN" или "LINK_SET".
Родительский объект идентифицирован как число "1" связи и можно обратиться как "LINK_ROOT".
integer createdObjectCounter;
integer linkedObjectCounter;

default
{
state_entry()
{
llSay( 0, "Hello, Avatar!");
linkedObjectCounter = 0; // zero the linked object counter.
}

touch_start(integer total_number)
{
if( createdObjectCounter <= 0 ) // nothing has yet been linked,
{ // begin object creation sequence...
// ask for permissions now, since it will be too late later.
llRequestPermissions( llGetOwner(), PERMISSION_CHANGE_LINKS );
}
else // just do whatever should be done upon touch without
{ // creating new objects to link.
// insert commands here to respond to a touch.
}
}

run_time_permissions( integer permissions_granted )
{
if( permissions_granted == PERMISSION_CHANGE_LINKS )
{ // create 2 objects.
llRezObject("Object1", llGetPos() + < 1, 0, 2 >,
ZERO_VECTOR, ZERO_ROTATION, 42);
createdObjectCounter = createdObjectCounter + 1;

llRezObject("Object1", llGetPos() + < -1, 0, 2 >,
ZERO_VECTOR, ZERO_ROTATION, 42);
createdObjectCounter = createdObjectCounter + 1;

}
else
{
llOwnerSay( "Didn't get permission to change links." );
return;
}
}

object_rez( key child_id )
{
llOwnerSay( "rez happened and produced object with key " +
(string)child_id );

// link as parent to the just created child.
llCreateLink( child_id, TRUE );

// if all child objects have been created then the script can
// continue to work as a linked set of objects.
linkedObjectCounter++;
if( linkedObjectCounter >= 2 )
{
// Change all child objects in the set to red (including parent).
llSetLinkColor( LINK_ALL_CHILDREN, < 1, 0, 0 >, ALL_SIDES );

// Make child object "2" half-tranparent.
llSetLinkAlpha( 2, .5, ALL_SIDES );

// Insert commands here to manage subsequent activity of the
// linkset, like this command to rotate the result:
// llTargetOmega( < 0, 1, 1 >, .2 * PI, 1.0 );
}
}
}
Объекты могут быть созданы в пределах 10-метрового расстояния от родительского объекта.


,Текстуры мультипликации.
Возможно создать текстуры, которые могут использоваться как структуры мультипликации.
Вот снимок автора рядом с пламенем, моделируемым, используя текстуры мультипликации:



default
{
state_entry()
{
llSetStatus(STATUS_PHANTOM,TRUE);
llSetTexture("lit_texture", ALL_SIDES);
llSetTextureAnim (ANIM_ON | LOOP, ALL_SIDES, 4, 4, 0, 0, 15.0);
}
}
Этот скрипт воздействует на сглаженный куб с измерениями приблизительно 8.0 8.0 на 0.0 метра.
Чтобы положить эту текстуру в объект, Вы должны сначала
положить в ваш инвентарь  и затем переместить в объект.
В течение загружающегося процесса Вы будете видеть, что файл структуры составлен из 16 немного различных изображений пламени,
вынутых в 4 4 сетками, как показано ниже:



Отметьте также, что вертикальные желтые линии будут иногда видеться рядом с пламенем.
Они - фактически очень узкие стороны куба, пылающего с изображением пламени.
(Возможно осторожная спецификация сторон объекта, которые используются в мультипликации могла предотвратить ошибку.)


Датчик, для определения центра вращения.
Более ранняя статья показала, как заставить объект вращаться вокруг неподвижного центра.
Эта программа вводит датчики и показы, чтобы идентифицировать местоположение скрипта так, чтобы объект мог вращаться вокруг его владельца.

Датчики позволяют объектам просмотреть их окружающую среду, чтобы установить присутствие других объектов или агентов поблизости.
Датчики используют
функции llSensor () или llSensorRepeat (), чтобы просмотреть отобранные части окружающей среды.
llSensor () делает единственный просмотр, в то время как llSensorRepeat () может быть настроен, чтобы просмотреть окружающую среду равномерно.
Отметьте, что объект может иметь только один активный датчик одновременно.
Когда датчик проводит просмотр, это вызывает случай "датчика", который может обработать результаты просмотра.
В пределах скрипта, чтобы обработать случай датчика, ряд функций обнаружения может использоваться, чтобы приобрести информацию об ощущаемых объектах.
Вот скрипт, который использует повторившийся просмотр датчика, чтобы идентифицировать местоположение его владельца,
и вращает его объект вокруг его владельца.
// Этот скрипт для движения его владельца по кругу.
vector startPos;
vector curPos;

vector offset; // offset from Agent
integer iteration;
float rotationRate; // degrees of rotation per iteration
float sensorInterval; // seconds between sensor scan.

default
{
state_entry()
{
llOwnerSay( "Hello, Avatar! Touch to start orbiting." );
llSetStatus( 1, FALSE ); // turn Physics off.
offset = < 2, 2, 1 >;
iteration = 0;
rotationRate = .5;
sensorInterval = .3;
}

touch_start(integer total_number)
{
startPos = llGetPos();
curPos = startPos;

llSleep( .1 );

key id = llGetOwner();
llSensorRepeat( "", id, AGENT, 96, PI, sensorInterval );
}

sensor(integer total_number)
{
iteration++;

if( iteration > 300 )
{
llResetScript();
}

if( llDetectedOwner( 0 ) == llGetOwner() )
{ // the detected Agent is my owner.
vector position = llDetectedPos(0); // find Owner position.

// calculate next object position relative both to the Owner's
// position and the current time interval counter. That is,
// use the iteration counter to define a rotation, multiply
// the rotation by the constant offset to get a rotated offset
// vector, and add that rotated offset to the current position
// to defne the new position.

float degreeRotation = llRound( rotationRate * iteration ) % 360;
rotation Rotation =
llEuler2Rot( < 0, 0, degreeRotation * DEG_TO_RAD > );
vector rotatedOffset = offset * Rotation;
position += rotatedOffset;

// change the location of the object and save the current (rotated)
// offset for use during the next iteration.
llSetPos( position );
offset = rotatedOffset;
}
}
}
Датчик скрипте может искать владельца в пределах 96 метров от объекта и в пределах радианов к любой стороне передового вектора объекта.





Форма входа
Календарь новостей
«  Май 2024  »
ПнВтСрЧтПтСбВс
  12345
6789101112
13141516171819
20212223242526
2728293031
Поиск
Ссылки
Статистика
Copyright MyCorp © 2024
Сделать бесплатный сайт с uCoz