Jump to content

Would Appreciate Some Scripting Help; setPosition does not work after TranslateTo


ZeroCore

Recommended Posts

Hi.

 

In short, I'm trying to make an object move from one spot to another, then instantaneously return to its original position, and then do this again and again.

 

To be be more precise, I'm trying to do this to many objects in order to make it look like the player is standing inside a tunnel and is constantly moving even when standing still.

 

This is my script, which is attached to every segment of the tunnel (which are static objects) :

Scriptname ___ZugImUnterfuhrung extends ObjectReference

Event OnCellLoad()
      OnTranslationAlmostComplete() 
EndEvent 

Event OnUpdate() 
      OnTranslationAlmostComplete() 
EndEvent 

Event OnTranslationAlmostComplete() 
      int END = 1152 

      if Is3DLoaded() 
            TranslateTo(END, GetPositionY(), GetPositionZ(), GetAngleX(), GetAngleY(), GetAngleZ(), 100, 0.0) 
      endif 
EndEvent 

Event OnTranslationComplete() 
      int START = -8832 
      disable() 
      setPosition(START, 0, 0) 
      enable() 
      registerForSingleUpdate(0.1) 
EndEvent

What is supposed to go on is that each and every section of the tunnel is supposed to move from its original position backwards to a certain point at a constant speed, then teleport back to a starting position and repeating this over and over again.

 

 

The start and end positions are concealed behind two black planes (this is in a tunnel after all; it won't be easy for the player to see what's going on).

 

The issue is that all segments of the tunnel move backwards to the end position well enough, but every attempt that I've made to get them to move forward to the start position has failed, and I don't know why.

 

And I'm not familiar with using object states (and as per usual, Bethesda's tutorials on the subject are... lacking to say the least; I couldn't figure it out on my own just by reading the wiki, so just to let you know, if your solution to the problem is to use various states, I won't have any idea of what you're talking about).

 

I was thinking of possibly trying to use the moveTo function as a means of getting the things to move, and then placing an X marker at the start coordinates, but I don't know if this would work either, since setPosition didn't work after TranslateTo was called.

Link to comment
Share on other sites

Hmm there's a few things wrong with the code from what I can see, and while it's unlikely that all of them contribute to the problem they do make it a bit difficult to diagnose the problem.

 

First, I do not recommend calling an event as if it were a function. It shouldn't usually cause any problems, but it makes the code hard to follow and can lead to some mistakes if you aren't careful. I would put the OnTranslationAlmostComplete() code into a separate function and have the desired events call that function.

 

Second, I assume this is all the code which would mean nothing ever changes START and END. As such, they should be made constants, or at least initialized and declared outside of any functions. No need to have the game do the extra work of setting that variable every time it needs to do an operation with it.

 

Third, I don't know what you're using On3DLoaded() for, but putting a TranslateTo() inside an OnTranslateAlmostComplete() event would result in an infinite loop where the object is always translating. I don't think SetPosition() will work when the object is translating but even if it did, looping it this way is not ideal. You should probably put your TranslateTo() function in the same scope (event, function, etc.) as and right after the SetPosition() call.

 

Fourth, you have no catch to detect if the object fails to finish translating. This is especially important because when you send a request to translate an object while it's already translating, it never sends the OnTranslateComplete() event, but instead sends the OnTranslateFail() event. Thus, because you're creating a loop whereby each translation is being interrupted it never calls OnTranslateComplete(), which never activates with SetPosition(). Because of this, OnUpdate() is never called and the fact that TranslateTo() is self repeating makes OnUpdate() entirely superfluous.

 

You should get into the habit of learning to debug these kinds of errors. On a simple level, just putting Debug.Notification() several places in the code with simple messages would show a message in the top-left while playing and can tell you a lot about what events are activating and when. For instance, putting a debug message in the OnTranslationComplete() event and then playing the game so that it runs the script. If it showed the message then you know that the game is sending that event and that something in that event isn't working. If you don't see a message, then you know that the event is never being called. Debug messages like this are crucial when diagnosing your own code and for larger segments and more complicated systems are a necessity.

 

Modified Code:

Scriptname ___ZugImUnterfuhrung extends ObjectReference

Int END = 1152
Int START = -8832 

Event OnCellLoad()
      Move() 
EndEvent 

Event OnTranslationComplete() 
      Move()
EndEvent 

function Move()                     ;To be called on first load and on translation completion.
      disable() 
      setPosition(START, 0, 0) 
      enable()
      Utility.Wait(0.1)             ;replaces delay previously set when registering for a single update
      if Is3DLoaded() 
            TranslateTo(END, GetPositionY(), GetPositionZ(), GetAngleX(), GetAngleY(), GetAngleZ(), 100, 0.0) 
      endif
