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 ![]()
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 () {
}
}