Jump to content

Setting direction of deployed parachute?


Recommended Posts

I'm working on a wind/weather mod and I've got wind working pretty well, except that the parachute model doesn't seem to respond correctly. Taking the drag vector pointing directly up, the wind effect vector perpendicular to the drag vector, the parachute seems to deploy in the direction that's opposite of the resultant velocity vector, not the direction of the net force vector.

So I understand that this is probably because it's easier to model that way, but is there a way for me to rotate the direction of the parachute model? A simple rotation of 180° around the vertical axis (with respect to the vessel) would fix my problem, but I can't seem to find the API function to do that.

Link to comment
Share on other sites

Which vector? The impulse vector I'm applying needs to be in the direction it's currently pointing, otherwise it wouldn't be an accurate model of wind, it's that I can't get the parachute to respond properly to that impulse (or rather, it responds properly, just not in the way I want as wind usually causes the parachute to act opposite the direction a normal impulse would). I've tried things like using small position changes instead of an impulse, but that causes the craft to be unstable even though it solves the orientation issue. I've thought of forging the velocity vector, but I can't figure out how to change the velocity vector without changing the direction the craft is going (yes, I know this sounds silly).

Link to comment
Share on other sites

So you basically want to move the chute into the direction of the wind? So you need to find the correct transform and rotate it. Try sth like this:


var part = ...;
var moduleParachute = part.GetComponent<ModuleParachute>();
var transform = part.FindModelTransform(moduleParachute.canopyName);
// use transform... might rotate it?

Link to comment
Share on other sites

Thanks for the suggestion, but it didn't seem to work. I tried:

            ModuleParachute moduleParachute = part.GetComponent<ModuleParachute>();
Transform transform = part.FindModelTransform(moduleParachute.canopyName);
transform.RotateAround(Vector3.up, 180);

but it didn't seem to have any effect. Just to confirm, I also tried with

transform.RotateAround(Vector3.right, 20);

to see if it rotated the model, but there was no effect. Is there anything I need to do to apply the transformation? According to the Unity docs, I shouldn't need to, but maybe KSP is doing something special here?

Also, just out of curiosity, what's the difference between transform found this way and the transform located in the scope of PartModule?

Edited by kevmo314
Link to comment
Share on other sites

Thanks for the suggestion, but it didn't seem to work. I tried:

            ModuleParachute moduleParachute = part.GetComponent<ModuleParachute>();
Transform transform = part.FindModelTransform(moduleParachute.canopyName);
transform.RotateAround(Vector3.up, 180);

but it didn't seem to have any effect. Just to confirm, I also tried with

transform.RotateAround(Vector3.right, 20);

to see if it rotated the model, but there was no effect. Is there anything I need to do to apply the transformation? According to the Unity docs, I shouldn't need to, but maybe KSP is doing something special here?

Also, just out of curiosity, what's the difference between transform found this way and the transform located in the scope of PartModule?

since ModuleParachute has a name variable for the canopy transform (canopyName) it's safe to assume that ModuleParachute sets the rotation of that transform based on frame velocity. Which in fact it does seem to do every fixed update.

Sadly I can't see any way around this, safe for overriding ModuleParachute entirely, which of course is a possible solution. Probably in conjunction with ModuleManager.

Link to comment
Share on other sites

Well, the approach i mentioned should work. Here is a little proof of concept:

    class DoRot : MonoBehaviour
{
public Transform t;
public void LateUpdate()
{
t.Rotate(Vector3.left);
}
}

// Code to add the module
if (GUILayout.Button("Add chute rot"))
{
foreach (var p in FlightGlobals.ActiveVessel.Parts)
{
var modPara = p.GetComponent<ModuleParachute>();
if (modPara != null)
{
var newBehavior = p.gameObject.AddComponent<DoRot>();
newBehavior.t = p.FindModelTransform(modPara.canopyName);
}
}
}

Screen after adding a bunch of those modules: http://db.tt/5twvUBEq

JDP is correct, the game re-sets it on every fixedUpdate. But using a later update should work just fine, as long as you only want it as an visual effect and the physical wind was already applied anyway. You also have to make sure you do only a single rotation after each reset of the game, since there sadly is no lateFixedUdpate ... the code above does not, thats why you sometimes notice some flickering.

Link to comment
Share on other sites

<snip>

[T]here sadly is no lateFixedUdpate ... the code above does not, thats why you sometimes notice some flickering.

the solution to flickering could be simply replacing each instance of ModuleParachute with a custom module that derives from ModuleParachute, with the only addition of modifying the canopy rotation. Replacing this module could be done via ModuleManager or you could do it programatically yourself.


public class ModuleParachute2 : ModuleParachute {
private Transform CanopyToRotate;

public override void OnStart(PartModule.StartState state) {
base.OnStart(state);
CanopyToRotate = part.FindModelTransform(canopyName);
}

public override void OnFixedUpdate() {
base.OnFixedUpdate();
CanopyToRotate.Rotate(Vector3.left);
}
}

Link to comment
Share on other sites

I tried the LateUpdate() method and the flickering is quite extreme for me. It might be just my computer, but it's incredibly noticeable, so I guess I'll try the module replacement method. When I did it with ModuleManager, it seemed to break any current auto-saved ships saying ModuleParachute wasn't found (because I replaced it with something else). Is this supposed to happen? I can just do it programmatically, but I was just curious as ModuleManager does seem like a cleaner solution overall.

Link to comment
Share on other sites

I tried the LateUpdate() method and the flickering is quite extreme for me.

Guess that means you have a much better PC than mine^^

As mentioned, a simple check should fix that:


class DoRot : MonoBehaviour
{
Boolean needsRot = true;
public Transform t;
void LateUpdate()
{
if (needsRot)
{
t.Rotate(Vector3.left);
needsRot = false;
}
}
void FixedUpdate()
{
needsRot = true;
}
}

You could try to work around those compatibility issues. An approach might be be to use the same class name as the original one. But therefor you likely have to dump modulemanager and have to replace the module yourself. It would be a much "cleaner" solution (until sth else wants to manipulate ModuleParachut, ofc^^)

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...