Jump to content

[SOLVED]Apply force in a floatcurve for orion engine module


Recommended Posts

Hey. Im in the process of making my moduleorionengine class. (Basically bombs explodes behind the engine providing force in pulses, the force gets dampened by a pusher plate. My approach is quite different than the previous orion plugin so there is unfortunantly not much i can take from it) What has got me steiffeled is how to apply force over time. Like in a floatcurve. Im wondering if this is possible to do contained inside a partmodule(without a monobehaviour class)

The idea is that as the second part of the animation cycle plays(pistons compress) force gets applied progressively so you dont get such a big spike in gees.

Thanks in advance. Any input will help. I do realize doing an engine module as a first ksp plugin project is a bit ambitious:P

Novice plugin coder

Update:

Using the method discribed by sarbian, nathankell and honeyfox i have solved how to do it. Marked the thread as solved. Will be putting up a vid in my wip thread of the plugin in action in the unity editor

Edited by landeTLS
Link to comment
Share on other sites

You just have to change the force you apply yourself each frame. I don't really see what the problem is, unless you want to use the stock engine module too?

You could try to apply the force with ForceMode.Impulse too

Link to comment
Share on other sites

Then apply a bit each FixedUpdate?

I guess you should create a floatcurve that relates time-since-explosion to force-multiplier; then track the time since the last explosion, and AddForce(force * curve.Evaluate(timeSinceExplosion)) in each FixedUpdate.

Link to comment
Share on other sites

Heheh. I should have been more clear. The problem doesnt lie in the code, its more the coder:P. Thanks nathankell, that makes perfect sence. Im still learning how to make partmodules in ksp do stuff so its all new to me. Sarbian: whats the difference between forcemode.impulse and forcemode.force? Im not extending moduleengine.

Edited by landeTLS
Link to comment
Share on other sites

Heheh. I should have been more clear. The problem doesnt lie in the code, its more the coder:P. Thanks nathankell, that makes perfect sence. Im still learning how to make partmodules in ksp do stuff so its all new to me. Sarbian: whats the difference between forcemode.impulse and forcemode.force? Im not extending moduleengine.

Have to say that PartModule is actually inherited from MonoBehaviour and so it can have void FixedUpdate() function to be called each physics frame.

You can load/create a float curve and record the UT of the moment when the nuclear charge explodes, then get the time by subtracting the current UT with the recorded one, use float curve's Evaluate() function to get the thrust value and finally use rigidbody.AddForceAtPosition() to add force in each physics frame.

Link to comment
Share on other sites

Heheh. I should have been more clear. The problem doesnt lie in the code, its more the coder:P. Thanks nathankell, that makes perfect sence. Im still learning how to make partmodules in ksp do stuff so its all new to me. Sarbian: whats the difference between forcemode.impulse and forcemode.force? Im not extending moduleengine.

For continuous force applying, use ForceMode.Force. ForceMode.Impulse mode will consider your force parameter as the impulse given in one time step.

If you want to use ForceMode.Impulse and still want to get similar effect as ForceMode.Force does, you need your force parameter multiplied by fixedDeltaTime (which might vary but should be close to 0.03sec).

Link to comment
Share on other sites

Have to say that PartModule is actually inherited from MonoBehaviour and so it can have void FixedUpdate() function to be called each physics frame.

You can load/create a float curve and record the UT of the moment when the nuclear charge explodes, then get the time by subtracting the current UT with the recorded one, use float curve's Evaluate() function to get the thrust value and finally use rigidbody.AddForceAtPosition() to add force in each physics frame.

Thanks man. That info is so gold to me!

I spent some time today setting up unity and adding keyinputs so i can experiment without loading ksp for each test. Made some progress but i can feel its been a while since i did any programming. Trying out some different force modes and it seems that impulse is indeed the way to go. I also found this method =

AddExplosionForce(explosionForce: float, explosionPosition: Vector3, explosionRadius: float, upwardsModifier: float = 0.0F, mode: ForceMode = ForceMode.Force): void;]
it makes it so easy to apply force to objects in a sphere around the rigidbody. Ill probably be using it in addition to some random destruction of parts in the sphere. (Blastzone) havent tried it out inside ksp yet tho. But in unity it works spledidly Edited by landeTLS
Link to comment
Share on other sites

hey guys. back again, this time with a basic adhoc unity class for the first smooth force application.

a quite sleepy so i am probably missing some very basic math.

how do i configure the thrust delivered properly along the floatcurve?

also i didnt add a bool etc yet to check if the curve has reached the end so it just continues applying force.

im using animationcurve instead of floatcurve since im testing in unityeditor. but floatcurve is an extension of it so it works the same way i presume.

special thanks to both nathankell and honeyfox, without you guys i would be much much less further along. thanks in advance.


using System;
using UnityEngine;
using System.Collections;


namespace Assets
{
class orion : MonoBehaviour
{
public GameObject Payload_Obj;
public string payloadTransform = "payload_Obj";

public float ThrustPerPulse = 100f;
public GameObject adhoc_obj;

[SerializeField]
AnimationCurve ThrustCurve;
private float timeAtLastBlast = -0f;
private float timeSinceLastBlast = -0f;
private float thrustToApply = -0f;
private float forceDirection = 0f;

//stage 1
// record time of last blast as it happens with: timeAtLastBlast = Time.fixedTime;
private void OnTriggerEnter(Collider other)
{
if (other.name == payloadTransform)
{
print("the payload object has entered trigger zone");
timeAtLastBlast = Time.fixedTime;
Destroy(Payload_Obj);
}
else
{ print("a different object has entered trigger zone"); }
}

void FixedUpdate()//per physx frame (onFixedUpdate for ksp)
{
if (timeAtLastBlast > 0)
{
//checking time passed
timeSinceLastBlast = Time.fixedTime - timeAtLastBlast;
print("time since last blast: " + timeSinceLastBlast);
thrustToApply = ThrustPerPulse / ThrustCurve.Evaluate(timeSinceLastBlast); //(?)

print("thrust to apply is: " + thrustToApply);
adhoc_obj = GameObject.Find("OrionPlaceholder");
adhoc_obj.rigidbody.AddForceAtPosition(adhoc_obj.transform.up * thrustToApply * Time.fixedDeltaTime, adhoc_obj.transform.position, ForceMode.Impulse);

}
}
}
}

edit: i feel embarrased now, i just checked the code.

thrustToApply = ThrustPerPulse / ThrustCurve.Evaluate(timeSinceLastBlast); //(?) should be:

thrustToApply = ThrustPerPulse * ThrustCurve.Evaluate(timeSinceLastBlast);

appears to work as expected now, now i just wonder how the best way would be to stop applying force when the floatfurve reaches clamp?

Edit2: i got to do a lot of work on the plugin class this evening.finally Finished the whole force loop. Still need to move the functions to fixedupdate. Most of the time i spent experimenting with different physics scripts and dynamic creation of gameobjects from prefabs. Im thinking now that this is the best way to make the bomb translate out of the barrel transform and raycast++ to check when it reaches a transform or box called obj_trigger. I was toying first with using rigidbody for thid but unity physics doesnt seem to like fast moving objects too well. This way i can have the pusher plate animation slow or speed up depending on the force curve and not need it to move at a constant speed because the bomb transform is moved by it. Looking forward to trying out the particle system to create some (hopefully) nice explosion effects. Am i right that i need to stick to the kspparticleemitter stuff or can i make some of the unity built in stuff work somehow? also am i overcomplicating things with raycasting the bomb transform etc. Is there an easier and effective way to do it?

Edited by landeTLS
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...