Getting rid of the unitys charachter controller. Problem with movement scripting

Hello,

I am pretty new to Unity and I am trying to make character controller movement script without using the Unitys character controller. I just want to apply physics to my character so I need a controller with rigidbody.

I was following an example in Unity 3.x scripting book:

With the difference that I am coding in C# and because of that I made some changes to the script… I also think that is actually why it is not working :slight_smile:

I almost got everything working but I have a problem with the mouselook-script. When I move the mouse and then move the character using the movement buttons in keyboard the character looses it’s direction. For example if I push the up arrow and try to move straight forward my character is moving almost straight to the right.

Can anyone spot what I am doing wrong here? The most important functions are the inputcontrollerscripts movement() -function and camera scripts Apply() -function.

Here is my inputcontrollerscript:

using UnityEngine;
using System.Collections;

public class FPSInputController : MonoBehaviour {
	
	public int Speed = NORMALSPEED;
	public float JumpSpeed = 350;
	public float Gravity = NORMALGRAVITY;
	
	public Vector3 MoveDirection = Vector3.zero;
	public Vector3 JumpDirection = Vector3.zero;
	public bool Grounded = false;
	public bool Jumping = false;
	public bool InAir = false;
	public float AirControl = 0.5f;
	public bool JumpClimax = false;
	
	public PlayerState.playerState pState = PlayerState.playerState.Normal;
	
	// needed for camera
	public GameObject CPrefab;
	public CameraScr CameraInstance;
	
	private ContactPoint contact;
		
	private const int NORMALSPEED = 6;
	private const int NORMALJUMPSPEED = 12;
	private const float NORMALGRAVITY = 20;

	
	void Start() {
		//Initialize camera in start function
		if(CPrefab == null)
		{
			print ("Finding prefab");
			CPrefab = GameObject.FindGameObjectWithTag("PlayerCamera");
			CameraInstance = CPrefab.GetComponent<CameraScr>();
			CameraInstance.Initialize(transform);
		} else {
			CameraInstance = CPrefab.GetComponent<CameraScr>();
			CameraInstance.Initialize(transform);
		}
	}
	
	// FixedUpdate is called once per frame
	void FixedUpdate() {
	
		//toggle camera
		if(Input.GetKey(KeyCode.T)) {

			CameraInstance.SetCamValue();
		}
		if(!Grounded) {
			// At the moment character capsule height is 2 (3rd param in Raycast)so we will get the point in the middle of the character
			// since the raycast is started from there. If we change the capsule size also change this script
			if(Physics.Raycast(transform.position, -transform.up, 2f/2f + 0.2f))
			{
				print("grounded");
				Grounded = true;
				Jumping = false;
				InAir = false;
				JumpClimax = false;
			} else if (!InAir) {
				InAir = true;
			} else if (InAir  rigidbody.velocity.y == 0) {
				JumpClimax = true;
			}
		}
		//this rotate call allows camera angle change the movement direction
		transform.Rotate(new Vector3(0, Input.GetAxis("Mouse X"), 0) * Time.deltaTime * CameraInstance.MouseSpeed );
		Movement ();
	}
	
	/* Checks when character is leaving the ground (jumps)*/
	void OnCollisionExit(Collision collisionInfo) {
        Grounded = false;
    }
	
	/* prevents charater to get stuck on inside other colliders*/
	void OnCollisionStay(Collision collisionInfo) {
		contact = collisionInfo.contacts[0];
		if(InAir || Jumping) {
			rigidbody.AddForceAtPosition(-rigidbody.velocity, contact.point);
		}
	}
	