endFunction
Edited by dalsio
Link to comment
Share on other sites

  On 8/29/2016 at 4:01 AM, dalsio said:

 

Hmm there's a few things wrong with the code from what I can see, and while it's unlikely that all of them contribute to the problem they do make it a bit difficult to diagnose the problem.

 

First, I do not recommend calling an event as if it were a function. It shouldn't usually cause any problems, but it makes the code hard to follow and can lead to some mistakes if you aren't careful. I would put the OnTranslationAlmostComplete() code into a separate function and have the desired events call that function.

 

Second, I assume this is all the code which would mean nothing ever changes START and END. As such, they should be made constants, or at least initialized and declared outside of any functions. No need to have the game do the extra work of setting that variable every time it needs to do an operation with it.

 

Third, I don't know what you're using On3DLoaded() for, but putting a TranslateTo() inside an OnTranslateAlmostComplete() event would result in an infinite loop where the object is always translating. I don't think SetPosition() will work when the object is translating but even if it did, looping it this way is not ideal. You should probably put your TranslateTo() function in the same scope (event, function, etc.) as and right after the SetPosition() call.

 

Fourth, you have no catch to detect if the object fails to finish translating. This is especially important because when you send a request to translate an object while it's already translating, it never sends the OnTranslateComplete() event, but instead sends the OnTranslateFail() event. Thus, because you're creating a loop whereby each translation is being interrupted it never calls OnTranslateComplete(), which never activates with SetPosition(). Because of this, OnUpdate() is never called and the fact that TranslateTo() is self repeating makes OnUpdate() entirely superfluous.

 

You should get into the habit of learning to debug these kinds of errors. On a simple level, just putting Debug.Notification() several places in the code with simple messages would show a message in the top-left while playing and can tell you a lot about what events are activating and when. For instance, putting a debug message in the OnTranslationComplete() event and then playing the game so that it runs the script. If it showed the message then you know that the game is sending that event and that something in that event isn't working. If you don't see a message, then you know that the event is never being called. Debug messages like this are crucial when diagnosing your own code and for larger segments and more complicated systems are a necessity.

 

Modified Code:

Scriptname ___ZugImUnterfuhrung extends ObjectReference

Int END = 1152
Int START = -8832 

Event OnCellLoad()
      Move() 
EndEvent 

Event OnTranslationComplete() 
      Move()
EndEvent 

function Move()                     ;To be called on first load and on translation completion.
      disable() 
      setPosition(START, 0, 0) 
      enable()
      Utility.Wait(0.1)             ;replaces delay previously set when registering for a single update
      if Is3DLoaded() 
            TranslateTo(END, GetPositionY(), GetPositionZ(), GetAngleX(), GetAngleY(), GetAngleZ(), 100, 0.0) 
      endif
endFunction

 

This did not work.

 

SetPosition still failed to trigger and the object merely stopped at its end point and did not return to its start position.

Link to comment
Share on other sites

Here something for you to Study

I Guarantee it works, if you know how to use it.

 

 

Function MoveMe(ObjectReference akObjectREFa, ObjectReference akObjectREFb)

Float X = akObjectREFb.GetPositionX()
Float Y = akObjectREFb.GetPositionY()
akObjectREFa.MoveTo(akObjectREFb, X, Y)
EndFunction

Link to comment
Share on other sites

Is there any reason you are disabling the object before setting it's position? That might be causing your problems. Replacing that with Peter's suggestion might work but if it doesn't you can always use TranslateTo() with a ridiculously high speed.

Edited by dalsio
Link to comment
Share on other sites

Why are you disabling then calling setposition.

 

This is a small clip out of one of my codes ...

I use XMarkers set where I need them to be then translate to them

 

MarkerREF.SetPosition(2560.0000,2560.0000,-1024.0000)

WaterREF.TranslateToRef(MarkerREF, 10.0)
While(WaterREF.GetPositionZ()!=(-1024.0000))
Utility.Wait(2.0)
EndWhile
WaterREF.SetPosition(2560.0000,2560.0000,-1024.0000)

 

You can also use translate to pop them back in place very fast after the move.

Link to comment
Share on other sites

  On 8/29/2016 at 8:21 AM, PeterMartyr said:

Here something for you to Study

I Guarantee it works, if you know how to use it.

 

 

Function MoveMe(ObjectReference akObjectREFa, ObjectReference akObjectREFb)

 

