I first experienced this camera system in Mass Effect 1. Was a bit annoying during a couple of minutes, but then I got used to it and started to like it. Was also used in The Witcher 2 and 3, and I wanted to implement it for a future RPG project we are designing. But my lack of math skills prevented me from implementing a working prototype, until a few days ago, when I figured out a way to achieve it.So, I decided to post this little TPS tutorial, in case it can help somebody.
Look at the following gameobject hierarchy:
The relevant objects are player and Pivot. The first one is the player (model, collider, etc) obviously. The second is the parent of the camera and handles its rotations, via the following script:
float rotationY = 0F;
Camera cam;
// Use this for initialization
void Start () {
cam = gameObject.GetComponentInChildren<Camera> ();
}
// 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);
}
}
The player gameobject also has an script, that deals with player movements, and also keeps the pivot sinchronized with its own position:
public GameObject pivot;
// Use this for initialization
void Start () {
Cursor.visible = false;
Screen.lockCursor = true;
}
// Update is called once per frame
void Update () {
pivot.transform.position = gameObject.transform.position;
if (Input.GetKey (KeyCode.W)) {
Vector3 rot = gameObject.transform.localEulerAngles;
rot.y = pivot.transform.localEulerAngles.y;
gameObject.transform.rotation = Quaternion.Slerp (gameObject.transform.rotation, Quaternion.Euler (rot), 5f * Time.deltaTime);
gameObject.transform.Translate (0, 0, 20 * Time.deltaTime);
pivot.transform.Translate (0, 0, 20 * Time.deltaTime);
} else if (Input.GetKey (KeyCode.S)) {
//go back
Vector3 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);
gameObject.transform.Translate (0, 0, 20 * Time.deltaTime);
pivot.transform.Translate (0, 0, 20 * Time.deltaTime);
}
}
Perhaps not the most elegant solution, but seems to work.
Look at the following gameobject hierarchy:
The relevant objects are player and Pivot. The first one is the player (model, collider, etc) obviously. The second is the parent of the camera and handles its rotations, via the following script:
float rotationY = 0F;
Camera cam;
// Use this for initialization
void Start () {
cam = gameObject.GetComponentInChildren<Camera> ();
}
// 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);
}
}
The player gameobject also has an script, that deals with player movements, and also keeps the pivot sinchronized with its own position:
public GameObject pivot;
// Use this for initialization
void Start () {
Cursor.visible = false;
Screen.lockCursor = true;
}
// Update is called once per frame
void Update () {
pivot.transform.position = gameObject.transform.position;
if (Input.GetKey (KeyCode.W)) {
Vector3 rot = gameObject.transform.localEulerAngles;
rot.y = pivot.transform.localEulerAngles.y;
gameObject.transform.rotation = Quaternion.Slerp (gameObject.transform.rotation, Quaternion.Euler (rot), 5f * Time.deltaTime);
gameObject.transform.Translate (0, 0, 20 * Time.deltaTime);
pivot.transform.Translate (0, 0, 20 * Time.deltaTime);
} else if (Input.GetKey (KeyCode.S)) {
//go back
Vector3 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);
gameObject.transform.Translate (0, 0, 20 * Time.deltaTime);
pivot.transform.Translate (0, 0, 20 * Time.deltaTime);
}
}
Perhaps not the most elegant solution, but seems to work.
Comments
Post a Comment