Jump to content

Applying gravity to a spawned object


Recommended Posts

Hello again :)

I've been messing about with something for one of my project, and thanks to stupid_chris pointing me in the right direction, I can now spawn objects into game in flight. Great, I thought, I'll just apply rigidybody to it, set to use gravity and bingo! How very naive of me :D

I gather from this post that gravity is handled by FlightIntegrator and applied to vessels. Sooooo, if I want to spawn an object and have KSP apply gravity to it, do I have to make it a vessel, and if so, how do I do that? Or am I missing something entirely?

This works insofar-as the object appears, but then it's still on rails because rock.GoOffRails(); give a null-ref.:


Vessel rock = FlightIntegrator.Instantiate(rockproto,_spawnPosition.transform.position, new Quaternion(0,0,0,0)) as Vessel;


rock.GoOffRails();

I have a feeling this is entirely the wrong way to go about it :/ I suppose a crude way would be simply to rigidybody.addforce() pointing towards OceanNormal as this will be purely ground based and orbital considerations don't matter. All musing welcome!

Thanks, as ever.

Link to comment
Share on other sites

I have a feeling this is entirely the wrong way to go about it :/ I suppose a crude way would be simply to rigidybody.addforce() pointing towards OceanNormal as this will be purely ground based and orbital considerations don't matter.

Are these temporary ground objects like scatter? If so (and so their ultimate position in world space doesn't matter like, say, a KSC building would) then you're complicating things ;) KSP seems to adjust gravity properly and in the right direction for the current reference frame so you needn't do anything special:

19650802b5.png

You'll note in my code that I didn't do anything to make the coins fall: I just create them, set an initial rotation and then let gravity do its work

    [KSPAddon(KSPAddon.Startup.Flight, false)]
class GoldenShower : MonoBehaviour
{
private Rect _windowRect = new Rect(400, 400, 128f, 1f);
private GameObject _coinPrefab;
private const int ShowerCoinCount = 800;

void Start()
{
_coinPrefab = GameObject.CreatePrimitive(PrimitiveType.Sphere); // note: comes with sphere collider
_coinPrefab.transform.localScale = new Vector3(0.04f, 0.01f, 0.04f);

// KSP/Diffuse apparently needs a texture, can't just set a color like regular Diffuse shader
var goldTexture = new Texture2D(1, 1);
goldTexture.SetPixels32(new Color32[] {XKCDColors.GoldenYellow});
goldTexture.Apply();

_coinPrefab.renderer.material = new Material(Shader.Find("KSP/Diffuse")) { mainTexture = goldTexture };

var rb = _coinPrefab.AddComponent<Rigidbody>();
rb.mass = 0.01f;
rb.angularDrag = 5f;

_coinPrefab.collider.material = new PhysicMaterial
{
frictionCombine = PhysicMaterialCombine.Maximum,
bounceCombine = PhysicMaterialCombine.Minimum,
bounciness = 0.45f,
dynamicFriction = 0.05f,
staticFriction = 0.25f
};


_coinPrefab.SetActive(false);
}



void OnGUI()
{
_windowRect = KSPUtil.ClampRectToScreen(GUILayout.Window(123, _windowRect, DrawWindow, "Menu"));
}



private void DrawWindow(int winid)
{
GUILayout.BeginVertical();
GUILayout.Label(string.Format("Gravity: {0}", Physics.gravity.FString()));
GUILayout.Label(string.Format("Accel: {0}", Physics.gravity.magnitude));
if (GUILayout.Button("Increase monetary wealth?"))
StartCoroutine(CoinShower());
GUILayout.EndVertical();
GUI.DragWindow();
}


private float Random360()
{
return UnityEngine.Random.Range(0f, 360f);
}

private System.Collections.IEnumerator CoinShower()
{
print("Let there be wealth!");

var vessel = FlightGlobals.ActiveVessel;
float start = Time.realtimeSinceStartup;

for (int i = 0; i < ShowerCoinCount; ++i)
{
var spawn = vessel.GetWorldPos3D() + FlightGlobals.upAxis * 20f;
var coin = (GameObject)Instantiate(_coinPrefab, spawn + UnityEngine.Random.insideUnitSphere * 2f,
Quaternion.Euler(new Vector3(Random360(),
Random360(),
Random360())));

coin.rigidbody.velocity = vessel.rigidbody.velocity; // else if in orbit, coins will miss

// impart a bit of force to get it spinning
coin.rigidbody.AddTorque(new Vector3(Random360() * 0.1f, Random360() * 0.1f, Random360() * 0.1f), ForceMode.Impulse);

coin.SetActive(true);

// we might need to spawn more than [fps] coins per second if we're to reach ShowerCoinCount in
// two seconds
// so delay here if we're ahead of schedule, otherwise continue dumping coins
while ((Time.realtimeSinceStartup - start) / 2f <= (float) i / ShowerCoinCount)
yield return 0;

}

print("Wealth complete");
}
}

Link to comment
Share on other sites

Your Gameobject needs both a collider and a Rigidbody in order for physics to do its work. Here's a look at how I implemented physics way back in the old RT1 code. This snippet has to do with antennae breaking apart under high airflow, just like solar panels do. So the Gameobjects handled are all preexisting objects within a part hierarchy, which all have a collider of some sort.

In order for the detached objects to behave properly within the drag of an atmosphere, I wrote a DragModel to handle that. Also to make sure that the objects are deleted once they go beyond the loading range from the active vessel. Looking at my code now, I see that I actually forgot to implement the last part.

In any case, you wont have to go overboard with adding a custom drag model. You can simply add the stock physicalObject to your GameObjects to make them behave properly within KSPs fiddly physics.


SomeRockGameObject.AddComponent<physicalObject>()

And of course make sure that your GameObjects have both a collider and a RigidBody (that has a mass of >0).

Link to comment
Share on other sites

Yup, I was over-thinking it, and quite possibly did forget the mass or other prerequisite for gravity to work ;) Thanks for that little demo, there's loads of handy stuff in there, EvilReeper, and thanks for the extra references and tips JDP. I'll submit this for inclusion in the modding info links, I think, as it may prove useful to someone in the future.

One thing I can't figure out, having messed with a lot of the collider and physics material settings, is how to stop the objects falling through the terrain. Colliders appear to work, as they interact with vessel parts, but no matter what I do I can't stop them falling through the floor. Any ideas?

Also, class name really made me chuckle ;)

Edited by lo-fi
Link to comment
Share on other sites

One thing I can't figure out, having messed with a lot of the collider and physics material settings, is how to stop the objects falling through the terrain. Colliders appear to work, as they interact with vessel parts, but no matter what I do I can't stop them falling through the floor. Any ideas?

This was a known issue with concave colliders. Unity doesn't handle collision detection between two concave colliders that well, and since the terrain collider is concave, concave mesh colliders tend (or at least tended) to have some issues with the terrain. It could also be an issue with the terrain layermask though. Maybe someone has some more in-debth and up to date info on this.

Link to comment
Share on other sites

Interestingly, I found last night that using an object that's spawned from a .mu and has a sphere collider applied works fine. Using the potatoroid model, even having forced convex on the collider does not, and would always drop through the floor. Creating objects entirely with code, as in evilreepers example (which creates objects with sphere colliders) also results in objects going through the terrain, so I'm thinking something is being overlooked there. I'll get back with any insights if I manage to find anything further, though, as I'm still tinkering. Thanks for the physicalobject hint by the way, that's really handy. FFR, physicalobject.maxdistance units are meters.

Merry Christmas :)

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