Problems with Player Controller .. Ground seems to be random..

My player controller appears to be applying random gravity…
It don’t know when its grounded and when it is not.

My setup is.
GameObject
-PlayerController collier
-UnitPlayer Script
-Unit Script.
Player is tagged as player… not that that matters at the moment…

also scale is 1.5,1.5,1.5 if player transform.
Character controller
slope 45
offset .03
skin 08
min move 0
center 0 0 0
rad 0.5000001
height 2.

I have another GameObject named #MainGame
attached to it is the GlobalGameObjects script.
just so i can pass around some stuff for testing…

the player, is just a capsule.
for testing…

unit .cs

using UnityEngine;
using System.Collections;

//Get Main GameWorld Namespace..
using GameWorld;

//Remove default collider when this script is added to unity because the character controllerp provides its own collider.
[RequireComponent(typeof(CharacterController))]

public class Units : MonoBehaviour {
	
	protected CharacterController control; 
	
	protected bool jump;
	protected bool run;
	
	protected Vector3 move = Vector3.zero;
	protected Vector3 forward = Vector3.zero;
	protected Vector3 right = Vector3.zero;
	
	protected Vector3 gravity = Vector3.zero;
	protected float velocity = 0f;

	protected ParticleSystem turboparticle;
	protected ParticleSystem turboparticle2;
		
	protected GlobalGameObjects globalgameobjects;
	
	// Use this for initialization
	public virtual void Awake () {
		
		//Gets the main gameworld from primary GameObject.
		globalgameobjects = GameObject.Find("#MainGame").GetComponent<GlobalGameObjects>();
		
		//get particle system childs.
		//turboparticle = transform.FindChild("TurboParticle").GetComponent<ParticleSystem>();
		//turboparticle2 = transform.FindChild("TurboParticle2").GetComponent<ParticleSystem>();
		
		//Gets Attached character Controller.
		control = GetComponent<CharacterController>();
		
		if (control == null)
		{
			Debug.LogError(name + ": No Controller Character!");
		}
		
	}
	
	// Update is called once per frame
	public virtual void Update () {
		
		if (!control.isGrounded)
		{
			Debug.Log("in air");
			gravity += Physics.gravity * Time.deltaTime;
		}
		else
		{
			gravity = Vector3.zero;
			Debug.Log("grounded");
			
			if (jump)
			{
				//transform.audio.Play();
				Debug.Log("jump");
				
				gravity.y = globalgameobjects.JumpHeight;
				
				if (globalgameobjects.Turbo >= 02f)
				//turboparticle2.Play();
				
				if (globalgameobjects.Turbo > 0f)
				{
				//turboparticle.Play();
				gravity.y += globalgameobjects.Turbo * 100f;
				}
				jump = false;
			}
			
		}
		move += gravity;
			
		control.Move(move * Time.deltaTime);
		
	}
	
}

unit player.cs

using UnityEngine;
using System.Collections;

public class UnitsPlayer : Units {
	
	// Use this for initialization
	public virtual void Awake () {	
		base.Awake ();
	}
	
	// Update is called once per frame
	void Update () 
	{
		
		//rotate player before move..
		Vector3 transformeulangles = transform.eulerAngles;		
		if (Input.GetKey(KeyCode.A))
		{
			transformeulangles.y += -globalgameobjects.TurnSpeed  * Time.deltaTime;	
		}
		
		if (Input.GetKey(KeyCode.D))
		{
			transformeulangles.y += globalgameobjects.TurnSpeed  * Time.deltaTime;
		}			
		transform.eulerAngles = transformeulangles;	
		//done rotating player.
		
		
		forward = transform.forward;
		//right = new Vector3(forward.z,0,-forward.z);
		
		float horizontalInput = Input.GetAxisRaw("Horizontal");
		float verticalInput = Input.GetAxisRaw("Vertical");
		
		//Vector3 targetDirection = horizontalInput * right + verticalInput * forward;	
		Vector3 targetDirection =  verticalInput * forward;	
		
		move = Vector3.RotateTowards(move, targetDirection, 200 * Mathf.Deg2Rad * Time.deltaTime, 1000);
 	
		run = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
		
		//move = move  * Time.deltaTime * globalgameobjects.RunSpeed;
		
		if (run)
		{
			move *= globalgameobjects.RunSpeed * Time.deltaTime;
		}
		else
		{
			move *= globalgameobjects.WalkSpeed * Time.deltaTime;
		}
		
		//get local from global
		if (Input.GetMouseButtonUp(0))
		{
			jump = true;
		}
		
		
		base.Update();
				
	}
	
	
}

GlobalGameObjects.cs

using UnityEngine;
using System.Collections;

namespace GameWorld
{
	public class GlobalGameObjects : MonoBehaviour
	{
	
		public float Turbo = 0f;
		public bool Alive = true;
		public float Strength = 0f;
		
		public int Lifes = 5;
		public float WalkSpeed = 1f;
		public float RunSpeed = 2;
		public float JumpHeight = .5f;
		public float TurnSpeed = 50f;
		
		
		public bool SimulateGravity = true;
		
		void Awake(){
		
			Screen.lockCursor = true;
		
		}

		// Use this for initialization
		void Start ()
		{
	
		}
	
		// Update is called once per frame
		void Update ()
		{
	
		}
	}

}

anyone know why my player would be grounded then in the air then grounded randomly while moving ?

You should apply gravity even if your controller is not grounded.
When you call Move it won’t report that player is grounded if it doesn’t collide with ground during that Move. Setting gravity to zero when controller is grounded will make velocity completely horizontal and it won’t collide with ground so it will stay grounded just for a frame. Your code actually changes isGrounded every frame.

Hi aniv,

Thanks for the reply, much appreciated.
Now I think I am on the right track here.

I don’t fully understand how to apply the gravity vector and the tutorial I watched on it was wrong =/

So, when I changed my code to apply gravity constantly it seems to work…
IE, i am always grounded when I should be and its no longer random.

But now when I try to jump…
I try adding a value to gravity.y and my charter instantly teleports up in the air instead of jumping.
and then we he falls back down… that dont work either =/

Any idea where i can find a simple explanation of applying gravity and jumping…
trying to apply gravity as a vector force. … if that helps.

Your move vector is actually velocity of the object.
You should add a value to the move vector, not to gravity because jumping is (almost) instantaneous change in velocity.
And because gravity is an acceleration and velocity is product of time and acceleration: move = gravity * TIme.deltaTime
And part control.Move(move * Time.deltaTime) is right because you need to pass displacement to Move method and it is a product of velocity and time.
There is a simple example in Unity reference on how to apply gravity and jump with character controller:

If you are interested about the physics behind it and how to calculate jump height read about free fall.
I found this explanation: Free Fall :: Physics Tutorials

Thanks aniv…
Ya, my physics needs some brushing up =x.

I will look into that, as It explains things a little more then I first understood about it.