Jump to content

How to rotate parts in editor BEFORE they're placed?


Recommended Posts

I'd like to write some plugin code that tweaks the orientation of parts as they're picked from the parts panel, and I'm having a dickens of a time getting it to work.

The way I'm trying to rotate parts is by calling part.transform.Rotate(...).  That method works just fine-- but as far as I can tell, only for parts that have actually been placed on the ship in the editor.  Calling it on a part that hasn't been placed yet appears to do nothing, as far as I can tell.

Here are some things I've tried, and what I've observed:

  • Calling part.transform.Rotate() works just fine if I do it in onEditorPodPicked, which gets called when the first root part is placed for a new vessel.  So I've got that case covered.
  • Parts that are instantiated from the parts panel get an onEditorPartEvent of type ConstructionEvenType.PartCreated.  This would be the ideal place for me to do the rotation... except calling part.transform.Rotate() here appears to do absolutely nothing, as far as I can tell.  The rotation of the part isn't affected, either when being dragged around or when placed on the ship.
  • The next editor part event that happens after PartCreated is PartDragging.  I've tried calling part.transform.Rotate() there, too... also no dice, I can't seem to affect the rotation at all.

Basically, what I'm looking for is the ability to do, programmatically, the same thing that happens when I hit one of QWEASD while dragging a part.

Does anyone have any suggestions for how I can make this happen?  What am I missing, here?

Link to comment
Share on other sites

6 hours ago, Snark said:

The way I'm trying to rotate parts is by calling part.transform.Rotate(...).  That method works just fine-- but as far as I can tell, only for parts that have actually been placed on the ship in the editor.  Calling it on a part that hasn't been placed yet appears to do nothing, as far as I can tell.

Play with part.attRotation and/or part.attRotation0 (forgot which one does what, try to print them while you rotate a part with the kb and gizmo)

Link to comment
Share on other sites

5 hours ago, sarbian said:

Play with part.attRotation and/or part.attRotation0 (forgot which one does what, try to print them while you rotate a part with the kb and gizmo)

Thank you!

Unfortunately... although it seems to "work", it has odd side effects that make it unusable (at least in the experimentation I've done thus far.)  Details below, but the executive summary is that as far as I can tell, attRotation0 does nothing and attRotation does too much.

 

Let's say I want to rotate the object 90 degrees around the Y axis, so that it's spawned "facing" east instead of north.  So I set up a rotation like this:

Quaternion ROTATION = Quaternion.Euler(0, 90, 0);

Then I register for GameEvents.onEditorPartEvent, and handle it thus:

private void OnEditorPartEvent(ConstructionEventType eventType, Part part)
{
    if (eventType == ConstructionEventType.PartCreated)
    {
        part.attRotation = ROTATION;
    }
}

Result:  It appears to do what I want (the part shows up facing the right way, and if I attach it via a stack node above or below another part, it keeps that orientation).

However... the part's been subtly borked.  It now attaches wrong via surface attachment.

vnyTUwq.png

Looks like it's rotated the part model inside its own space relative to its surface attachment node, rather than rotating the transform of the part.  In other words, it's acting like it's rotating the model but nothing else.  For example, in the above image, that radially attached fuel tank should be touching (not clipping) the center tank, extending off to the left.  Instead, it's been rotated 90 degrees around the attachment point, instead of just behaving as if I had hit the Q key while dragging it.

I note that aside from part.attRotation, there's also part.attRotation0 and part.initRotation.  I've tried playing around with all three of these, to no avail:

  • part.initRotation affects the visible display of the part when it's initially created and is transparent and being dragged around by the mouse.  But it appears to have absolutely zero effect on the part once attached; the part immediately snaps to whatever orientation it would have had if initRotation had not been set.
  • part.attRotation looks right for when the part's created and being dragged, and is fine for stack attachments... but surface attachment becomes borked, as shown above.
  • part.attRotation0 does absolutely nothing at all under any circumstances, as far as I can tell.  (Of course it must do something or they wouldn't have added it.  It's just that I have yet to discover any visible difference that it makes to anything.)

I've tried multiple combinations of the above (e.g. "what if I set initRotation and attRotation", etc.); but as far as I can tell, they don't seem to affect each other at all.  initRotation appears to affect only rotation-while-dragging; attRotation affects both dragging and attachment, but borks the surface attachment; attRotation0 does nothing to either, as far as I can tell.

(There's also part.orgRot, another Quaternion, which also does nothing as far as I can tell.)

Hitting the Q key or similar orientation keys while dragging the part does indeed modify part.attRotation.  It does not affect part.attRotation0.  Since weird borkage happens when I try to modify part.attRotation, clearly the editor is modifying something else besides just part.attRotation.

I note that there's also a part.attPos.  I tried setting "part.attPos = ROTATION * part.attPos" in concert with setting attRotation, but that appears to do nothing as far as I can tell-- I still get the odd behavior shown in the picture above.  If I leave part.attPos alone and just monitor it passively, it appears to be always (0,0,0) and is not affected when I rotate the part via Q, so it's irrelevant to the current problem as far as I can tell.

TL;DR:  I have thus far not been able to find out how to programmatically do to a part what QWEASD keys do.  They affect part.attRotation cleanly, without borking the part.  When I touch that, it borks the part, which means there must be something else that I also need to update, but I've tried everything I can think of, to no avail.

Any suggestions as to what else I might try?

Link to comment
Share on other sites

Okay, finally managed to figure out how to do what I wanted, and I was looking in entirely the wrong place.  :)

Essentially what I've been trying to do is figure out how to make the default orientation of a vessel in the VAB face east instead of north.  I was trying to do that by reorienting the parts.  Upon further reflection now, I see that the above supposedly "borked" behavior isn't actually borked at all-- it's exactly what you'd see when attaching a radial part if you'd hit the Q key anyway.

The fundamental problem that I was bumping up against is that the VAB has an environment that assumes a particular orientation, and everything is geared towards that, and you can't simulate a change of environment direction just by rotating parts.  You have to rotate the environment itself.

And it turns out that EditorLogic has exactly such a field on it.  It's called "vesselRotation".  So all I have to do is trap GameEvents.onEditorStarted in the VAB, and set EditorLogic.fetch.vesselRotation to point in the direction I want, and presto, everything behaves exactly the way I want it to.  It's like two lines of code.

Anyway, got it sorted out, many thanks to @sarbian for giving a completely correct (as usual) answer to my entirely wrong question.  :)

Link to comment
Share on other sites

...aaand now I discover that my mod has borked the SPH because it turns out that the following supposedly separate and distinct enum values,

  • KSPAddon.Startup.EditorAny
  • KSPAddon.Startup.EditorVAB
  • KSPAddon.Startup.EditorSPH

...are all the same damn value, meaning that my script that's clearly marked "EditorVAB" is also running in the SPH even though I don't want it to.  :mad:

Anyway, gonna get that sorted out next.  I see that there exists an "EditorFacility" enum, but need to figure out how to get one so I know what facility I'm in.

[EDIT] Okay, found it... though it seems a bit byzantine.  EditorLogic.fetch.ship.shipFacility.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...