	/*All the character movement is done here*/
	void Movement()
	{
		//if( Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0) {
		
			MoveDirection = new Vector3(Input.GetAxis("Horizontal"),0 ,Input.GetAxis("Vertical"));
			MoveDirection = transform.TransformDirection(MoveDirection);
			
			if(Input.GetButtonDown("Jump")  Grounded) {
				print ("Jumping");
				Jumping = true;
				JumpDirection = MoveDirection;
				rigidbody.AddForce( (transform.up) * JumpSpeed);
			}
			if(Grounded) {
				
				this.transform.Translate( (MoveDirection.normalized * Speed) * Time.deltaTime);
			} 
			else if ( Jumping || InAir ) {
			
				this.transform.Translate(( JumpDirection.normalized * Speed * AirControl) * Time.deltaTime);
			
			}
		//}
	}
}

And here is the camera script:

using UnityEngine;
using System.Collections;

public class CameraScr : MonoBehaviour {
	
	public const float CAMDISTANCE1 = 1.3f;
	public const float CAMDISTANCE2 = -5.0f;
	public const float CAMDISTANCE3 = -10.0f;
	public const float CAMHEIGHTOFFSET1 = 2.0f;
	public const float CAMHEIGHTOFFSET2 = 2.0f;
	public const float CAMHEIGHTOFFSET3 = 2.0f;
	
	public enum CamType {
		FP,
		SP,
		TP
	}
	public CamType CameraType;
	public int CamNum = 0;
	public float CamDistance;
	public float CamHeightOffset;
	
	public Transform CharObj;
	private float x = 0.0f;
	private float y = 0.0f;
	private float StartRotation = 0;
	public float MouseSpeed = 300f;
	public float MinimumY = -60f;
	public float MaximumY = 60f;
	
	public void Initialize( Transform Player ) {
		CamNum = 3;
		CameraType = CamType.TP;
		CharObj = Player;
		
		StartRotation = CharObj.transform.eulerAngles.y;
		x = transform.eulerAngles.x;
		y = transform.eulerAngles.y;
		SetCamValue();
	}
	
	void Apply() {
	
	 	x += Input.GetAxis("Mouse X") * MouseSpeed * Time.deltaTime;
	 	y -= Input.GetAxis("Mouse Y") * MouseSpeed * Time.deltaTime;
		y = clampAngle(y, MinimumY, MaximumY);
		
		Quaternion rotation = Quaternion.Euler(y, x + StartRotation, 0);
		Vector3 targPos = rotation * (new Vector3(0.0f, 0.0f, CamDistance)) + CharObj.position;
		targPos.y += CamHeightOffset;
		transform.rotation = rotation;
		transform.position = targPos;
	}
	
	public static float clampAngle(float Angle, float Min, float Max ) {
	
		if( Angle < -360 ) {
		Angle += 360;
		}
		if( Angle > 360 ) {
		Angle -= 360;
		}
		return Mathf.Clamp ( Angle, Min, Max );
	}
	
	public void SetCamValue() {
		ChangeCamType();
		switch(CameraType) {
			case CamType.FP:
			{
				print ("Firstperson camera selected");
				CamDistance = CAMDISTANCE1;
				CamHeightOffset = CAMHEIGHTOFFSET1;
				break;
			}
			case CamType.SP:
			{
				print ("Secondperson camera selected");
				CamDistance = CAMDISTANCE2;
				CamHeightOffset = CAMHEIGHTOFFSET2;
				break;
			}
			case CamType.TP:
			{
				print ("Thirdperson camera selected");
				CamDistance = CAMDISTANCE3;
				CamHeightOffset = CAMHEIGHTOFFSET3;
				break;
			}
		}
	}
	
	public void ChangeCamType() {
		print ("TOOGGGLLLEEEEE THISSSSSS!!!!");
		switch(CamNum){
			case 1:
			{
				CameraType = CamType.SP;
				CamNum = 2;
				break;
			}
			case 2:
			{
				CameraType = CamType.TP;
				CamNum = 3;
				break;
			}
			case 3:
			{
				CameraType = CamType.FP;
				CamNum = 1;
				break;
			}
		}
	}


	
	void LateUpdate(){
		if(CharObj) {
			Apply();
		}
	
	}
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

http://wiki.unity3d.com/index.php/RigidbodyFPSWalker

Thanks! I think I can use that :slight_smile: