Follower sind normalerweise in der Sim gerezzte Objekte, die mehr oder weniger zufällig Avataren in der Region nachlaufen.
Heute wurde in der
Scripts-Gruppe nach einem Follower gefragt, den man an den Avatar anhängen (attachen) kann.
Ich habe folgendes kurzes Skript geschrieben, es muss in das Rootprim eines Objekts aus zwei Prims - das erste Childprim stellt den "Follower" dar, und macht nichts weiter als ein Stück zurückzufallen wenn sich der Avatar bewegt, um so das Hinterherschweben zu simulieren.
Das Objekt muss am Attachmentpunkt "Center" angehängt werden, und soll keinen Offset haben (die relative Position/Rotation des gesamten Objekts als Attachment soll 0,0,0 [,0] sein).
Das Skript enthält auch den Code dafür, wie man die relative und die absolute Position von Childprims in Attachments berechnet bzw. umrechnet:
Zitat:
integer LINKNUMMER_CHILDPRIM = 2; //Linknummer des gesuchten Child-Prims
vector AVATAR_POSITION = llGetPos();
rotation AVATAR_ROTATION = llGetRot();
vector RELATIVE_CHILD_POSITION = llList2Vector(llGetLinkPrimitiveParams(LINKNUMMER_CHILDPRIM, [PRIM_POS_LOCAL]),0);
vector ABSOLUTE_CHILD_POSITION = AVATAR_POSITION + (RELATIVE_CHILD_POSITION * AVATAR_ROTATION);
vector RELATIVE_CHILD_POSITION_NEU = (ABSOLUTE_CHILD_POSITION - AVATAR_POSITION) / AVATAR_ROTATION;
Da die im Client angezeigte Rotation des Avatars nicht der entspricht, die auf dem SL-Server gespeichert ist, weicht die sichtbare Position der Childprims leider von der tatsächlichen ab.
Code:
//Object must be attached to center-attachment-point with zero vector/rotation offset.
integer iChildprim = 2; //linknumber of childprim
float fTimer = 0.618; //timer-interval
float fMinDistance = 0.2; //distance the avatar must walk/run.. before it is determined a position-change
vector vLastPos; //stores last known position of the avatar
vector vRelativeChildPos_BeforeAvatarmovement; //stores last known position of the childprim
float fFallBehind = 0.25; //percentage of 'fall behind' of the childprim, while the avatar is moving
integer iMOVING = FALSE;
default
{
state_entry()
{
//initial child pos
vLastPos = llGetPos(); //avatar position
llSetTimerEvent(fTimer);
}
on_rez(integer start_param)
{
llResetScript();
}
timer()
{
if (llGetAttached() == 0)
{ //not attached, return.
return;
}
vector vPos = llGetPos(); //avatar position
vector vChildPos = llList2Vector(llGetLinkPrimitiveParams(iChildprim, [PRIM_POS_LOCAL]),0); //childprim-position
vector vAbsoluteChildPos = vPos+(vChildPos*llGetRot()); //get absolute position of the childprim in the sim
vector vAbsolutePos = vAbsoluteChildPos + ((vAbsoluteChildPos-vPos)*fFallBehind); //apply offset
vector vRelativeChildPos = (vAbsolutePos-vPos)/llGetRot(); //get relative position of the childprim in the sim
float fDistance = llVecDist(vPos, vLastPos);
if (fDistance >= fMinDistance && !iMOVING)
{ //avatar moving (was not moving before)
iMOVING = TRUE;
llSetLinkPrimitiveParamsFast(iChildprim,[PRIM_POS_LOCAL,vRelativeChildPos]);
vRelativeChildPos_BeforeAvatarmovement = vChildPos; //preserve relative pos of childprim.
}
else
{
if (iMOVING)
{
if (fDistance < fMinDistance)
{ //avatar stopped moving
iMOVING = FALSE;
//reset pos
llSetLinkPrimitiveParamsFast(iChildprim,
[PRIM_POS_LOCAL,vRelativeChildPos_BeforeAvatarmovement]);
} //else still moving, keep current relative position
} //else avatar not moving and not stopping, do nothing.
}
vLastPos = vPos;
}
}
Bearbeitet vom Moderator Freitag, 19. September 2014 09:34:01(UTC)
| Grund: Nicht angegeben