Tuesday, February 9, 2016

TPS with free look tutorial, version 2 (and bugs)

After working a bit to improve the third person camera system I mentioned a couple of days ago, I found a few problems that I could fix, and other I cant. Here is the updated code:

public class PlayerControl : MonoBehaviour {

    public GameObject pivot;
    Animator anim;
    int direction = 0;
    int FORWARD  = 1;
    int BACKWARD = 2;
    int LEFT = 3;
    int RIGHT = 4;

    // Use this for initialization
    void Start () {
        //cam = gameObject.GetComponent<Camera> ();
        //Cursor.visible = false;
        //Cursor.lockState = CursorLockMode.Locked;
        anim = gameObject.GetComponent<Animator> ();
    }
   
    // Update is called once per frame
    void Update () {
        Vector3 rot;

        if (Input.GetKeyDown (KeyCode.W)) {
            direction = FORWARD;
        } else if (Input.GetKeyDown (KeyCode.S)) {
            //go back
            direction = BACKWARD;
        } else if (Input.GetKeyDown (KeyCode.A)) {
            direction = LEFT;
        } else if (Input.GetKeyDown (KeyCode.D)) {
            direction = RIGHT;
        } else if (Input.GetKeyUp (KeyCode.W) || Input.GetKeyUp (KeyCode.S) || Input.GetKeyUp (KeyCode.A) || Input.GetKeyUp (KeyCode.D)) {
            direction = 0;
        }

        switch (direction) {
            case 0: //do nothing
                anim.SetInteger("State",0);
                break;
            case 1:        //forward
                rot = gameObject.transform.localEulerAngles;
                rot.y = pivot.transform.localEulerAngles.y;
                gameObject.transform.rotation = Quaternion.Slerp (gameObject.transform.rotation, Quaternion.Euler (rot), 5f * Time.deltaTime);
                anim.SetInteger("State",1);
                gameObject.transform.Translate (0, 0, 20 * Time.deltaTime);               
                pivot.transform.position = Vector3.Slerp(pivot.transform.position, gameObject.transform.position, 5f *Time.deltaTime);
                break;
            case 2: //
                rot = gameObject.transform.localEulerAngles;
                rot.y = pivot.transform.localEulerAngles.y+180f;
                gameObject.transform.rotation = Quaternion.Slerp (gameObject.transform.rotation, Quaternion.Euler (rot), 5f * Time.deltaTime);
                anim.SetInteger("State",1);
                gameObject.transform.Translate (0, 0, 20 * Time.deltaTime);               
                pivot.transform.position = Vector3.Slerp(pivot.transform.position, gameObject.transform.position, 5f *Time.deltaTime);
                break;
            case 3:
                rot = gameObject.transform.localEulerAngles;
                rot.y = pivot.transform.localEulerAngles.y-90f;
                gameObject.transform.rotation = Quaternion.Slerp (gameObject.transform.rotation, Quaternion.Euler (rot), 5f * Time.deltaTime);
                anim.SetInteger("State",1);
                gameObject.transform.Translate (0, 0, 20 * Time.deltaTime);               
                pivot.transform.position = Vector3.Slerp(pivot.transform.position, gameObject.transform.position, 5f *Time.deltaTime);
            break;
            case 4:
                rot = gameObject.transform.localEulerAngles;
                rot.y = pivot.transform.localEulerAngles.y+90f;
                gameObject.transform.rotation = Quaternion.Slerp (gameObject.transform.rotation, Quaternion.Euler (rot), 5f * Time.deltaTime);
                anim.SetInteger("State",1);
                gameObject.transform.Translate (0, 0, 20 * Time.deltaTime);               
                pivot.transform.position = Vector3.Slerp(pivot.transform.position, gameObject.transform.position, 5f *Time.deltaTime);
            break;
        }
    }
}

The above code handles player movement, the next, handles camera free look:

public class PivotControl : MonoBehaviour {
    float rotationY = 0F;
    Camera cam;
    Text label;

    // Use this for initialization
    void Start () {
        cam = gameObject.GetComponentInChildren<Camera> ();
        label = GameObject.Find ("Label").GetComponent<Text>();;
    }
   
    // Update is called once per frame
    void Update () {       
        if (Input.GetAxis ("Mouse X") != 0 || Input.GetAxis ("Mouse Y") != 0) {
                       float rotationX = gameObject.transform.localEulerAngles.y + Input.GetAxis("Mouse X") * 2f;

            rotationY += Input.GetAxis("Mouse Y") * 5f;       
            gameObject.transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
            cam.transform.LookAt(cam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, cam.farClipPlane)));
            //check if we are looking at something we can interact with                
            RaycastHit hit; 
            Ray ray =  cam.ViewportPointToRay(new Vector3(0.5F, 0.5F, 0));
            if (Physics.Raycast (ray, out hit, 100)) {
                                    if (hit.collider.tag=="Interactable")
                    label.text = "Press E to interact with "+hit.collider.name;
            } else {
                label.text = "";
            }
        }
    }
}

Ok,  whats the problem here? Well, the camera free look works, but I find that the picking system is not precise. Also, the player is not being rotated exactly towards the camera direction when the angle between player and camera orientation is large (like, the camera is looking to the screen left side). I think Im missing something important here, like resynch the camera to the screen center or something. Also, I havent implemented yet a crosshair system.
Sure you can make a game with the current code, but it lacks the polish a professional title should have.

No comments:

Post a Comment