-
표정 허드(Facial Expressions HUD) 만들기 - 세컨드라이&오픈심웹프로그래밍/LSL(세컨드라이프) 2015. 7. 30. 00:34반응형
사진촬영 할때 유용한 "표정 허드" 만드는 방법 입니다.
스크립트 소스는 "Dora Gustafson, Studio Dora 2012" 의 소스를 사용 하였습니다.
1. 바닥에 아무 프림 하나를 만든다.
2. 그 프림을 "Shift+드래그"로 복사해서 Y축(녹색) 방향으로 나란히 놓는다.
- HUD는 장착했을때 X축(빨강) 방향이 정면이 되므로
Y축/Z축 방향으로 정렬을 해주어야 합니다.3. 밝은표정 모음과 어두운 표정 모음 구분을 위해 각 프림의 텍스쳐 색상을 변경해 준다.
- 저는 파랑/빨강 으로 나누었습니다.4. 밝은표정(파랑)쪽 프림에 스크립트를 넣어 줍니다.
- "Edit"창의 [Content]탭을 누릅니다.- [New Script] 버튼을 누르면 "New Script"라는 파일이 생깁니다.
- "New Script"를 더블클릭 하여 스크립트 편집창을 엽니다.
- 안에있는 스크립트를 다 지우고 아래의 스크립트를 넣어주고 밑부분의 [Save]버튼을 눌러줍니다.
// Pose ball and facial expressions, script by Dora Gustafson, Studio Dora 2012
// build on Basic pose ball script. by Dora Gustafson, Studio Dora 2010
// v1.00 Has 10 facial expressions that can be chosen from a menu, chosen by random,
// ... looped, has menu reopen and saves camera position
// v1.01 wearable
string animation = "stand"; // name of built-in animation or animation in prim inventory
list FACIALS = [
"express_open_mouth",
"express_tongue_out",
"express_kiss",
"express_smile",
"express_toothsmile",
"express_laugh_emote",
"express_shrug_emote",
"express_surprise_emote",
"express_wink_emote"
];
list BUTTONS = [
"Open mouth",
"Tongue out",
"Kiss",
"Smile",
"Toothsmile",
"Laugh",
"Shrug",
"Surprise",
"Wink",
"Loop", "Random"];
key sitter;
integer dialogChanal=-532247676;
integer haandtag;
string menuHead;
integer act=0;
string Fanim;
default
{
state_entry()
{
llSitTarget( <0.0, 0.0, 1.0>, ZERO_ROTATION );
llSetSitText("Animate");
llSetClickAction(CLICK_ACTION_SIT);
}
attach(key id)
{
menuHead = llGetScriptName( )+"\nMemory in use: "+(string)llGetUsedMemory()+"\n\nChoose facial expression";
llSetClickAction(CLICK_ACTION_TOUCH);
llSetTimerEvent( 0.0 );
act = 0;
if (id)
{
sitter = id;
llRequestPermissions( sitter , PERMISSION_TRIGGER_ANIMATION);
}
else llListenRemove( haandtag);
}
changed(integer change)
{
menuHead = llGetScriptName( )+"\nMemory in use: "+(string)llGetUsedMemory()+"\n\n[Page Down] reopens this Dialog Menu\n\nChoose facial expression";
llSetTimerEvent( 0.0 );
act = 0;
if (change & CHANGED_LINK)
{
sitter = llAvatarOnSitTarget() ;
if(sitter != NULL_KEY) llRequestPermissions( sitter , PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS | PERMISSION_TRACK_CAMERA);
else
{
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) llStopAnimation(animation);
llSetAlpha(1.0, ALL_SIDES); // show prim
llListenRemove( haandtag);
}
}
}
run_time_permissions(integer perm)
{
if ( (perm & PERMISSION_TRIGGER_ANIMATION) && (llAvatarOnSitTarget() != NULL_KEY) )
{
llSetAlpha(0.0, ALL_SIDES); // hide prim
llStartAnimation(animation);
llStopAnimation("sit");
}
if ( perm & PERMISSION_TAKE_CONTROLS )
{
llTakeControls( CONTROL_DOWN , TRUE, TRUE);
llListenRemove( haandtag);
haandtag = llListen( dialogChanal, "", sitter, "");
llDialog( sitter, menuHead, BUTTONS, dialogChanal);
}
}
touch_end( integer num )
{
if ( llDetectedKey(0) == sitter )
{
llListenRemove( haandtag);
haandtag = llListen( dialogChanal, "", sitter, "");
llDialog( sitter, menuHead, BUTTONS, dialogChanal);
}
}
control(key id, integer down, integer new)
{
if ( down & new & CONTROL_DOWN ) llDialog( sitter, menuHead, BUTTONS, dialogChanal);
}
listen( integer channel, string name, key id, string message)
{
if ( "Loop" == message )
{
act = act ^ 1;
if ( act & 1 ) llSetTimerEvent( 1.0 );
else llSetTimerEvent( 0.0 );
}
else
{
if ( "Random" == message )
{
Fanim = llList2String( llListRandomize( FACIALS, 1), 0);
act = act ^ 2;
}
else
{
integer n = llListFindList( BUTTONS, [message]);
if ( n >= 0 ) Fanim = llList2String( FACIALS, n);
}
if ( llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) llStartAnimation( Fanim);
}
llDialog( sitter, menuHead, BUTTONS, dialogChanal);
if( llGetPermissions() & PERMISSION_TRACK_CAMERA)
{
rotation cam_rot=llGetCameraRot()/llGetRot(); // relative camera rotation
vector cam_pos=(llGetCameraPos()-llGetPos())/llGetRot(); // relative camera position
llSetLinkCamera( LINK_THIS, cam_pos, cam_pos + llRot2Fwd(cam_rot));
}
}
timer()
{
if ( act & 2 ) Fanim = llList2String( llListRandomize( FACIALS, 1), 0);
if ( llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) llStartAnimation( Fanim);
}
}
5. 어두운 표정(빨간)쪽에 같은방법으로 아래의 스크립트를 넣어 줍니다.
// Pose ball and facial expressions, script by Dora Gustafson, Studio Dora 2012
// build on Basic pose ball script. by Dora Gustafson, Studio Dora 2010
// v1.00 Has 10 facial expressions that can be chosen from a menu, chosen by random,
// ... looped, has menu reopen and saves camera position
// v1.01 wearable
string animation = "stand"; // name of built-in animation or animation in prim inventory
list FACIALS = [
"express_afraid_emote",
"express_worry_emote",
"express_sad_emote",
"express_disdain",
"express_frown",
"express_anger_emote",
"express_bored_emote",
"express_cry_emote",
"express_embarrased_emote",
"express_repulsed_emote"
];
list BUTTONS = [
"Afraid",
"Worry",
"Sad",
"Disdain",
"Frown",
"Angry",
"Bored",
"Cry",
"Embarrase",
"Repulsed",
"Loop", "Random"];
key sitter;
integer dialogChanal=-532247677;
integer haandtag;
string menuHead;
integer act=0;
string Fanim;
default
{
state_entry()
{
llSitTarget( <0.0, 0.0, 1.0>, ZERO_ROTATION );
llSetSitText("Animate");
llSetClickAction(CLICK_ACTION_SIT);
}
attach(key id)
{
menuHead = llGetScriptName( )+"\nMemory in use: "+(string)llGetUsedMemory()+"\n\nChoose facial expression";
llSetClickAction(CLICK_ACTION_TOUCH);
llSetTimerEvent( 0.0 );
act = 0;
if (id)
{
sitter = id;
llRequestPermissions( sitter , PERMISSION_TRIGGER_ANIMATION);
}
else llListenRemove( haandtag);
}
changed(integer change)
{
menuHead = llGetScriptName( )+"\nMemory in use: "+(string)llGetUsedMemory()+"\n\n[Page Down] reopens this Dialog Menu\n\nChoose facial expression";
llSetTimerEvent( 0.0 );
act = 0;
if (change & CHANGED_LINK)
{
sitter = llAvatarOnSitTarget() ;
if(sitter != NULL_KEY) llRequestPermissions( sitter , PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS | PERMISSION_TRACK_CAMERA);
else
{
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) llStopAnimation(animation);
llSetAlpha(1.0, ALL_SIDES); // show prim
llListenRemove( haandtag);
}
}
}
run_time_permissions(integer perm)
{
if ( (perm & PERMISSION_TRIGGER_ANIMATION) && (llAvatarOnSitTarget() != NULL_KEY) )
{
llSetAlpha(0.0, ALL_SIDES); // hide prim
llStartAnimation(animation);
llStopAnimation("sit");
}
if ( perm & PERMISSION_TAKE_CONTROLS )
{
llTakeControls( CONTROL_DOWN , TRUE, TRUE);
llListenRemove( haandtag);
haandtag = llListen( dialogChanal, "", sitter, "");
llDialog( sitter, menuHead, BUTTONS, dialogChanal);
}
}
touch_end( integer num )
{
if ( llDetectedKey(0) == sitter )
{
llListenRemove( haandtag);
haandtag = llListen( dialogChanal, "", sitter, "");
llDialog( sitter, menuHead, BUTTONS, dialogChanal);
}
}
control(key id, integer down, integer new)
{
if ( down & new & CONTROL_DOWN ) llDialog( sitter, menuHead, BUTTONS, dialogChanal);
}
listen( integer channel, string name, key id, string message)
{
if ( "Loop" == message )
{
act = act ^ 1;
if ( act & 1 ) llSetTimerEvent( 1.0 );
else llSetTimerEvent( 0.0 );
}
else
{
if ( "Random" == message )
{
Fanim = llList2String( llListRandomize( FACIALS, 1), 0);
act = act ^ 2;
}
else
{
integer n = llListFindList( BUTTONS, [message]);
if ( n >= 0 ) Fanim = llList2String( FACIALS, n);
}
if ( llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) llStartAnimation( Fanim);
}
llDialog( sitter, menuHead, BUTTONS, dialogChanal);
if( llGetPermissions() & PERMISSION_TRACK_CAMERA)
{
rotation cam_rot=llGetCameraRot()/llGetRot(); // relative camera rotation
vector cam_pos=(llGetCameraPos()-llGetPos())/llGetRot(); // relative camera position
llSetLinkCamera( LINK_THIS, cam_pos, cam_pos + llRot2Fwd(cam_rot));
}
}
timer()
{
if ( act & 2 ) Fanim = llList2String( llListRandomize( FACIALS, 1), 0);
if ( llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) llStartAnimation( Fanim);
}
}
6. 두개의 프림을 드래그 또는 "한프림 클릭+Shift+한프림 클릭" 으로 둘다 선택하고
Edit 창의 [link] 버튼을 눌러줍니다.
그리고 [General]탭으로 가서 Name 에 이름을 적어 줍니다.
저는 "face_Expression_hud"라고 적었습니다.7. Edit 창을 닫고 프림을 마우스 오른클릭 하고 "Take" 해 줍니다.
8. 허드장착
- 인벤토리(단축키 : Ctrl+I)를 열고 방금만든 "face_Expression_hud"를 찾아 마우스 오른클릭을 합니다.
- Attach to HUD > 적당한 위치 선택(저는 Top Right)를 선택 했습니다.9. 허드가 장착된 모습
- 허드가 장착된 상태에서 허드를 마우스 오른클릭 하여 크기조정/위치조정을 할수 있습니다.
10. 사용방법
- 각 버튼(밝은표정/어두운표정)을 누르면 해당하는 표정목록이 있는 대화창이 뜹니다.- "Toothsmile"을 눌러봤습니다.
- 몇초가 지나면 다시 무표정으로 돌아옵니다.
- [Loop]버튼으로 해당표정을 지속적으로 짓고 있도록 할수 있습니다.
[Loop]버튼을 다시한번 누르면 해제 됩니다.
- [Random] 버튼은 아무 표정이나 랜덤으로 한번 선택됩니다.10. 대화창 닫기
- 대화창 윗부분의 [x]를 누르거나 아래의 [Ignore]버튼을 누릅니다.
- 만약 [Block]버튼으로 창을 닫으면, 다음부턴 대화창이 열리지 않습니다.
이럴경우엔 허드를 벗었다가 다시 착용하면 됩니다.반응형'웹프로그래밍 > LSL(세컨드라이프)' 카테고리의 다른 글
텔레포터 스크립트 기본형 (0) 2015.08.01 아바타의 표정을 좀더 세밀하게 조정하기 - 세컨드라이프&오픈심 (0) 2015.07.31 내가만든 쉐입 내려받기/올리기 - 세컨드라이프 또는 오픈심 (0) 2015.07.29 세컨드라이프(또는 오픈심) 에서 오브젝트를 파일로 다운로드/업로드 하기 (0) 2015.07.28 딱 세컨드라이프를 즐길만큼만 익혀보는 블렌더 - 텍스쳐 입히기 (0) 2015.07.24