I am currently working on an Old school, 2d side scroller for the iPhone. we are using the character controller script to control the, you guessed it, main character. It allows it to run pretty smoothly and we are deep enough to have our heart set on said particular system. However, we’ve run into a snag. Due to the lack of rigidbodies, I’m unsure of how to handle a spring like system for the game. we just want to add a spring to the ground, and have it launch you into the air once you jump off of it.
The spring joint isn’t being very kind, and I’m not sure of any other rock solid places to look.
Any comments are welcome. I’m just looking for some direction before I pull ALL of my hair out.
just add a one time force upwards to it for example (or the same behaviour just through your own scripts if you don’t use physics)
A spring simply applies a force relative to its length. So, like dreamora said, for launching, just apply a force. If you want real spring behavior, vary the force based on displacement.
Force = -k * displacement
where k is the spring constant (strong or weak spring) and displacement is the offset from the spring’s rest length. the minus is due to the fact that a spring pulls in the opposite direction as the force displacing it.
If you want damping, you will have to track the velocity (not difficult).
Force = -k * displacement - damping * velocity
Ok. Let break this down step-by-step, so I don’t get overwhelmed by the code.
I set up an object to act as a spring. I give the object a rigidbody so I can apply force to it. I give the object a tag. The Platformer controller script recognizes the tag and governs the object. Once the character recognizes the object. I add a one time force.
So in one option, I can add a one time force: AddForce(Vector3.up *10); and I assume I would have to control that duration for a specified time with Time.deltaTime.
Or in the other option, I set up some spring variables for a rest length (displacement) and a spring constant (k). So now when the character recognizes the tag. I apply the force downward onto the object for a short time with Time.deltaTime, which should cause the object to spring back.
Have I misinterpreted either of your suggestions, and/or am I missing the general concept of how to do this?
You simply displace the endpoints of the spring and calculate the resulting force to apply. You don’t have to pull down, then release. you can pull on one end of the spring and the other will pull on your rigid body accordingly.
So, the spring script has 2 endpoint vectors, and a calculate force function. In this case, the input controls one end of the spring, and the other end pulls on the rigid body. So, use your input or whatever you want to move the first endpoint a certain distance, call calculate, and apply the resulting force in the direction of the spring to the rigid body.
If you have a high constant, the rigid body will snap to the new position. If you have a low constant, the rigid body will lag behind. If you have a damping value of 0, then the spring will oscillate forever. If you have a damping value of < 0.0 it will gain energy and explode. If you have a value of > 0.0 it will eventually come to rest.
If you want to launch something like a catapult, just place the first endpoint far away and in the direction you want to launch the rigid body. Then just keep calling the function that calculates the force until the displacement == rest length.
Let me try a for instance:
Inside of the Platform Controller script:
var sprung : boolean = false;
if(hit.gameObject.tag == spring){
sprung = true;
}
So now i have the spring script check to see if that variable is true somehow.
Spring script:
var end1 : Vector3;
var end2 : Vector3;
var Force : int;
var k : int;
var damp : int = 0.2;
var displacement : int;
function Update(){
if(sprung){
//displace end1
end1.transfrom.y = whatever;
Calculate();
}
}
function Calculate(){
Force = -k * displacement - damping * velocity;
end2.AddForce(Vector3.down * Force);
}
I apologize if I’m frustrating you. I’m still getting a grasp on Unity’s coding structure. I can read, and I can even comprehend it. I’m just having trouble coming up with scripts on my own. Is the above faux-javascript at all close o what you are describing. The platformer controller script is controlling my collisions, which is why I have that bit in there. I really just wanted to try and understand this in coding terms before I try to implement it. I mean, I’m kinda getting what you’re driving at, I’m just struggling with how to implement it.
And I really do appreciate the help. Thank you very much.
Looks pretty good conceptually, but I’m not a java script guy, so I might be missing something.
I would make the int values into floats, and you don’t need to track the end points with vectors if you are only using one axis-aligned direction. But if you want to launch in any arbitrary direction, simply subtract the two endpoints and normalize to get the direction vector. That way you could just move around the end point in 3d space and apply the force along the spring with direction.
You will also want to stop calling calculate at some point. A good place to reset your “sprung” variable would be when displacement reaches zero (before the spring begins to apply forces in the opposite direction as it compresses). You should make a note of rest length so it is clear how you are calculating displacement. But actually, since your spring will never need to compress, you can have a rest length of zero, so displacement == distance between endpoints.
You will also need to calculate velocity (a simple way would be to use the delta displacement but you could also just use the velocity from the rigid body) for damping. But since damping is only interesting with oscillations, you really can leave it out.
Also, from the docs:
“If you want to apply a force over several frames you should apply it inside FixedUpdate instead of Update.”
Otherwise, looks good to me.