Hi everyone. I need to know something that I’m sure is easy, but my brain can’t wrap around it.
Basically, I have a spring object and I want to have my character spring from it along the springs y axis. Or simply, move an object relative to another objects y axis regardless of the first objects current rotation.
If the spring is a collider and your object has hit the spring, wouldn’t it just be a matter of increasing your object’s Y axis value through interations in an Update() function until it reaches the desired height? It’s already at the correct location in all other respects.
Alternatively, if your object is a Rigidbody, you could always just apply force (rigidbody.AddForceAtPosition) to it’s Y axis when it hits the collider and let physics do the work for you.
I’m still learning so take everything I say only half seriously
Thanks hjp, but that’s not what I’m looking for. That would only make the object move along it’s own y axis, not along a targets y axis.
Does it require serious vector math? What kind of formula would I need to pull this off so that my character (character controller by the way) would be able to approach a spring object and spring in the direction that the spring is pointing.
Ok. I have another problem. I figured I’d post it here instead of making a new topic because it’s still related to the spring.
I gotta tell you, I’m probably the worst programmer on the planet. This is something that anyone else could figure out but it’s persistently beating me up. I’ve been racking my brain on a way to get this to work but it’s practically impossible. I now want my character to spring in exactly the same way as if I hit the jump button (my character uses the character motor from beta 6).
Sounds sad, doesn’t it? Here’s the code I have so far.
#pragma strict
var strength : float = 0.0;
private var springTransform : Transform;
private var playerCollider : CharacterController;
private var playerController : CharacterMotor;
private var springUp : Vector3;
var hitSpring : boolean = false;
function Start ()
{
playerCollider = GameObject.Find ("First Person Controller").GetComponent (CharacterController) as CharacterController;
playerController = GameObject.Find ("First Person Controller").GetComponent (CharacterMotor) as CharacterMotor;
springTransform = GetComponent (Transform) as Transform;
springUp = springTransform.TransformDirection (Vector3.up);
}
function OnTriggerEnter (object : Collider)
{
if (object == playerCollider)
{
SpringCharacter();
}
}
function Update ()
{
//print (playerController.jumping.lastButtonDownTime);
if (hitSpring)
{
playerController.movement.velocity += springUp * CalculateSpringVerticalSpeed (strength) * Time.deltaTime;
}
}
function SpringCharacter ()
{
playerController.canControl = false;
playerCollider.transform.position = Vector3 (springTransform.position.x, playerCollider.transform.position.y + 0.5, springTransform.position.z);
playerController.movement.velocity = Vector3.zero;
hitSpring = true;
audio.Play();
yield WaitForSeconds (1.0);
hitSpring = false;
playerController.canControl = true;
}
function CalculateSpringVerticalSpeed (targetSpringHeight : float) //I don't even know what this function actually does!!!
{
// From the spring height and gravity we deduce the upwards speed
// for the character to reach at the apex.
return Mathf.Sqrt (2 * targetSpringHeight * playerController.movement.gravity);
}
This script is actually near perfect. It behaves how I want except for one important part in that, for some ungodly reason, when the character hits the spring, he doesn’t immediately spring up like he would if I hit the jump button. Instead, it’s as if he’s using retro rockets and is accelerating rather than instantly jumping. I thought it might have to do with gravity, but turning gravity to zero still has the same problem. I tried copying parts of the jump code to see if that would work, but it didn’t. Frankly, I’m not even sure why this is happening as my code looks like it should work. The worst part is that velocity is ran through so many changes per frame that I don’t have a clue what would be the problem.
The character controller uses update and that’s where all of it’s code is handled from, and it works.
I don’t use that function anymore. It made no difference if I used it or not.
That’s only there to make it so that the character comes to a halt (regardless of it’s speed) when it hits the spring. Changing it makes no difference.
Where are you getting this from? The playerController.movement.gravity variable equals 20! These aren’t my variables, they are in the character motor (that comes with Unity) and I’m simply manipulating them.
Thanks for your help, but nothing works. I’m quite baffled as to why it doesn’t work. The character motor’s jumping functions work the same way I want my spring to work, but they don’t work in the spring system for some reason and I can’t figure out why.
I’m very tempted at this point to just have my script execute a jump command and have the jump direction equal my spring direction. It’s just so hacky and stupid that I don’t want to, but given how difficult it is to script something like this that’s so simple, I’m not even sure I can.
Ha. I figured it out. It had to do with the grounded variable. I overlooked it and later realized that grounded, when enabled, makes the current velocity equal itself (or something, too lazy to look at it now).
Here’s the final code to make a spring that interacts with the first person controller. Feel free to use!
#pragma strict
var strength : float = 0.0;
private var springTransform : Transform;
private var playerCollider : CharacterController;
private var playerController : CharacterMotor;
private var springUp : Vector3;
private var hitSpring : boolean = false;
function Start ()
{
playerCollider = GameObject.Find ("First Person Controller").GetComponent (CharacterController) as CharacterController;
playerController = GameObject.Find ("First Person Controller").GetComponent (CharacterMotor) as CharacterMotor;
springTransform = GetComponent (Transform) as Transform;
springUp = springTransform.TransformDirection (Vector3.up);
}
function OnTriggerEnter (object : Collider)
{
if (object == playerCollider)
{
SpringCharacter();
}
}
function Update ()
{
if (hitSpring)
{
playerController.grounded = false;
playerController.movement.velocity += springUp * CalculateSpringVerticalSpeed (strength);
hitSpring = false;
}
}
function SpringCharacter ()
{
playerController.canControl = false;
playerCollider.transform.position = Vector3 (springTransform.position.x, playerCollider.transform.position.y + 0.5, springTransform.position.z);
playerController.movement.velocity = Vector3 (0, 0, 0);
hitSpring = true;
audio.Play();
yield WaitForSeconds (1.0);
playerController.canControl = true;
}
function CalculateSpringVerticalSpeed (targetSpringHeight : float)
{
return Mathf.Sqrt (2 * targetSpringHeight * playerController.movement.gravity);
}
Nice, you found your own solution. I got the gravity value from Edit → Project Settings → Physics.
I can’t find any documentation about CharacterMotor. O.k. I got it. It’s a new script and that use it’s own local gravity value. This First Person Controller don’t use the physics engine … That is not my way. Why they do something like that ???
In PhysX, there is a nice controller for that …
Even though the gravity variable is obviously coming from the playerController, not the physics?
Standard assets don’t come with docs.
Your way isn’t really possible. Physics with first person controllers is bad if you try to make the controller behave like a traditional fps character.
Give this a read and you’ll find out why the character controllers don’t make use of the physics engine (under details).
with the update of PhysX, there is a nice controller for that …
If you do your own, you must simulate or emulate it. That is a bad solution. This playercontroller is in his own world. More badly it does not go actually….