- Home /
Problem is not reproducible or outdated
Another Gravity Question: Player suddenly flies upward
Edit: A new script was created to replace the Third Person controller, based off of the original controller. The player is not moving...
Edit: I found something out using the Lerpz Third Person Controller... The floating happens only after collision with the enemy. I ended up starting a game, colliding with the enemy several times, and then having the player float upward with all movements!
Gravity is giving me problems! I have the main character ("Player") in my game. He normally does what he should do when I control him, but at random times, he quickly floats upward. He eventually falls back downward, but not after leaving the room I have made through the ceiling. I have attached the Character Controller (from Unity) and a custom script for controlling the player. The code for the script is as follows:
//Set variables!
var runSpeed : float;
var gravity : float = 20;
var addedGravity : float = 3;
var rotateSpeed : float;
var speedSmoothing : float;
private var moveDirection : Vector3 = Vector3.zero;
var verticalSpeed : float = 0;
var moveSpeed : float = 0;
private var collisionFlags : CollisionFlags;
private var lockCameraTimer : float = 0;
private var movingBack : boolean = false;
private var isMoving : boolean = false;
function Awake (){
moveDirection = transform.TransformDirection(Vector3.forward);
}
function UpdateSmoothedMovementDirection(){
var cameraTransform : Transform = Camera.main.transform;
var grounded = IsGrounded();
var forward = cameraTransform.TransformDirection(Vector3.forward);
forward.y = 0;
forward = forward.normalized;
var right : Vector3 = Vector3(forward.z,0,-forward.x);
//Inputs
var v = Input.GetAxisRaw("Vertical");
var h = Input.GetAxisRaw("Horizontal");
right = Vector3(forward.z, 0, -forward.x);
var left = -right;
if(v< -0.2){
movingBack = true;
}
else{
movingBack = false;
}
var wasMoving : boolean = isMoving;
isMoving = Mathf.Abs(h) > 0.1 || Mathf.Abs(v)>0.1;
var targetDirection = h * right + v * left;
if(grounded){
if (isMoving != wasMoving)
lockCameraTimer += Time.deltaTime;
if (targetDirection != Vector3.zero){
moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 1000);
moveDirection = moveDirection.normalized;
}
var curSmooth = speedSmoothing * Time.deltaTime;
var targetSpeed = Mathf.Min(targetDirection.magnitude, 1.0);
moveSpeed = Mathf.Lerp(moveSpeed, targetSpeed, curSmooth);
}
}
function Update(){
//create variable for the controller
var controller : CharacterController;
controller = GetComponent(CharacterController);
//I know what to do here! Gravity!
moveDirection[1] -= gravity * Time.deltaTime;
UpdateSmoothedMovementDirection();
var movement = moveDirection * moveSpeed;
movement *= Time.deltaTime;
collisionFlags = controller.Move(movement);
if(IsGrounded()){
transform.rotation = Quaternion.LookRotation(moveDirection);
}
else{
moveDirection[1] -= gravity * Time.deltaTime * addedGravity;
}
}
function GetSpeed () {
return moveSpeed;
}
function IsGrounded () {
return (collisionFlags & CollisionFlags.CollidedBelow) != 0;
}
function GetDirection () {
return moveDirection;
}
function IsMovingBackwards () {
return movingBack;
}
function GetLockCameraTimer (){
return lockCameraTimer;
}
function IsMoving () : boolean {
return Mathf.Abs(Input.GetAxisRaw("Vertical")) + Mathf.Abs(Input.GetAxisRaw("Horizontal")) > 0.5;
}
function Reset (){
gameObject.tag = "Player";
}
@script RequireComponent(CharacterController)
@script AddComponentMenu("Third Person Player/Main M Controller")
Does anyone have any suggestions on fixing this?
Edit: Here is the Player Damage script, which contains a collision event with the enemy. private var canDamage : boolean = true;
public var invincibletime : float = 2.9;
function OnTriggerEnter(Enemy : Collider) { if(Enemy.gameObject.tag == "MarshmellowMan")
{
if(canDamage)
{
ApplyDamage();
}
else
{
return;
}
} }
function ApplyDamage() {
PlayerStat.health -= 1;
canDamage = false;
yield WaitForSeconds(invincibletime);
canDamage = true;
}
Did you alter the code on either the Char Cntlr or 3rdPrsnCntl in any way at all????
Are you positive there is no additional lines in Any of your other scripts dealing with movement at all(rotation included).
I am positive... This error happened immediately the first time I played the scene and has been decreasing in frequency. The error happens less than half of the time, but the existence of the error at all is bad.
One of my other scripts attached to the player only contains variables. It originally had a purpose, but the need for it became nonexistent. The only reason why I keep it is because other working scripts link to it.
The other script only deals with damage to the player. It contains a variable for invincibility. Currently, the enemies are not damaging the player for debug purposes.
Bringing comments to new position for new day.
"Finished writing the script. I can't control the character, though... Help?"
line 45 => is$$anonymous$$oving is a boolean , and you are trying to store a float in it. Looks like the wrong var name , and the math has an or statement which I just don't get. $$anonymous$$aybe it's there?
"What that math is saying is to store the results of the boolean operation as true if one of them is true... Basically this:
set ""is$$anonymous$$oving" to ... (((The absolute value of "h") > 0.1) OR ((The absolute value of "v") > 0.1))"
thanks. I shall have to check that out for myself later. Final thought - have you set the verticalSpeed and moveSpeed in the inspector? (set to 0 in var setup of script).
I checked in the inspector...to find that I hadn't attached the script! But the problem still continued when the script was in place.
I changed verticalSpeed and moveSpeed to be non-private variables. When I changed their values in the inspector, the player now just falls (face-first) into the ground. The speed of this was affected by the verticalSpeed.
Just to clarify, the player is not falling through the ground. One moment, his orientation is normal, and the next, he is on the ground as straight as a board.
Edit: ...bump...
Answer by reptilebeats · Mar 24, 2012 at 10:41 AM
I have self taught myself, modeling, scripting, textureising, art and unity it self with no knowledge of any before starting, and i have always made it a rule of thumb whenever testing scripts and objects to do it in an empty scene and then save as prefab. This is so i can quickly rule out problems with my game. Obviously a lot of different things in your game will be checking other scripts so take them into the empty scene and test it with it. For your problem it sounds if your arrow key is referenced possible in another script causing the character to jump in the air.
Check ur settings and try using a different key under a different name, i dont know the scripta ur using as i always custom wright my own to learn, even if im repeating a script
I just found that the player does the strange "anti-gravity" after colliding with the enemy. Any ideas?
this is a bad comment and I shouldn't be writing it . How about raycasting down, and if the distance is more than what it's supposed to be, add gravity/someforce down. assu$$anonymous$$g your terrain is (reasonably) flat and you don't have a jump ability or anything that requires the player to be in the air.
the better comment is : search what is being applied in the collision function ( i cannot see it in the above script). Use a debug to print when the collision happens , the player moveDirection before and after the collision , etc.
The reason why you don't see what is applied in the collision function is because there is no collision function in that script. The collision function is in a different script that deals purely with damage calculation, Player Damage.
Here is the code. This code will also be posted above.
private var canDamage : boolean = true;
public var invincibletime : float = 2.9;
function OnTriggerEnter(Enemy : Collider) { if(Enemy.gameObject.tag == "$$anonymous$$arshmellow$$anonymous$$an")
{
if(canDamage)
{
ApplyDamage();
}
else
{
return;
}
}
}
function ApplyDamage() {
PlayerStat.health -= 1;
canDamage = false;
yield WaitForSeconds(invincibletime);
canDamage = true;
}
Edit: I forgot to mention that I come to this conclusion by using the Third Person Controller from the Lerpz tutorial. $$anonymous$$y script for movement has not been fixed and might not be used if the problem can be fixed.
yup, looks fine ( do you need else-return though ). If you need this done quick, try the raycast idea. Better still, add force in ONE of the following functions :
in the UpdateSmoothed$$anonymous$$ovementDirection function at =>
if(grounded) {
//
} else {
// add Downward Force too keep player grounded
}
or in the function Update at =>
if(IsGrounded()){
transform.rotation = Quaternion.LookRotation(moveDirection);
} else {
// add Downward Force too keep player grounded
}
cool, at least the quirky can come off as a bit of fun, then just restart. And you have plenty of time after tomorrow to get into all the vids and ideas from this weekend 'cram'. have fun.