Float X = akObjectREFb.GetPositionX()

Float Y = akObjectREFb.GetPositionY()

akObjectREFa.MoveTo(akObjectREFb, X, Y)

EndFunction

 

 

I'm going to have to have object references in here, and something else to hold the script rather than having the script attached to the object, but essentially what you're doing is a function that causes the first reference to be moved to the second one using MoveTo, and then since X and Y are set to the second reference's X and Y coordinates, it should center the first ref on the position of the second.

 

I'm not sure how this will work after TranslateTo has been called though, which is to say, I don't know if this function will, well, function after TranslateTo has been used.

 

 

  On 8/29/2016 at 8:41 AM, dalsio said:

Is there any reason you are disabling the object before setting it's position? That might be causing your problems. Replacing that with Peter's suggestion might work but if it doesn't you can always use TranslateTo() with a ridiculously high speed.

 

Because I thought that it would work similarly to how you can't delete something without disabling it. Even if I remove the .disable() and .enable(), it still won't return to its original position as SetPosition won't work after TranslateTo has been called.

 

  On 8/29/2016 at 4:26 PM, NexusComa said:

Why are you disabling then calling setposition.

 

This is a small clip out of one of my codes ...

I use XMarkers set where I need them to be then translate to them

 

MarkerREF.SetPosition(2560.0000,2560.0000,-1024.0000)

WaterREF.TranslateToRef(MarkerREF, 10.0)
While(WaterREF.GetPositionZ()!=(-1024.0000))
Utility.Wait(2.0)
EndWhile
WaterREF.SetPosition(2560.0000,2560.0000,-1024.0000)

 

You can also use translate to pop them back in place very fast after the move.

 

I disabled them because I thought it would be similar to how you can't delete something when its enabled. With or without disabling though, they just won't move after TranslateTo has been called; SetPosition will not work for me after TranslateTo is used.

 

I'll try to rewrite the code be similar to yours, but I don't know how it'll work.

Link to comment
Share on other sites

in this script

 

MarkerREF.SetPosition(2560.0000,2560.0000,-1024.0000)

WaterREF.TranslateToRef(MarkerREF, 10.0)
While(WaterREF.GetPositionZ()!=(-1024.0000))
Utility.Wait(2.0)
EndWhile
WaterREF.SetPosition(2560.0000,2560.0000,-1024.0000)

 

SetPosition is not what moves the water but it is needed to update where the water is after TranslateToRef to the "world space" ...

 

For what you're doing set a Xmarker down at the start point and one down at the end point. Then TranslateToRef like the script.

Then TranslateToRef back to the 1st XMarker. I know TranslateToRef is the fastest type of movement and I think that is what you're

looking for, for the pop back to XMarker #1 ...

 

.TranslateToRef(MarkerRef, 0.1) is very very fast. Faster then a blink of an eye. May even need to use 0.3 ...

Edited by NexusComa
Link to comment
Share on other sites

Aha, I think I know why my code failed for you. It seems that I didn't take my own advice in accounting for if the translation failed, because from what I can tell your translations are in fact failing. Is there something in the objects way that is stopping them, or are there any other bits of code that's interacting with the objects? If they in any way stop the translation it will result in a failed translation and thus TranslateComplete() doesn't activate.

 

Regardless, this bit of code should cause the object to return to it's start position and translate regardless of whether it successfully translates or not. StopTranslation() is used here to make doubly sure the object isn't translating when setposition() is called, though that shouldn't happen.

 

Try this:

Scriptname ___ZugImUnterfuhrung extends ObjectReference

Int END = 1152
Int START = -8832 

Event OnCellLoad()
      Move() 
EndEvent 

Event OnTranslationComplete() 
      Move()
EndEvent

Event OnTranslationFailed()
      Move()
EndEvent

function Move()                     ;To be called on first load and on translation completion. 
      StopTranslation()
      setPosition(START, 0, 0) 
      Utility.Wait(0.1)             ;replaces delay previously set when registering for a single update
      if Is3DLoaded() 
            TranslateTo(END, GetPositionY(), GetPositionZ(), GetAngleX(), GetAngleY(), GetAngleZ(), 100, 0.0) 
      endif
endFunction
Edited by dalsio
Link to comment
Share on other sites

  On 8/30/2016 at 5:12 PM, dalsio said:

 

Aha, I think I know why my code failed for you. It seems that I didn't take my own advice in accounting for if the translation failed, because from what I can tell your translations are in fact failing. Is there something in the objects way that is stopping them, or are there any other bits of code that's interacting with the objects? If they in any way stop the translation it will result in a failed translation and thus TranslateComplete() doesn't activate.

 

