Developing a 3D FPS game in Unity.
The code below is set up so that the player can walk in the direction of the mouse.
However, if you point the mouse cursor up, the player will walk towards the sky, and if you point the mouse cursor down, the player will push through the ground and go underground. In other words, it is in a state of walking in all directions.
I would like to fix this.
I want the player to be able to look up and down, but not be able to advance up and down.
How can I modify the code?
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FPSController : MonoBehaviour
{
float x, z;
float speed = 0.1f;
public GameObject cam;
Quaternion cameraRot, characterRot;
float Xsensityvity = 3f, Ysensityvity = 3f;
bool cursorLock = true;
float minX = -90f, maxX = 90f;
public Animator animator;
public GameObject meinCamera,subCamera;
// Start is called before the first frame update
void Start()
{
cameraRot = cam.transform.localRotation;
characterRot = transform.localRotation;
GameState.canShoot = true;
}
// Update is called once per frame
void Update()
{
float xRot = Input.GetAxis("Mouse X") * Ysensityvity;
float yRot = Input.GetAxis("Mouse Y") * Xsensityvity;
cameraRot *= Quaternion.Euler(-yRot, 0, 0);
characterRot *= Quaternion.Euler(0, xRot, 0);
cameraRot = ClampRotation(cameraRot);
cam.transform.localRotation = cameraRot;
transform.localRotation = characterRot;
UpdateCursorLock();
}
if(Mathf.Abs(x) > 0 || Mathf.Abs(z) > 0)
{
if(!animator.GetBool("Walk"))
{
animator.SetBool("Walk", true);
PlayerWalkFootStep(WalkFootStepSE);
}
}
else if(animator.GetBool("Walk"))
{
animator.SetBool("Walk", false);
StopFootStep();
}
if(z > 0 && Input.GetKey(KeyCode.LeftShift))
{
if(!animator.GetBool("Run"))
{
animator.SetBool("Run", true);
speed = 0.25f;
PlayerRunFootStep(RunFootStepSE);
}
}
else if(animator.GetBool("Run"))
{
animator.SetBool("Run", false);
speed = 0.1f;
StopFootStep();
}
if(Input.GetMouseButton(1))
{
subCamera.SetActive(true);
meinCamera.GetComponent<Camera>().enabled = false;
}
else if(subCamera.activeSelf)
{
subCamera.SetActive(false);
meinCamera.GetComponent<Camera>().enabled = true;
}
}
private void FixedUpdate()
{
x = 0;
z = 0;
x = Input.GetAxisRaw("Horizontal") * speed;
z = Input.GetAxisRaw("Vertical") * speed;
//transform.position += new Vector3(x,0,z);
transform.position += cam.transform.forward * z + cam.transform.right * x;
}
public void UpdateCursorLock()
{
if(Input.GetKeyDown(KeyCode.Escape))
{
cursorLock = false;
}
else if(Input.GetMouseButton(0))
{
cursorLock = true;
}
if(cursorLock)
{
Cursor.lockState = CursorLockMode.Locked;
}
else if(!cursorLock)
{
Cursor.lockState = CursorLockMode.None;
}
}
public Quaternion ClampRotation(Quaternion q)
{
q.x /= q.w;
q.y /= q.w;
q.z /= q.w;
q.w = 1f;
float angleX = Mathf.Atan(q.x) * Mathf.Rad2Deg * 2f;
angleX = Mathf.Clamp(angleX, minX, maxX);
q.x = Mathf.Tan(angleX * Mathf.Deg2Rad * 0.5f);
return q;
}
}
You could use Vector3.ProjectOnPlane
in order to map any movement input into a flat direction on the XZ plane like
transform.position += Vector3.ProjectOnPlane(cam.transform.forward * z + cam.transform.right * x, Vector3.up);
I see though that you are using the FixedUpdate
which looks like you are using Rigidbody
and physics. If this is the case you shouldn't do anything via transform
but rather through the Rigidbody
component.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.