While I'm learning unity and C#, I made a first person controller using the new unity input system.
I scripted a first person camera, when I go in playmode in the editor, sometimes the camera works well, but sometimes it will stutter very hard when I move the mouse (the problem don't seem to appear with a controller), and I have no idea why it happens.
In the "built" version, the mouse sensitivity is very, very high and the controller sensitivity is very low (same in editor), but there is no stuttering at all.
So, do you have any ideas to fix it ?
Here is the piece of code (called in a LateUpdate loop)
private void MoveCamera()
{
Vector2 MouseAxis = m_inputManager.GetMouseDelta();
float MouseX = MouseAxis.x * CameraSensitivity * Time.deltaTime;
float MouseY = MouseAxis.y * CameraSensitivity * Time.deltaTime;
xRot -= MouseY;
xRot = Mathf.Clamp(xRot, MinClamp, MaxClamp);
m_camHolder.transform.localRotation = Quaternion.Euler(xRot, 0f, 0f);
transform.Rotate(Vector3.up * MouseX);
}
Related
Im trying to code so that my Character dashes to the right when pressing the Left mouse button, but instead of dashing it just starts slowly glieding or lets say floating.
This is the code i´ve used;
if (Input.GetMouseButton(0))
{
rb.velocity = Vector2.right * DashSpeed;
}
Im not sure but a other part of my code might be the reason for this problem but if so i would like to know how i could solve it. Thats the part im talking about
rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);
thats the code im using for movement.
void Start()
{
cam = Camera.main;
rb = GetComponent<Rigidbody2D>();
}
private void Update()
{
horizontal = Input.GetAxisRaw("Horizontal");
animator.SetFloat("Horizontal", Input.GetAxis("Horizontal"));
if (Input.GetKeyDown(KeyCode.Space) && isGrounded == true)
{
float jumpVelocity = 7f;
rb.velocity = Vector2.up * jumpVelocity;
jumpsound.Play();
}
Vector3 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
if (Input.GetKey(KeyCode.RightAlt))
{
Dashing();
}
}
void FixedUpdate()
{
isGrounded = Physics2D.OverlapCircle(groundCheck.position, CheckRadius, whatisGround);
moveInput = Input.GetAxisRaw("Horizontal");
rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);
if (Input.GetKeyDown(KeyCode.Escape))
{
SceneManager.LoadScene("Main menu");
}
}
void Dashing()
{
rb.AddForce(Vector2.right * DashSpeed, ForceMode2D.Impulse);
}
The issue with your current code is you are directly changing velocity in a few places. Some basic physics, the integral of position vs. time graph is velocity, and the integral of velocity is acceleration vs. time. To get a more realistic movement, it is better to apply a Force to objects. When doing this, the physics engine Unity uses can add a new force at a given time, then using acceleration can accelerate the object in that direction over time, then can change the velocity over time which will result in the position changing over time.
The example code you posted, you are directly setting velocity in a few places.
rb.velocity = Vector2.up * jumpVelocity; (Jump)
rb.velocity = new Vector2(moveInput * speed, rb.velocity.y); (Movement)
rb.velocity = Vector2.right * DashSpeed; (Dash)
When directly setting these values, the new values overwrite the old ones. As your movement code is not in any sort of if conditional it will continually write to the velocity causing the dash to never change anything regardless if you use add-force or change velocity directly.
I would consider making both your jump and dash use AddForce, and if you like the feel of your movement by applying velocity directly, then add the velocity do not set it.
Your previous line rb.velocity = new Vector2(moveInput * speed, rb.velocity.y); would then become rb.AddForce(new Vector2(moveInput * speed, 0), ForceMode2D.Impulse);. Similarly you can update your jump and dash to match this. Let me know if you get this working or have more questions.
It could be a problem with your animation. Link to a thread on unity answers:
https://answers.unity.com/questions/674516/rigidbody-character-problems-constant-floating-jum.html
You should go over to the animation place and hit bake into pose.
You should use the Rigidbody2D.AddForce(Vector2, ForceMode2D). What this does is moving the GameObject in the direction of the Vector2, with the force mode of ForceMode2D. What is different about this from just translating it, is that it interacts with physics and improves the quality of your game. Here is a link, and the script:
https://docs.unity3d.com/ScriptReference/Rigidbody2D.AddForce.html
Rigidbody2D rb;
float dashSpeed;
void Update()
{
if (Input.GetMouseButton(0))
{
rb.AddForce(Vector2.right * dashSpeed);
}
}
And if the other part of the code you were talking about, if that is glitching, then do the same trick.
The Unity 3D movement has this built in feature where it glides when you stop while holding the key. How do I remove this glide?
Fair warning, I haven't tried anything yet. I am very new to Unity and assume its most likely just some button I need to click so please help.
Here's the code that I'm using:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movement : MonoBehaviour
{
float moveSpeed;
float walkSpeed = 3;
float sprintSpeed = 6;
public CharacterController controller;
public float gravity = -9.81f;
public Transform groundCheck;
public float groundDistance = 8.4f;
public LayerMask groundMask;
Vector3 velocity;
bool isGrounded;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.LeftShift))
{
moveSpeed = sprintSpeed;
}
else
{
moveSpeed = walkSpeed;
}
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * moveSpeed * Time.deltaTime);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
}
I'm more than happy to answer your question but I can't leave out this tidbit. I can't stress this enough. If you are new to Unity, you should avoid posting questions like this as much as possible. I'm not discouraging you from asking questions, but since you're new, really give it a go before you post anything. You'll learn soooo much more by removing variables and lines of code to figure out a solution on your own instead of getting the answer right away.
Regardless I believe the answer is in the last two lines of your code:
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
Let's think about this line by line. Dissect each line and try to really understand what they mean. As you run through your code, you are receiving three main inputs from the user:
if (Input.GetKey(KeyCode.LeftShift))
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
if (Input.GetKey(KeyCode.LeftShift)) is just a check to see if your user wants to run or not. The other two are receiving what is likely mouse movement input. These are primarily used to define the users movement. We know this because they are directly tied to these next two lines:
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * moveSpeed * Time.deltaTime);
Now when you look closer at this, it tells us that if the user isn't moving the mouse, then the Vector3 move will be 0. That means that our player will stop moving and there should be no reason they glide. However, take a look at the next two.
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
These are not necessarily driven by user input. This means that considering they are tied to your controller and the other move calls aren't running without user input, these two lines must be the culprits for your glide problem.
So remove these and you should be good. However, I must make it clear, asking questions is good, but breaking the code to learn more about it is soo much better. As a challenge I think you should look into what drives velocity.y... or maybe isGrounded... and that will tell you more about why the glide is happening!
Hope this helps!
Check the "Gravity" field on your "Horizontal" and "Vertical" axes in the input manager (Edit > Project Settings, then select the Input category). If not 0, it will smooth out keyboard inputs.
I use rigidbody.MovePosition to move around my character , and have a camera following it. The problem is when i switch directions suddenly the player will teleport a bit instead of smoothly moving in the opposite direction of motion. The scripts for the player and Camera are set to FixedUpdate , if I try moving camera to a LateUpdate then the whole thing jitters a lot.
Player Script :
private void Start()
{
m_Rb = GetComponent<Rigidbody>();
m_InputAxisName = "Vertical" + m_playerNumber;
m_StrafeAxisName = "Horizontal" + m_playerNumber;
}
private void FixedUpdate()
{
m_InputAxisValue = Input.GetAxis(m_InputAxisName);
m_StrafeAxisValue = Input.GetAxis(m_StrafeAxisName);
//Movement
Vector3 movement = (transform.forward * m_InputAxisValue * m_Speed * Time.deltaTime) + (transform.right * m_StrafeAxisValue * m_Speed * Time.deltaTime);
m_Rb.MovePosition(m_Rb.position + movement);
}
Camera Script
void FixedUpdate () {
m_NewPos = m_player.transform.position + m_offset;
if (m_Rotate)
{
Quaternion newRot = Quaternion.AngleAxis(Input.GetAxis("Mouse X") * m_rotSpeed, Vector3.up);
m_offset = newRot * m_offset;
}
transform.position = Vector3.SmoothDamp(transform.position, m_NewPos, ref m_MoveSpeed, m_DampTime); ;
if (m_Rotate)
transform.LookAt(m_player);
}
the problem is that your motion logic is implemented within FixedUpdate but you take the time.deltaTime. You have to use the fixedDeltaTime version.
Also do not try to get the Input within the FixedUpdate that can also cause jitter and stutter/jumping of objects.
Instead get the Input from Update and use variables to pass it inside the FixedUpdate.
A last one, look at your RigidBody for the Interpolation/Extrapolation depending on your Scene Setup and Camera this could also help.
I finally figured out what was wrong with it, something about the rotation of the camera in the fixed update. I moved it to update and it works fine now
I have UI button that rotate an object in the scene when pressed with the MouseDown and stopes rotating when MouseUp.
I am rotating the object using the following code:
private float rotationSpeed = 205f;
public void dragBrain(GameObject brain) {
float rotateX = Input.GetAxis("Mouse X") * rotationSpeed * Mathf.Deg2Rad;
float rotateY = Input.GetAxis("Mouse Y") * rotationSpeed * Mathf.Deg2Rad;
theObjectToRotate.transform.Rotate(Vector3.up, -rotateX);
theObjectToRotate.transform.Rotate(Vector3.right, -rotateY);
}
When I test the application with unity, it works fine (without VR), but when I build the project and test it on an Android device, the object doesn't rotate when I click the button.
Is it because I am trying to get the axis of the mouse? and its different with the VR?
And how should I go about doing it? because I tried to look for the documentations but with no luck.
I am working on a first person game where the character is able to latch on to any flat surface and walk on it (kind of like moon boots). I am having issues with the camera since most implementations of mouse look I have been able to find depend on the player being oriented straight up and down in the world, so as soon as my "flipping" animation (the player orienting to the new surface) has finished, the camera will instantly flip back to straight up and down as defined by the world. What I need is a way to implement mouse look so that it does not reset the rotation after my animation. I am currently using:
transform.Rotate(-Input.getAxis("Mouse Y") turnSpeed Time.deltaTime, Input.getAxis("Mouse X") turnSpeed Time.deltaTime, 0);
in order to perform my mouse look rotations while avoiding the standard method, but this is clearly incorrect since I get some weird rotations when turning the camera horizontally. Is there a better way to implement mouse look so that it works correctly regardless of the orientation of the player?
You can plance camera inside player Transform and add this script to player:
public class MouseLook : MonoBehaviour {
[SerializeField]
Camera Camera;
[Range(10f,50f)]
public float Speed = 30;
void Update () {
transform.rotation = Quaternion.AngleAxis(Input.GetAxis("Mouse X") * speed * Time.deltaTime, transform.rotation * Vector3.up)*transform.rotation;
Camera.transform.rotation = Quaternion.AngleAxis(-Input.GetAxis("Mouse Y") * Speed * Time.deltaTime, Camera.transform.rotation * Vector3.right)* Camera.transform.rotation;
}
}
You add reference to Camera in inspector. You will have to check not to rotate above +/- 90 degrees on camera to avoid over rotating to back. If you will have issue with that I will help you.