I have tried to make a Player Controller where you control it via WSAD or the arrow keys and it worked fine, but when I tried to add the part that registers the mouse movements on the X Y axes it went wrong...
Input.GetAxis ("Mouse X") worked fine but Input.GetAxis ("Mouse Y") only returns zero no matter what I do... I have tried checking inside the Input Manager and there was nothing wrong, nor anything they're missing and I tried to Clear All PlayerPrefs and that did not work and I have also tried to restart my whole PC but it did not work either...
I do not know what to do and I have tried everything but without luck
If there are any of you who can help me it will be a great help
Thanks
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Controller : MonoBehaviour
{
private Rigidbody RB;
public int Speed = 250, JumpPawer = 250, RotationSpeed = 20, MaxAngle = 130;
private Animator A;
public GameObject Came;
// Start is called before the first frame update
void Start()
{
RB = GetComponent<Rigidbody>();
A = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
//rotation
transform.eulerAngles += new Vector3(0, Input.GetAxis("Mouse X"), 0) * Time.deltaTime * RotationSpeed;
if (Came.transform.eulerAngles.x + (Input.GetAxis("Mouse Y") * Time.deltaTime * RotationSpeed) < MaxAngle) {
print(Input.GetAxis("Mouse Y"));
Came.transform.eulerAngles += new Vector3(Input.GetAxis("Mouse Y"), 0, 0) * Time.deltaTime * RotationSpeed;
}
//controls
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow)) {
RB.velocity = transform.forward * Time.deltaTime * Speed;
A.SetInteger("A", 1);
}
else if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow)) {
RB.velocity = -transform.forward * Time.deltaTime * Speed;
A.SetInteger("A", 1);
}
else if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow)) {
RB.velocity = -transform.right * Time.deltaTime * Speed;
A.SetInteger("A", 2);
}
else if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow)) {
RB.velocity = transform.right * Time.deltaTime * Speed;
A.SetInteger("A", 3);
}
else if (Input.GetKeyDown(KeyCode.Space)) {
RB.velocity = Vector3.up * Time.deltaTime * JumpPawer;
}
else
A.SetInteger("A", 0);
}
}
Unless you changed the input manager’s settings, it isn’t a problem with the actual input. You could make sure the problem isn’t with the input system, by typing this (make sure it is out of the if statement you wrote before):
print(Input.GetAxis(“Mouse Y”);
If you do this and test the game, move your mouse up and down, then if you get a value, that then tells us, that the problem lies with the if statement, if it still returns 0, then there is a problem with unity. Here is what the if statement says:
if (Came.transform.eulerAngles.x + (Input.GetAxis("Mouse Y") * Time.deltaTime * RotationSpeed) < MaxAngle) {
print(Input.GetAxis("Mouse Y"));
Came.transform.eulerAngles += new Vector3(Input.GetAxis("Mouse Y"), 0, 0) * Time.deltaTime * RotationSpeed;
}
Everything here is written out of my style (which is fine, it is just harder to understand), and there are no obvious errors, except for the code inside the parentheses. They say:
(Came.transform.eulerAngles.x + (Input.GetAxis("Mouse Y") * Time.deltaTime * RotationSpeed) < MaxAngle)
The only thing I can spot is that you are only checking if the x rotation goes over. This won’t work the way you wanted to, because it wouldn’t be cow clamped when it goes under to. Since we can’t find the error, (someone might) we should just rewrite it.
Instead of putting an if statement, just use Mathf.Clamp(v, a, b); Mathf.Clamp clamps a number, v, so it doesn’t go under a, or over b. This is useful for a camera script, because you don’t want it to rotate behind the player. You should try this method:
void Camera()
{
float MouseY = Input.GetAxis(“Mouse Y”) * Time.deltaTime * RotationSpeed;
Mathf.Clamp(MouseY, -89.5f, 89.5f);
Came.transform.localEulerAngles = new Vector3(MouseY, 0, 0);
print(MouseY);
}
I removed the if statement entirely because we use Mathf.Clamp. Now we don’t have to test if it goes over or under because if this. You should multiply Time.deltaTime and RotationSpeed earlier, because if you multiply it later, it will go above/below the clamp. I then use local Euler angles, because if the player rig rotates, then so does the camera, and local means https://docs.unity3d.com/ScriptReference/Transform-localEulerAngles.html. I then use the print statement just to test everything.
I hope this helps, if something doesn’t work, I’ll be sure to edit this post.
Related
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 = -gravity;
}
// jump
if (controller.isGrounded && Input.GetKeyDown(KeyCode.Space))
{
velocityY = jumpForce;
}
// sprint
if (Input.GetKey(KeyCode.LeftShift))
{
velocity = (transform.forward * currentDir.y + transform.right * currentDir.x) * sprintSpeed + Vector3.up * velocityY;
}
else
{
velocity = (transform.forward * currentDir.y + transform.right * currentDir.x) * walkSpeed + Vector3.up * velocityY;
}
velocityY -= gravity * Time.deltaTime;
Debug.Log(velocityY);
controller.Move(velocity * Time.deltaTime);
}
This is the code that I am using to move and jump in my game. Those functions work fine, the problem is in the gravity when walking off a surface. When jumping gravity works as intended but when falling without jumping (walking off the edge) gravity is still set to it's default value (15) so the characters falls incredibly fast.
I understand that this is caused by having no function to change this value when falling from an edge but I have found no way of making this happen without breaking all of the vertical movement.
You can reset the gravity as Brackeys did in his FPS Controller Tutorial:
if (isGrounded) {
velocityY = -2f;
}
im having an issue with the rotation of the camera around player getting too much damping. i do try to manipulate those speed value but it doesnt work at all. i think thats need something combination between slerp and lerp together, and i just dont know how. Btw im trying to create a third person game and the camera scripts make me stuck, and also i try to create my own scripts rather than using cinemachine. Really hope u guys can help me out.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Camera : MonoBehaviour
{
public float MouseX, MouseY;
public Transform Player;
public float SmoothTime;
public float DefaultZoom = 5f;
public float ZoomSpeed;
Vector3 NewPosition;
Quaternion NewRotation;
//----------------------------------------------------------------------------------------------------
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
Player = GameObject.Find("Player").transform;
}
//----------------------------------------------------------------------------------------------------
void Update()
{
MouseX += Input.GetAxis("Mouse X") * 100f * Time.deltaTime;
MouseY -= Input.GetAxis("Mouse Y") * 100f * Time.deltaTime;
MouseY = Mathf.Clamp(MouseY, -75, 75);
DefaultZoom += Input.GetAxis("Mouse ScrollWheel") * 100f * Time.deltaTime;
DefaultZoom = Mathf.Clamp(DefaultZoom, 3f, 9f);
DefaultZoom = Mathf.Lerp(Vector3.Distance(transform.position, Player.position), DefaultZoom, ZoomSpeed * Time.deltaTime);
}
void LateUpdate()
{
NewRotation = Quaternion.Euler(MouseY, MouseX, 0f);
transform.rotation = Quaternion.Slerp(transform.rotation, NewRotation, Time.deltaTime * SmoothTime);
NewPosition = Player.position - (transform.forward * DefaultZoom);
transform.position = Vector3.Lerp(transform.position, NewPosition, Time.deltaTime * SmoothTime);
}
}
You are using Lerp wrong, both for rotation and position. Lerp isn't actually intended for smoothing, but is used for that purpose never the less, since it is very quick to program.
To fix your problem quickly (tho at the cost of being frame rate dependent), simply remove the Time.deltaTime and make sure that the smooth variable is kept between 0 and 1. The underlying reason is that Time.deltaTime is jumpy (or jittery) by nature and it passes that property directly to Lerp.
I know this has been asked but can't figure out how to solve this.
if (this.gameObject.tag == "1Team"){
unitGO.transform.position += transform.right * movementSpeed * Time.deltaTime;
} else if (this.gameObject.tag == "2Team"){
unitGO.transform.position += transform.left * movementSpeed * Time.deltaTime;
}
Unity marks in red transform.left ( Transform' does not contain a definition for 'left' ), so I dont know how to move my character to the left. I have tried using -Transform.right, Transform.right * -movementSpeed, new Vector3( - 1,0,0), unitGO.transform.position -= new Vector3(1,0,0) * movementSpeed * Time.deltaTime; and other options without getting the movement I want.
if I change the tag from the GameObject I want to move, it actually moves right, so I dont think it's anything related to attaching scripts
https://docs.unity3d.com/ScriptReference/Vector3-left.html
Any suggestions?
Thank you
While Vector3.left exists, for Transform there is only transform.right.
Which is no problem since for moving left you simply use -transform.right.
Now note that your intempts of using new Vector3 also didn't work since if you use that you move in global space along Unity's X axis .. not in local space.
Now there are multiple possible solutions:
For moving in your local space do e.g.
if (gameObject.CompareTag("1Team"))
{
unitGO.transform.position += transform.right * movementSpeed * Time.deltaTime;
}
else if (gameObject.CompareTag("2Team"))
{
unitGO.transform.position -= transform.right * movementSpeed * Time.deltaTime;
// Same as
//unitGO.transform.position += -transform.right * movementSpeed * Time.deltaTime;
}
Or if you wan to move in Unity's global X axis then
if (gameObject.CompareTag("1Team"))
{
unitGO.transform.position += Vector3.right * movementSpeed * Time.deltaTime;
}
else if (gameObject.CompareTag("2Team"))
{
unitGO.transform.position += Vector3.left * movementSpeed * Time.deltaTime;
// Same as
//unitGO.transform.position -= Vector3.right * movementSpeed * Time.deltaTime;
}
Or if you actually rather wanted to move along the local X axis of the object you are moving you could rather use Translate which by default uses the local space of the moved object
if (gameObject.CompareTag("1Team"))
{
unitGO.transform.Translate(Vector3.right * movementSpeed * Time.deltaTime);
}
else if (gameObject.CompareTag("2Team"))
{
unitGO.transform.Translate(Vector3.left * movementSpeed * Time.deltaTime);
// Same as
//unitGO.transform.Translate(-Vector3.right * movementSpeed * Time.deltaTime);
}
In general rather use CompareTag instead of == to throw an error if there is a typo
I've only been working in unity for a few days and have the following problem that I don't know how to make the zoom in and zoom out smooth without the rest running smooth as well. Nevertheless I want to keep the function that I can decide if the rest can be smooth or not. As mentioned before, the main problem is that I don't know how to Smoothen the zoom in and zoom out ONLY. When I start the project with my current code, it feels like my mouse's dpi is pretty high. Also, every action is smooth, which I don't want either. I would be very happy about help.
Vace :)
if (thirdperson)
{
yaw += Input.GetAxis("Mouse X") * mouseSensitivity;
pitch -= Input.GetAxis("Mouse Y") * mouseSensitivity;
pitch = Mathf.Clamp(pitch, pitchMinMax.x, pitchMinMax.y);
// out
if (Input.GetAxis("Mouse ScrollWheel") < 0)
{
if (dstFromTarget < 12)
{
dstFromTarget++;
}
}
//in
if (Input.GetAxis("Mouse ScrollWheel") > 0)
{
if (dstFromTarget > 2)
{
dstFromTarget--;
}
}
currentRotation = Vector3.SmoothDamp(currentRotation, new Vector3(pitch, yaw), ref rotationSmoothVelocity, rotationSmoothTime);
transform.eulerAngles = currentRotation;
Vector3 test = Vector3.SmoothDamp(transform.position, target.position - transform.forward * dstFromTarget, ref zoomSmoothVelocity, zoomSmoothTime);
transform.position = new Vector3(test.x, test.y, test.z);
}
Use the float version of Vector3.SmoothDamp: Mathf.SmoothDamp.
Use it to find a smoothed target for dstFromTarget. change zoomSmoothVelocity to a float and initialize a current zoom variable to the same value as you initialize dstFromTarget.
Then, you can just assign the target you had for your Vector3.SmoothDamp directly to the camera's position.
Use transform.eulerAngles = new Vector3(pitch.yaw); to bypass your first call to Vector3.SmoothDamp
I'd also recommend using Mathf.Clamp to keep your zoom in a valid range.
Altogether, this may look like this:
private float zoomSmoothVelocity = 0f;
private float curZoom = 6f; // however dstFromTarget is initialized
// ...
if (thirdperson)
{
yaw += Input.GetAxis("Mouse X") * mouseSensitivity;
pitch -= Input.GetAxis("Mouse Y") * mouseSensitivity;
pitch = Mathf.Clamp(pitch, pitchMinMax.x, pitchMinMax.y);
// out
if (Input.GetAxis("Mouse ScrollWheel") < 0)
{
dstFromTarget++;
}
//in
if (Input.GetAxis("Mouse ScrollWheel") > 0)
{
dstFromTarget--;
}
dstFromTarget = Mathf.Clamp(dstFromTarget, 2f, 12f);
transform.eulerAngles = new Vector3(pitch, yaw);
curZoom = Mathf.SmoothDamp(curZoom , dstFromTarget, ref zoomVelocity , zoomSmoothTime);
transform.position = target.position - transform.forward * curZoom;
}
Have this camera working perfect on my target object with one caveat. Can't seem to get the character to look up and down. Left and right move perfectly, up and down don't move at all. What am I doing wrong with the "Mouse Y" part?
public GameObject target;
public float rotateSpeed = 7;
Vector3 offset;
void Start() {
offset = target.transform.position - transform.position;
}
void LateUpdate() {
float horizontal = Input.GetAxis("Mouse X") * rotateSpeed * Time.deltaTime;
float verticle = Input.GetAxis("Mouse Y") * rotateSpeed * Time.deltaTime;
target.transform.Rotate(0, horizontal, 0);
float desiredAngle = target.transform.eulerAngles.y;
Quaternion rotation = Quaternion.Euler(0, desiredAngle, verticle);
transform.position = target.transform.position - (rotation * offset);
transform.LookAt(target.transform);
}
You're not using verticle in your Transform.Rotate call (vertical?).
Edit: Sorry, I just stopped looking once I got to the first problem, looking further there's another problem that's similar to the one I addressed in this question. The "order of operations" is wrong (see the new comments):
public GameObject target;
public float rotateSpeed = 7;
Vector3 offset;
void Start() {
offset = target.transform.position - transform.position;
}
void LateUpdate() {
float horizontal = Input.GetAxis("Mouse X") * rotateSpeed * Time.deltaTime;
float verticle = Input.GetAxis("Mouse Y") * rotateSpeed * Time.deltaTime;
//You didn't use verticle before. Depending on your model/setup you might verticle as the 3rd (Z) parameter to get rotation in the right direction
target.transform.Rotate(verticle, horizontal, 0); //This line rotates the transform
float desiredAngle = target.transform.eulerAngles.y;
Quaternion rotation = Quaternion.Euler(0, desiredAngle, verticle);
transform.position = target.transform.position - (rotation * offset);
transform.LookAt(target.transform); //This sets the absolute rotation of the transform. This call will "override" the above call to Rotate
}
To give more information you'll have to give an explanation of what your end goal is with this code, because looking closer I'm seeing "oddities" with what the code sample is trying to do.
The last line of code (transform.Lookat) overrides the previous code ... basically says 'always look at the target no matter what else happens'.