The player will not move where the camera is facing - c#

when I hold down the 'w' and move the camera the player will not move in the camera direction e.g if I go forward and move the camera to the left it would not go to the left but keep going forward, What are some possible ways to fix this. Player Movement Script
public float movementspeed = 5.0F;
// Use this for initialization
void Start () {
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void Update () {
float translation = Input.GetAxis("Vertical") * movementspeed;
float straffe = Input.GetAxis("Horizontal") * movementspeed;
translation *= Time.deltaTime;
straffe *= Time.deltaTime;
transform.Translate(straffe, 0, translation);
}
}
and Camera View Script
public float xMoveThreshold = 1000.0f;
public float yMoveThreshold = 1000.0f;
public float yMaxLimit = 50.0f;
public float yMinLimit = -50.0f;
float yRotCounter = 0.0f;
float xRotCounter = 0.0f;
Transform player;
void Start()
{
player = Camera.main.transform;
}
// Update is called once per frame
void Update()
{
xRotCounter += Input.GetAxis("Mouse X") * xMoveThreshold * Time.deltaTime;
yRotCounter += Input.GetAxis("Mouse Y") * yMoveThreshold * Time.deltaTime;
yRotCounter = Mathf.Clamp(yRotCounter, yMinLimit, yMaxLimit);
//xRotCounter = xRotCounter % 360;//Optional
player.localEulerAngles = new Vector3(-yRotCounter, xRotCounter, 0);
}
}