Regardless, this bit of code should cause the object to return to it's start position and translate regardless of whether it successfully translates or not. StopTranslation() is used here to make doubly sure the object isn't translating when setposition() is called, though that shouldn't happen.

 

Try this:

Scriptname ___ZugImUnterfuhrung extends ObjectReference

Int END = 1152
Int START = -8832 

Event OnCellLoad()
      Move() 
EndEvent 

Event OnTranslationComplete() 
      Move()
EndEvent

Event OnTranslationFailed()
      Move()
EndEvent

function Move()                     ;To be called on first load and on translation completion. 
      StopTranslation()
      setPosition(START, 0, 0) 
      Utility.Wait(0.1)             ;replaces delay previously set when registering for a single update
      if Is3DLoaded() 
            TranslateTo(END, GetPositionY(), GetPositionZ(), GetAngleX(), GetAngleY(), GetAngleZ(), 100, 0.0) 
      endif
endFunction

 

  On 8/30/2016 at 9:45 AM, NexusComa said:

in this script

 

MarkerREF.SetPosition(2560.0000,2560.0000,-1024.0000)

WaterREF.TranslateToRef(MarkerREF, 10.0)
While(WaterREF.GetPositionZ()!=(-1024.0000))
Utility.Wait(2.0)
EndWhile
WaterREF.SetPosition(2560.0000,2560.0000,-1024.0000)

 

SetPosition is not what moves the water but it is needed to update where the water is after TranslateToRef to the "world space" ...

 

For what you're doing set a Xmarker down at the start point and one down at the end point. Then TranslateToRef like the script.

Then TranslateToRef back to the 1st XMarker. I know TranslateToRef is the fastest type of movement and I think that is what you're

looking for, for the pop back to XMarker #1 ...

 

.TranslateToRef(MarkerRef, 0.1) is very very fast. Faster then a blink of an eye. May even need to use 0.3 ...

 

 

I've tried to do both of these things.

 

Here's the problem I'm having now: the objects will translate, but they won't cycle properly since the function that I have to move them is also a translation function, and thus upon its completion triggers the "onTranslationComplete" event.

Scriptname ____________ZIU3 extends ObjectReference  


ObjectReference Property XSTART  Auto  ;This is an X marker that marks where the object is supposed to start
ObjectReference Property XEND  Auto  ;Another X marker where it winds up

function Move() ;moves the tunnel bits backwards behind the train
    StopTranslation()
    if Is3DLoaded()
        TranslateToRef(XEND, 1000.0)
    endif
EndFunction

function MoveToStart() ;moves the tunnel bits back to the starting position ahead of the train
    StopTranslation()
     if Is3DLoaded()
        TranslateToRef(XSTART, 1000000.0)
    endif
    registerForSingleUpdate(0.1)
EndFunction

Event OnCellLoad()
      MoveToMyEditorLocation() ;This is just a reset to keep tunnel pieces from going nuts and gaps from forming in the tunnel wall
    Move()
EndEvent

Event OnUpdate()
      Move()
EndEvent

Event OnTranslationComplete()
    MoveToStart()
EndEvent

Event OnTranslationFailed()
    MoveToStart()
EndEvent

The function "Move" is what makes the pieces of the tunnel move backward, behind the train.

 

The function "MoveToStart" is another translation function that moves them back to their original position at high speed, faster than the player can notice.

 

The issue though is that I can't use "OnTranslationComplete" to trigger "MoveToStart" since "MoveToStart" is also a translation function. This loop works once, after which the bits of the tunnel just jitter around in place, since "Move" and "MoveToStart" are triggering at the same time, and I don't know how to make one function work without triggering the other, unless there's a function that can make the script wait until the previous function is complete.

 

Then, if there is a function that can make the script wait until one function is complete, then I could have "Move" trigger, then use that function which halts the script until "Move" is done, which then, if all works correctly, make the script wait until "Move" is done, and then trigger "MoveToStart", and then use a "registerForSingleUpdate(0.1)" to use an "Event OnUpdate" loop to keep things going.

 

At present though, I don't know how to make this work, and all else has failed.

 

SetPosition and MoveTo don't work when "TranslateTo" or "TranslateToRef" is called; those two functions just stop working when translation functions are in use. I've tried just using "SetPostion" to move something to something else, and I've tried using "MoveTo" to get the individual pieces of the tunnel to move to an X Marker that I have at their respective start positions. NEITHER ONE WORKS after a translation.

Edited by ZeroCore
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...