i have a weird glitch, when i walk down from a corner (i dont press jump), the player will falling down with very fast speed. If i jump, then everything goes normal. (Its Quill18 FPS controller, i learn from there so thats why i dont use the built in controller instead)
using UnityEngine;
using System.Collections;
[RequireComponent (typeof(CharacterController))]
public class FirstPersonController : MonoBehaviour
{
public float movementSpeed = 5.0f;
public float mouseSensitivity = 5.0f;
public float jumpSpeed = 20.0f;
float verticalRotation = 0;
public float upDownRange = 60.0f;
float verticalVelocity = 0;
CharacterController characterController;
// Use this for initialization
void Start()
{
// Screen.lockCursor = true;
characterController = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
// Rotation
float rotLeftRight = Input.GetAxis("Mouse X") * mouseSensitivity;
transform.Rotate(0, rotLeftRight, 0);
verticalRotation -= Input.GetAxis("Mouse Y") * mouseSensitivity;
verticalRotation = Mathf.Clamp(verticalRotation, -upDownRange, upDownRange);
Camera.main.transform.localRotation = Quaternion.Euler(verticalRotation, 0, 0);
// Movement
float forwardSpeed = Input.GetAxis("Vertical") * movementSpeed;
float sideSpeed = Input.GetAxis("Horizontal") * movementSpeed;
verticalVelocity += Physics.gravity.y * Time.deltaTime;
if (characterController.isGrounded && Input.GetButton("Jump"))
{
verticalVelocity = jumpSpeed;
}
Vector3 speed = new Vector3(sideSpeed, verticalVelocity, forwardSpeed ;
speed = transform.rotation * speed;
characterController.Move(speed * Time.deltaTime);
}
}
The problem is that every frame you're running this line:
verticalVelocity += Physics.gravity.y * Time.deltaTime;
Thus, you're gaining "momentum" each second, and it wont stop ever until you jump because you're "resetting" the Y velocity to a normal value. I've ran into this problem before, and it can be fixed simply by only adding the Y velocity when you're not grounded. You can use Raycast to check if you have ground, and if you dont, increase verticalVelocity by that amount.
Related
I am using this movement code with a box collider in unity (I am quite a beginner)
public class Movement : MonoBehaviour
{
public float speed = 10.0f;
void Update()
{
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
transform.Translate(new Vector3(horizontalInput, 0, verticalInput) * Time.deltaTime * speed);
And this mouselook code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Mouselook : MonoBehaviour
{
public float sensitivity = 100.0f;
public float clampAngle = 80.0f;
private float rotX = 0.0f;
private float rotY = 0.0f;
void Start()
{
Vector3 rot = transform.localRotation.eulerAngles;
rotX = rot.x;
rotY = rot.y;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X");
float mouseY = -Input.GetAxis("Mouse Y");
rotX += mouseY * sensitivity * Time.deltaTime;
rotY += mouseX * sensitivity * Time.deltaTime;
rotX = Mathf.Clamp(rotX, -clampAngle, clampAngle);
Quaternion localRotation = Quaternion.Euler(rotX, rotY, 0.0f);
transform.localRotation = localRotation;
}
}
I tried making a different movement code and I was expecting it to let me use wasd to move in a unity puzzle game.
The thing is
transform.Translate(new Vector3(horizontalInput, 0, verticalInput) * Time.deltaTime * speed);
uses local space and since your object is rotated and looking up it will start to move upwards as well.
You could eliminate that by using global space and erase any movement on Y by doing e.g.
var move = transform.rotation * new Vector3(horizontalInput, 0, verticalInput) * Time.deltaTime * speed;
move.y = 0f;
transform.position += move;
I made a simple movement system in Unity 3D, but I don't know how to make it so that I move in the direction my player is pointing in.
using UnityEngine;
public class PlayerControler : MonoBehaviour
{
CharacterController characterController;
public float MovementSpeed = 1f;
public float Gravity = 9.8f;
private float velocity = 0f;
void Start()
{
characterController = GetComponent<CharacterController>();
}
void Update()
{
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
characterController.Move((Vector3.right * horizontal + Vector3.forward * vertical) * Time.deltaTime);
if (characterController.isGrounded)
{
velocity = 0;
}
else
{
velocity -= Gravity * Time.deltaTime;
characterController.Move(new Vector3(0, velocity, 0));
}
}
}
This is the player controller.
using UnityEngine;
public class MouseControl : MonoBehaviour
{
public float horizontalSpeed = 1f;
public float verticalSpeed = 1f;
private float xRotation = 0.0f;
private float yRotation = 0.0f;
private Camera cam;
void Start()
{
cam = Camera.main;
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * horizontalSpeed;
float mouseY = Input.GetAxis("Mouse Y") * verticalSpeed;
yRotation += mouseX;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
cam.transform.eulerAngles = new Vector3(xRotation, yRotation, 0.0f);
}
}
This is the code that makes my character face where my cursor is.
Edit: This is a First-Person 3D game. The player has a CharacterControler component on it, and the Main Camera is a child of the player. The second piece of code changes the direction that the camera is facing when the cursor is moved. The first script is the movement script, and utilises the CharacterController component of the player to move. I want to make to that instead of going in four static directions every time I press a movement key, I want the player to move in proportion to the direction that the camera is facing (on the X axis). E.g: If I am facing West and I press “W” to go forwards, I want the character to go West instead of North.
Instead of the global vectors Vector3.forward and Vector3.right in
characterController.Move((Vector3.right * horizontal + Vector3.forward * vertical) * Time.deltaTime);
rather use your local direction vectors Transform.forward and Transform.right
characterController.Move((transform.right * horizontal + transform.forward * vertical) * Time.deltaTime);
#derHugo was right, but I forgot to update the angles in the player movement script, so it always thought that I was rotated 0,0,0.
using UnityEngine;
public class PlayerControler : MonoBehaviour
{
Vector3 angles;
CharacterController characterController;
MouseControl mouseControl;
public float MovementSpeed = 1f;
public float Gravity = 9.8f;
private float velocity = 0f;
void Start()
{
characterController = GetComponent<CharacterController>();
mouseControl = GetComponent<MouseControl>();
}
void Update()
{
angles = new Vector3(mouseControl.xRotation, mouseControl.yRotation, 0f);
transform.eulerAngles = angles;
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
characterController.Move((transform.right * horizontal + transform.forward * vertical) * Time.deltaTime);
if (characterController.isGrounded)
{
velocity = 0;
}
else
{
velocity -= Gravity * Time.deltaTime;
characterController.Move(new Vector3(0, velocity, 0));
}
}
}
Updated code
Note: I had to made the X and Y rotation variables public.
[HideInInspector]public float xRotation = 0.0f;
[HideInInspector]public float yRotation = 0.0f;
If I move forward while looking up my player jumps or at least attempts to fly. If I press Space bar and do move forward while looking up my player jumps even higher. I honestly have no idea on whats's going on. My prediction is the forward. If I look up Forward is relative to where I'm looking.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class P_MOVEMENT : MonoBehaviour
{
private float ACCELERATION = 10.0f;
private float GRAVITY = -5.0f;
private float SPEED = 5.0f;
private float RUNNING_SPEED = 2.0f;
private float JUMP_IMPULSE = 2.5f;
private bool isRunning = false;
CharacterController P_CC;
Vector3 P_MOVE;
//Camera Moving Mouse
private float X_AXIS = 0.0f;
private float Y_AXIS = 0.0f;
private float CAMERA_SPEED = 2.0f;
// Start is called before the first frame update
void Start()
{
P_CC = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
if(P_CC.isGrounded)
{
// Player Movement
P_MOVE = transform.forward * Input.GetAxis("Vertical") + transform.right * Input.GetAxis("Horizontal");
// Special Cases Check
// Running
isRunning = ( Input.GetKey(KeyCode.LeftShift) ) ? true : false;
P_MOVE = (isRunning) ? P_MOVE * SPEED * RUNNING_SPEED : P_MOVE * SPEED;
// Jumping
if(Input.GetAxis("Jump") > 0)
{
P_MOVE += Vector3.up * JUMP_IMPULSE;
}
}
else
{
P_MOVE += Vector3.up * GRAVITY * Time.deltaTime;
}
// Player Camera Movement
X_AXIS += CAMERA_SPEED * Input.GetAxis("Mouse X");
Y_AXIS -= CAMERA_SPEED * Input.GetAxis("Mouse Y");
// Restrict 90 Degree Up and Down
Y_AXIS = Mathf.Clamp(Y_AXIS, -60f, 90f);
// Update Rotation
transform.eulerAngles = new Vector3(Y_AXIS, X_AXIS, 0.0f);
}
void FixedUpdate()
{
P_CC.Move(P_MOVE * Time.deltaTime);
}
}
You are probably right. Your transform.forward is about the local GameObject coordinates instead of the global ones.
You could try to update only transform.forward.x and transform.forward.z. So you will ignore transform.forward.y. This way the player should not move up.
Something like this:
P_MOVE = transfrom.forward.x * Input.GetAxis("Vertical") + transform.forward.z * Input.GetAxis("Vertical") + transform.right * Input.GetAxis("Horizontal");
I made this script for my Player object. It has to child, 1 camera and 1 model.
They problem is whenever i move my mouse the player moves down. and the cam goes up.
Script:
public GameObject cam;
public float sensitivity = 2f;
public float walk_speed = 2f;
public float run_speed = 2f;
CharacterController player_CC;
float speed;
float moveFB;
float moveLR;
float rotX;
float rotY;
bool canMove;
void Start () {
canMove = true;
player_CC = GetComponent<CharacterController>();
speed = walk_speed;
}
void Update () {
if (canMove)
{
moveFB = Input.GetAxis("Vertical") * speed;
moveLR = Input.GetAxis("Horizontal") * speed;
rotX = Input.GetAxis("Mouse X") * sensitivity;
rotY = Input.GetAxis("Mouse Y") * sensitivity;
Vector3 movement = new Vector3(moveLR, 0, moveFB);
transform.Rotate(0, rotX, 0);
cam.transform.Rotate(rotY, 0, 0);
movement = transform.rotation * movement;
player_CC.Move(movement * Time.deltaTime);
}
if (Input.GetKey(KeyCode.LeftShift))
{
speed = run_speed;
} else
{
speed = walk_speed;
}
}
movement = transform.rotation * movement;
You're multiplying your transforms rotation by your movement vector. Separate the logic.
I know what caused it. But i dont know why it did it. But i used a charachtercontroller and a rigidbody on the same object. Sorry for wasting your time :/
Very new to mono develop and Unity 3d and seem to be having issues with this code. First off, the code IS working. It does what it's supposed to, however, it also does some funky stuff that it's not supposed to. You are able to look up, down, left and right as well as walk those directions, the bad part is though for some reason my character likes to nudge the direction of the mouse when standing still. What am I missing? More efficient/less buggy way of doing this?
public class PlayerControl : MonoBehaviour {
public float WALK_SPEED = 1.3f;
public float RUN_SPEED = 4.0f;
public float STRAFE_SPEED = 5.0f;
public float ROTATION_SPEED = 300.0f;
public float JUMP_FORCE = 250.0f;
void Start()
{
}
// Update is called once per frame
void Update ()
{
float movementSpeed = WALK_SPEED;
float strafeSpeed = STRAFE_SPEED;
float rotationSpeedx = ROTATION_SPEED;
float rotationSpeedy = ROTATION_SPEED;
if (Input.GetKey(KeyCode.LeftShift))
{
movementSpeed = RUN_SPEED;
}
movementSpeed = Input.GetAxis("Vertical") * movementSpeed * Time.deltaTime;
strafeSpeed = Input.GetAxis("Horizontal") * strafeSpeed * Time.deltaTime;
rotationSpeedx = Input.GetAxis("Mouse X") * rotationSpeedx * Time.deltaTime;
rotationSpeedy = Input.GetAxis("Mouse Y") * rotationSpeedy * Time.deltaTime;
Vector3 rotate = new Vector3 (-rotationSpeedy, rotationSpeedx, 0);
transform.Translate(Vector3.forward * movementSpeed);
transform.Translate(Vector3.right * strafeSpeed);
transform.Rotate(rotate);
if (Input.GetKeyDown(KeyCode.Space) &&
transform.position.y < 30)
{
rigidbody.AddForce(Vector3.up * JUMP_FORCE);
}
}
}
Try freezing rotation constraints on rigidbody component. This may stop the nudging.