You need to use de camera transform to be able to do this. Something like:
public float movementspeed = 5.0F;
public Transform cameraTransform;
// Use this for initialization
void Start () {
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void Update () {
float translation = Input.GetAxis("Vertical") * movementspeed;
float straffe = Input.GetAxis("Horizontal") * movementspeed;
translation *= Time.deltaTime;
straffe *= Time.deltaTime;
Vector3 movement = cameraTransform.Forward * translation + cameraTransform.Right * straffe;
transform.position = transform.position+ movement;
}

Related

When look up my character moves forwards in unity

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;

How to jump properly using character controller?

I'm using a character controller for my player movement. I had walking and running working, but I couldn't get the jumping to work.
Here is my code:
[SerializeField] Transform playerCamera = null;
[SerializeField] float mouseSensitivity = 3.5f;
[SerializeField] float walkSpeed = 10.0f;
[SerializeField] float RunSpeed = 12.0f;
[SerializeField] float gravity = 9.81f;
[SerializeField] bool lockCursor = true;
[SerializeField] [Range(0.0f, 0.5f)] float moveSmoothTime = 0.3f;
[SerializeField] [Range(0.0f, 0.5f)] float mouseSmoothTime = 0.03f;
public float jumpHeight = 3f;
Vector3 velocity;
public float verticalVelocity;
float cameraPitch = 0.0f;
float VelocityY = 0.0f;
CharacterController controller = null;
Vector2 currentDir = Vector2.zero;
Vector2 currentDirVelocity = Vector2.zero;
Vector2 currentMouseDelta = Vector2.zero;
Vector2 currentMouseDeltaVelocity = Vector2.zero;
void Start()
{
controller = GetComponent<CharacterController>();
if (lockCursor)
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
}
void Update()
{
UpdateMouseLook();
UpdateMovement();
}
void UpdateMouseLook()
{
Vector2 targetMouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
currentMouseDelta = Vector2.SmoothDamp(currentMouseDelta, targetMouseDelta, ref currentMouseDeltaVelocity, mouseSmoothTime);
cameraPitch -= currentMouseDelta.y * mouseSensitivity;
cameraPitch = Mathf.Clamp(cameraPitch, -90.0f, 90.0f);
playerCamera.localEulerAngles = Vector3.right * cameraPitch;
transform.Rotate(Vector3.up * currentMouseDelta.x * mouseSensitivity);
}
void UpdateMovement()
{
Vector2 targetDir = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
targetDir.Normalize();
currentDir = Vector2.SmoothDamp(currentDir, targetDir, ref currentDirVelocity, moveSmoothTime);
if (controller.isGrounded)
VelocityY = 0.0f;
VelocityY += gravity * Time.deltaTime;
velocity = (transform.forward * currentDir.y + transform.right * currentDir.x) * walkSpeed + Vector3.up * VelocityY;
controller.Move(velocity * Time.deltaTime);
if ((Input.GetKey("left shift") || Input.GetKey("right shift")) && controller.isGrounded && !Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.DownArrow))
{
velocity = (transform.forward * currentDir.y + transform.right * currentDir.x) * RunSpeed + Vector3.up * VelocityY;
controller.Move(velocity * Time.deltaTime);
}
if (Input.GetKeyDown(KeyCode.J) && controller.isGrounded)
{
Debug.Log("Now Jumping!!");
VelocityY = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
}
Note: I'm not using rigidbody on my character.
The jumping is not working every time, on some clicks, it jumps and on most of the clicks nothing happens even Debug.Log("Now Jumping!!"); is not getting printed every time I hit J. How can I fix this?
I solved this problem. You have no choice but to add physics to the character controller. This is a simple code that has the same feature, but you should coordinate the movement and jump.
public class Player : MonoBehaviour
{
private Vector3 playerVelocity;
private CharacterController _controller;
public float jumpPower = 1f; // 1 is ok for -9.8 gravity
void Start()
{
_controller = GetComponent<CharacterController>();
}
void Update()
{
playerVelocity += Physics.gravity * Time.deltaTime;
_controller.Move(playerVelocity);
if (_controller.isGrounded)
{
playerVelocity.y = Input.GetKeyDown(KeyCode.Space) ? jumpPower : 0;
}
}
}

Unity 3d movement not working with Camera direction

I have two scripts one is the MouseHandler and the other is the SimpleMovement. rotating the camera works and moving works however when the camera turns the movement doesn't go in that direction. E.G i turn the camera 90 degrees to the right but the forward doesn't change. The forward doesn't go to where the camera is facing. Sorry if i'm just being stupid. Any help would be appreciated
MouseHandler script:
public class MouseHandler : MonoBehaviour
{
// horizontal rotation speed
public float horizontalSpeed = 1f;
// vertical rotation speed
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, -90, 90);
cam.transform.eulerAngles = new Vector3(xRotation, yRotation, 0.0f);
}
}
SimpleMovement Script:
public class SimpleMovement : MonoBehaviour
{
CharacterController characterController;
public float MovementSpeed = 1;
public float Gravity = 9.8f;
private float velocity = 0;
private void Start()
{
characterController = GetComponent<CharacterController>();
}
void Update()
{
// player movement - forward, backward, left, right
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
characterController.Move((Vector3.right * horizontal + Vector3.forward * vertical) * Time.deltaTime);
// Gravity
if (characterController.isGrounded)
{
velocity = 0;
}
else
{
velocity -= Gravity * Time.deltaTime;
characterController.Move(new Vector3(0, velocity, 0));
}
}
}
First, get a reference to the main cmaera and cache it, because you're going to be referencing it frequently, and simply using Camera.main is a bit expensive:
private Camera mainCam;
...
private void Start()
{
characterController = GetComponent<CharacterController>();
mainCam = Camera.main;
}
Then, use mainCam.transform.right and mainCam.transform.forward but with the y set to 0 and normalized instead of Vector3.right and Vector3.forward. This will make the movement be based on the rotation of the camera:
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
Vector3 camRightFlat = new Vector3(mainCam.transform.right.x, 0f,
mainCam.transform.right.z).normalized;
Vector3 camForwardFlat = new Vector3(mainCam.transform.forward.x, 0f,
mainCam.transform.forward.z).normalized;
characterController.Move(
(camRightFlat * horizontal + camForwardFlat * vertical) * Time.deltaTime);
Altogether:
public class SimpleMovement : MonoBehaviour
{
CharacterController characterController;
public float MovementSpeed = 1;
public float Gravity = 9.8f;
private float velocity = 0;
private Camera mainCam;
private void Start()
{
characterController = GetComponent<CharacterController>();
mainCam = Camera.main;
}
void Update()
{
// player movement - forward, backward, left, right
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
Vector3 camRightFlat = new Vector3(mainCam.transform.right.x, 0f,
mainCam.transform.right.z).normalized;
Vector3 camForwardFlat = new Vector3(mainCam.transform.forward.x, 0f,
mainCam.transform.forward.z).normalized;
characterController.Move((camRightFlat * horizontal + camForwardFlat * vertical)
* Time.deltaTime);
// Gravity
if (characterController.isGrounded)
{
velocity = 0;
}
else
{
velocity -= Gravity * Time.deltaTime;
characterController.Move(new Vector3(0, velocity, 0));
}
}
}

Stop my first person character controller going through the wall in Unity using C#?

