The rotation speed of my character is different while testing in the editor and in Built version of the game. By a pretty significant amount. This is the script in question.
using UnityEngine;
public class PlayerCam : MonoBehaviour
{
public float SensX;
public float SensY;
public Transform orientation;
float xRotation;
float yRotation;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
void Update()
{
float mouseX = Input.GetAxisRaw("Mouse X") * Time.deltaTime * SensX;
float mouseY = Input.GetAxisRaw("Mouse Y") * Time.deltaTime * SensY;
yRotation += mouseX;
xRotation -= mouseY;
orientation.rotation = Quaternion.Euler(0, yRotation, 0);
transform.rotation = Quaternion.Euler(xRotation, yRotation, 0);
}
}
If I stop multiplying it by Time.deltaTime it seems to work fine but then I cannot stop the rotation from happening when I want to pause the game in menu's using Time.timeScale = 0
If I change it from Update() to FixedUpdate() the rotation is extreemly jittery and doesn't work at all
Sorry for what is probably a dumb mistake but I don't understand what I am doing wrong.
Related
This script in Unity allows me to move my player forward, left and right but not backwards. This script also allows me to turn the player and move in the direction of the camera.
However, When pressing the back arrow the player spins and moves randomly.
I tried removing the "if" statement, didn't help.
Totally stuck, please help.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovment : MonoBehaviour
{
public Transform cam;
public float speed = 6f;
public CharacterController controller;
public float turnSmoothTime = 0.1f;
float turnSmoothVelocity;
void FixedUpdate()
{
float horizontalInput = Input.GetAxisRaw("Horizontal");
float verticalInput = Input.GetAxisRaw("Vertical");
Vector3 movementDirection = new Vector3(horizontalInput, 0f, verticalInput).normalized;
if (movementDirection.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(movementDirection.x, movementDirection.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f,angle, 0f);
Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
controller.Move(moveDir.normalized * speed * Time.deltaTime);
}
}
}
So I'm currently learning Unity 3D but I stuck on a problem.
So Iv'e done this code that the player moves with WASD keys. The movement works fine.
I tried to aply some rotation, that way the player can turn back or move to different positions.
But the problem is, I put the rotarion and the player turns but when he does he swap W for S, so basically if I turn back, when I press W to go forward he go backward and when I press S instead of going Backward he goes Forward.
I don't to make a lot of changes in my code because I think it's very "basic" right now and easy to understand. So if someone can explain what I'm doing wrong I would appreciate.
using System.Collections.Generic;
using UnityEngine;
//[RequireComponent(typeof(Rigidbody))]
public class PlayerMov : MonoBehaviour
{
//Player mov speed
float MovSpeed = 10f;
//Player jump, jumpforce, check if is on the ground and rb(rigidbody component)
public Vector3 jump;
public float jumpForce = 2.0f;
public bool isGrounded;
Rigidbody rb;
public float TurnSpeed = 100f;
void Start()
{
rb = GetComponent<Rigidbody>();
jump = new Vector3(0.0f, 2.0f, 0.0f);
}
void OnCollisionStay()
{
isGrounded = true;
}
void Update()
{
if (Input.GetKey(KeyCode.W))
{
transform.position -= Vector3.forward * MovSpeed * Time.deltaTime;
//transform.Translate(Vector3.forward * MovSpeed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.A))
{
transform.position -= Vector3.left * MovSpeed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.S))
{
transform.position -= Vector3.back * MovSpeed * Time.deltaTime;
//transform.Translate(-Vector3.forward * MovSpeed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.D))
{
transform.position -= Vector3.right * MovSpeed * Time.deltaTime;
transform.Rotate(Vector3.up * TurnSpeed * Time.deltaTime);
}
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
rb.AddForce(jump * jumpForce, ForceMode.Impulse);
isGrounded = false;
}
if (Input.GetKey(KeyCode.LeftArrow))
{
transform.Rotate(Vector3.up * TurnSpeed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.RightArrow))
{
transform.Rotate(Vector3.up * TurnSpeed * Time.deltaTime);
}
Why not use the Translate method? Please see its documentation. You can define a which space you want the transform to move in (global or local)
https://docs.unity3d.com/ScriptReference/Transform.Translate.html
As a side note: why check for each separate key? Using Input.GetAxis("Horizontal") and Input.GetAxis("Horizontal") vertical would be simpler.
(Parameter values are not being sent from script to blend tree resulting in not following animation with movement.) I have animations set up in a blend tree that has a 1d type blend tree. I have it set to custom thresholds with an idle animation as the base state then the blend tree has three motions: a strafe left, right, and a walk forward. When I move forward the player does not do the animations told in the tree and I am almost certain it is the script.
I am also using Unity 1212.1.2f1 and for my scripts I have been using Microsoft Visual Studio if it matters.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
public float speed = 12f;
public float gravity = -9.81f;
public float jumpHeight = 3f;
public float rotationSpeed = 75.0f;
public Animator anim;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
Vector3 velocity;
bool isGrounded;
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
float translation = Input.GetAxis("Vertical") * speed;
float rotation = Input.GetAxis("Horizontal") * rotationSpeed;
translation *= Time.deltaTime;
rotation *= Time.deltaTime;
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
if ((Input.GetButtonDown("Jump")) && isGrounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
{
anim.SetFloat("Vertical", Input.GetAxis("Vertical"));
anim.SetFloat("Horizontal", Input.GetAxis("Horizontal"));
}
}
}
first i think you could try to make a new var :
private Rigidbody2D rg;
then add this in Start ()
rg = Player.GetComponent<Rigidbody2D>();
and Update () with this
anim.SetFloat("Vertical", rg.velocity.x);
anim.SetFloat("Horizontal", rgvelocity.x);
and sure made 2 Vertical and Horizontal in Animator parameters
I am having trouble with aligning my player controlled camera (I use the same class for FPS and TPS) to look at a target (when ResetCamera() is called by another script) and then getting the player to resume control. The main reason I am doing this is so I can switch between FPS and TPS cameras and remain looking at the same target.
I can look at the target fine, but ONLY if I stop setting the rotation based on yaw and pitch (from "Mouse X" and "Mouse Y" inputs) in LateUpdate() after I set the lookAtTarget in ResetCamera(), but that means the player can no longer look around.
However, I cannot figure out how to get the correct yaw and pitch values after this so the player can continue looking around from the new look at target. How could I do this so the player could continue looking around?
public class PlayerCamera : MonoBehaviour {
public float mouseSensitivity = 10f;
public Transform target;
public float dstFromTarget = 2f;
public Vector2 pitchConstraints = new Vector2(-20f, 85f);
public float rotSmoothTime = .12f;
Vector3 rotSmoothVel;
Vector3 currRot;
float yaw;
float pitch;
void LateUpdate() {
yaw += Input.GetAxis("Mouse X") * mouseSensitivity;
pitch -= Input.GetAxis("Mouse Y") * mouseSensitivity;
pitch = Mathf.Clamp(pitch, pitchConstraints.x, pitchConstraints.y);
currRot = Vector3.SmoothDamp(currRot, new Vector3(pitch, yaw), ref rotSmoothVel, rotSmoothTime);
transform.eulerAngles = currRot;
transform.position = target.position - transform.forward * dstFromTarget;
}
public void ResetCamera(Transform lookAtTarget) {
transform.LookAt(lookAtTarget);
// below gets yaw and pitch values that move the camera to look at the
// wrong location
// yaw = transform.eulerAngles.x;
// pitch = transform.eulerAngles.y;
// pitch = Mathf.Clamp(pitch, pitchConstraints.x, pitchConstraints.y);
// currRot = new Vector3(pitch, yaw);
}
}
So, I figured out how to do what I wanted. Below is a script for a third or first person (just adjust the dstFromTarget variable to zero) camera that can be rotated to look at a target by another script with ResetCamera() and the player can resume moving around from that point.
public class PlayerCamera : MonoBehaviour {
public bool isFirstPerson = false;
public float mouseSensitivity = 10f;
public Transform target;
public float dstFromTarget = 2f;
public bool invertedPitch = false;
public float smoothTime = .12f;
public float minimumX = -85f;
public float maximumX = 85f;
// LateUpdate, so the Camera Target will definitely have been set
void LateUpdate () {
// first person updating is handled by Inverse kinematics stuff in my case
if (isFirstPerson) return;
UpdateStuff();
}
public void UpdateStuff() {
float yaw = Input.GetAxisRaw("Mouse X");
float pitch = -Input.GetAxisRaw("Mouse Y");
if (invertedPitch) {
pitch *= -1f;
}
Vector3 yRot = new Vector3(0f, yaw, 0f) * mouseSensitivity;
Vector3 xRot = new Vector3(pitch, 0f, 0f) * mouseSensitivity;
xRot = ClampRotationAroundXAxis(transform.rotation, xRot);
Transform newTrans = transform;
newTrans.Rotate(xRot);
newTrans.Rotate(yRot, Space.World);
transform.rotation = Quaternion.Slerp(transform.rotation, newTrans.rotation, smoothTime * Time.deltaTime);
transform.position = target.position - transform.forward * dstFromTarget;
}
public void ResetCamera(Transform lookAtTarget) {
transform.LookAt(lookAtTarget);
}
Vector3 ClampRotationAroundXAxis(Quaternion q, Vector3 xrot) {
q.x /= q.w;
q.y /= q.w;
q.z /= q.w;
q.w = 1.0f;
float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan (q.x);
if (angleX < minimumX && xrot.x < 0f) {
xrot = Vector3.zero;
}
if (angleX > maximumX && xrot.x > 0f) {
xrot = Vector3.zero;
}
return xrot;
}
}
In Unity I want to make it so that when I hold w, instead of going in a single direction I want it to go forward in the direction of my camera how do I do that? (Sorry I'm new to unity)
EDIT: The movement script is:
using UnityEngine;
using System.Collections;
public class Player_Movement : MonoBehaviour {
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
void Update() {
CharacterController controller = GetComponent<CharacterController>();
if (controller.isGrounded) {
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton("Jump"))
moveDirection.y = jumpSpeed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}
}
As indicated by #lockstock, the direction the camera is facing can be retrieved from its transform. Here is an example below if you want to know how to use it.
public class Player_Movement : MonoBehaviour
{
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
// Drag & Drop the camera in this field, in the inspector
public Transform cameraTransform ;
private Vector3 moveDirection = Vector3.zero;
void Update() {
CharacterController controller = GetComponent<CharacterController>();
if (controller.isGrounded) {
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = cameraTransform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton("Jump"))
moveDirection.y = jumpSpeed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}
}
This scripts works without any error. I've tested it in Unity myself.
The forward direction of the camera is obtained by using Camera.main.transform.forward
turn your player so the blue axis is facing the same direction as the blue axis on the camera. then drag and drop the camera onto the player. now when you move the player, the camera will follow, and stay behind the player