Argument `#1' cannot convert `UnityEngine.Vector3' expression to type `float'

using UnityEngine;
using System.Collections;

public class Igrac : MonoBehaviour
{
    public bool controllable = false;

    public float speed = 7.0f;
    public float jumpSpeed = 6.0f;
    public float gravity = 20.0f;

    private Vector3 moveDirection =new Vector3(0, 0, 0);
    private CharacterController controller;

    // Use this for initialization
    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    // Update is called once per frame
    void Update()
    {
        if (controller.isGrounded && controllable)
        {
            moveDirection += new Vector3(Input.GetAxis("Vertical") * transform.right, 0, Input.GetAxis("Horizontal") * transform.forward);
            moveDirection = transform.TransformDirection(moveDirection);
            moveDirection *= speed;

            if (Input.GetButton("Jump"))
                moveDirection.y = jumpSpeed;

        }
        moveDirection.y -= gravity * Time.deltaTime;
        controller.Move(moveDirection * Time.deltaTime);
    }
}

Firstly, transform.right and transform.forward are Vector3s. On line 26 you’re passing them as arguments to the Vector3 constructor - but it expects floats. You can achieve what you’re trying to do by summing them instead.

Secondly, you’re transforming moveDirection from local space to world space, but transform.right and transform.forward are both already in world space so this is unnecessary.

Thirdly, multiplying moveDirection by speed every frame will result in an acceleration.

Replace lines 26-28 with this instead:

var worldSpaceDir = transform.right * Input.GetAxis("Vertical") +
                    transform.forward * Input.GetAxis("Horizontal");

moveDirection += worldSpaceDir.normalized * speed;

Now my character moves super fast

My speed is determined by how long i hold it and the controls are super slippery and the forward movements are inverted

I see. The code provided above fixes the problems with your original code. It works (aside from the per frame acceleration) as it would if yours had compiled.

This is due to how Input.GetAxis works and is setup in the InputManager. If you don’t want that behaviour you can either use a different Input method/setup or snap the values by rounding them. Snapping would look like this:

var worldSpaceDir = transform.right * Mathf.Round(Input.GetAxis("Vertical")) +
                    transform.forward * Mathf.Round(Input.GetAxis("Horizontal"));

In that case, negate the forward direction:

var worldSpaceDir = transform.right * Mathf.Round(Input.GetAxis("Vertical")) -
                    transform.forward * Mathf.Round(Input.GetAxis("Horizontal"));