As seen in the video here: https://i.gyazo.com/ad45ef9e231fd2f9ec6d4cf76889aece.mp4
My code:
MouseLook.cs:
using UnityEngine;
using System.Collections;
public class MouseLook : MonoBehaviour
{
public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityX = 3F;
public float sensitivityY = 3F;
public Camera playerCamera;
public float minimumX = -360F;
public float maximumX = 360F;
public float minimumY = -60F;
public float maximumY = 60F;
private float rotationX = 0F;
private float rotationY = 0F;
private Quaternion originalRotation;
void Update()
{
if (axes == RotationAxes.MouseXAndY)
{
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationX = ClampAngle(rotationX, minimumX, maximumX);
rotationY = ClampAngle(rotationY, minimumY, maximumY);
Quaternion xQuaternion = Quaternion.AngleAxis(rotationX, Vector3.up);
Quaternion yQuaternion = Quaternion.AngleAxis(rotationY, -Vector3.right);
transform.localRotation = originalRotation * xQuaternion * yQuaternion;
}
if (axes == RotationAxes.MouseX)
{
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
rotationX = ClampAngle(rotationX, minimumX, maximumX);
Quaternion xQuaternion = Quaternion.AngleAxis(rotationX, Vector3.up);
transform.localRotation = originalRotation * xQuaternion;
}
if (axes == RotationAxes.MouseY || playerCamera != null)
{
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationY = ClampAngle(rotationY, minimumY, maximumY);
Quaternion yQuaternion = Quaternion.AngleAxis(-rotationY, Vector3.right);
if (playerCamera != null)
{
playerCamera.transform.localRotation = originalRotation * yQuaternion;
}
else
{
transform.localRotation = originalRotation * yQuaternion;
}
}
}
void Start()
{
/*
if (gameObject.GetComponent<Rigidbody>())
{
gameObject.GetComponent<Rigidbody>().freezeRotation = true;
}
*/
originalRotation = transform.localRotation;
}
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360F)
{
angle += 360F;
}
if (angle > 360F)
{
angle -= 360F;
}
return Mathf.Clamp(angle, min, max);
}
}
FirstPersonController.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using Cursor = UnityEngine.Cursor;
public class FirstPersonController : MonoBehaviour
{
private float speed = 5;
private float jumpPower = 4;
Rigidbody rb;
CapsuleCollider col;
public GameObject crossHair;
bool isActive;
float HorizontalInput;
float VerticalInput;
void Start()
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
rb = GetComponent<Rigidbody>();
col = GetComponent<CapsuleCollider>();
crossHair = GameObject.FindWithTag("CrossHair");
}
void Update()
{
HorizontalInput = Input.GetAxisRaw("Horizontal");
VerticalInput = Input.GetAxisRaw("Vertical");
if (Input.GetKeyDown("escape"))
{
Cursor.lockState = CursorLockMode.None;
}
if (Input.GetButtonDown("Sprint"))
{
speed = 15;
}
if (Input.GetButtonUp("Sprint"))
{
speed = 5;
}
if (Input.GetKeyDown(KeyCode.H))
{
isActive = !isActive;
}
if (isActive)
{
crossHair.SetActive(true);
}
else
{
crossHair.SetActive(false);
}
}
void FixedUpdate()
{
Vector3 xMovement = transform.right * speed * HorizontalInput * Time.deltaTime;
Vector3 zMovement = transform.forward * speed * VerticalInput * Time.deltaTime;
rb.velocity = new Vector3(HorizontalInput, 0, VerticalInput) * speed;
if (isGrounded() && Input.GetButtonDown("Jump"))
{
rb.AddForce(Vector3.up * jumpPower, ForceMode.Impulse);
}
}
private bool isGrounded()
{
return Physics.Raycast(transform.position, Vector3.down, col.bounds.extents.y + 0.1f);
}
}
Is there anything wrong I am doing in this code, if so how do I fix it?
Entire project can be downloaded here: https://github.com/Some-T/FirstPersonController-CSharp
Project has relevant colliders and rigidbodies set up!
Someone has advised me to use shapecast, but I believe that may incorrect? I can't see how that would work as my player does not have character controller component added to it?
Overall how do I stop my first person character controller going through the wall like in the initial video specified above?
Upon further research I have discovered the following:
The answer is to use:
https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html as a quick fix.
But definitively for flawlessness use:
https://docs.unity3d.com/ScriptReference/Rigidbody-velocity.html
As to how in C# I am not so sure, but here is a screen shot I did in bolt asset.
Currently I have movmement working with velocity but it does not work properly, not sure as to why? So overall my question now is how do I get movement working using velocity? I added a line in FirstPersonController.cs that moves the character using velocity of rb.velocity = new Vector3(HorizontalInput, 0, VerticalInput) * speed; so my only question and issue now is my player does not move in the direction the camera on my player is facing so I am not sure how to fix this specific thing overall?
In your project code is different from one that you provided here.
Try to enable rigidbody`s rotation constraint - freeze X and Z rotation, leave only Y. When you rotate your capsule collider (as it works in your project), it can "climb" on a wall.
Do the isGrounded check when you move, and lock movement, if not grounded.
Try to increase Collider.contactOffset
If above does not helps, try to use Rigidbody.velocity instead of Rigidbody.MovePosition.
You can also reduce Rigidbody.drag
In general, pretty good technique is to use NavMesh for movement - in this way, you able to explicitly lock player from movement outside of navmesh surface. But, of course, it doesn`t fit to many gameplays.
Hope, it helps.
upd
You move your player like this:
void FixedUpdate()
{
Vector3 xMovement = transform.right * speed * HorizontalInput * Time.deltaTime;
Vector3 zMovement = transform.forward * speed * VerticalInput * Time.deltaTime;
}
Note, that you not even apply it to rigidbody;
But you get your input this way:
float HorizontalInput = Input.GetAxis("Horizontal");
float VerticalInput = Input.GetAxis("Vertical");
in Update, so input just stays inside Update, and does not applied at all. You declared your variables twice, once on class top, another in Update().

Unity 5 fpscontroller weird error

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 :/

Categories