I'm creating on a game where the player is always bouncing up and down can go on different ground with different hights.
I have created this code for bouncing :
transform.position = new Vector3(Mathf.Lerp(transform.position.x, Towards.x, Time.deltaTime * 5), minY + Mathf.Abs(Mathf.Sin(Time.time * 3) * maxY) , transform.position.z);
with "MaxY" I controll the amount of height in a bounce. I change maxY when the ball is on the ground so it will have a smooth movement
if (Mathf.Abs(Mathf.Sin(Time.time * 3)) < 0.02f && grounded)
{
grounded = false;
maxZ = 2.5f * maxY;
}
else if (Mathf.Abs(Mathf.Sin(Time.time * 3)) > 0.02f)
{
grounded = true;
}
my problem is when the ball goes to a higher or lower ground.
i detect hight of the ground with this code :
RaycastHit hit;
if (Physics.Raycast(transform.position, -transform.up, out hit, 40, mask))
{
minY = GetComponent<SphereCollider>().radius + hit.point.y;
}
and then it will be added to the minY in next update. but the problem is the player will suddenly change it's position in the air when the minY changes.
I need a code to make this change of height smooth but cant come up with any idea.
Here is my very simple solution maybe you can give it a try:
using UnityEngine;
using System.Collections;
public class jump : MonoBehaviour {
private float radius;
public float jumpPowa = 350;
// Use this for initialization
void Start () {
radius = GetComponent<Collider>().bounds.extents.y;
}
// Update is called once per frame
void Update () {
if (isGrounded())
{
GetComponent<Rigidbody>().AddForce(transform.up * jumpPowa);
}
}
private bool isGrounded()
{
return Physics.Raycast(transform.position, -Vector3.up, radius + 0, 1);
}
}
Related
Player movement is working (at least somewhat) now, however one issue remains, and that's the insane numbers the y velocity of the Rigidbody2D on the player. Since the isGrounded check I plan to add will use velocity for the sake of stability, this needs to be fixed.
It confuses me, considering the velocity is 0 normally, but whenever moving left or right it changes to said high numbers.
Movement code:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerM : MonoBehaviour
{
private PControls control;
Rigidbody2D rb;
SpriteRenderer sp;
Transform tr;
public float speed = 0f;
public float speedC;
public float heightSpeed = 5f;
public float heightC;
public bool grounded;
void Start()
{
control = new PControls();
control.Enable();
rb = GetComponent<Rigidbody2D>();
sp = GetComponent<SpriteRenderer>();
tr = GetComponent<Transform>();
}
// Update is called once per frame
void FixedUpdate()
{
RaycastHit2D hit = Physics2D.Raycast(rb.position, -Vector2.up);
Color color = new Color(0, 0, 1.0f);
Debug.DrawRay(transform.position, Vector2.down);
speedC = rb.velocity.magnitude;
var pos = control.Movement.Move.ReadValue<float>();
float GetVerticalSpeed() => rb.velocity.y;
if(pos == -1)
{
sp.flipX = true;
}
else if(pos == 1)
{
sp.flipX = false;
}
if((pos == 0) && (speed > 0.1f))
{
speed -= 3f * Time.deltaTime;
}
else if(speed < 1.4f)
{
speed += Mathf.Abs(pos) * 8 * Time.deltaTime;
}
if(speedC < 7f)
{
rb.AddForce(new Vector3((pos * 5), 0f) * speed * Time.deltaTime, ForceMode2D.Impulse);
}
var jump = control.Movement.Jump.ReadValue<float>();
Debug.Log(GetVerticalSpeed());
Vector3 v = rb.velocity;
v.y = 10;
if(jump == 1)
{
rb.velocity = v;
}
}
}
Seems the main issue was fixed by converting the height velocity to an integer using System.Math.Round():
float vel = rb.velocity.y;
heightC = (int)System.Math.Round(vel);
Not sure it's the best solution, but it's something..
I can make the camera move the way I want, but I need it to be confined to within the 3D hollow sphere that I created. Currently the player can fly the camera out of the game area.
I've tried parenting the camera to a spherical game object, but the camera still leaves the game area but the sphere stays inside.
This was my attempt at using the BoundingSphere method to keep the camera inside the sphere.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SphericalBoundary : MonoBehaviour
{
public Vector3 pos;
public float r;
void Start()
{
BoundingSphere();
}
private void FixedUpdate()
{
BoundingSphere();
}
public void BoundingSphere()
{
pos = new Vector3(0, 0, 0);
r = (100);
}
}
============================================================================
============================================================================
This is the script that makes the camera fly around. Works perfectly.
using UnityEngine;
using System.Collections;
public class CameraFlight : MonoBehaviour
{
/*
EXTENDED FLYCAM
Desi Quintans (CowfaceGames.com), 17 August 2012.
Based on FlyThrough.js by Slin (http://wiki.unity3d.com/index.php/FlyThrough), 17 May 2011.
LICENSE
Free as in speech, and free as in beer.
FEATURES
WASD/Arrows: Movement
Q: Climb
E: Drop
Shift: Move faster
Control: Move slower
End: Toggle cursor locking to screen (you can also press Ctrl+P to toggle play mode on and off).
*/
public float cameraSensitivity = 90;
public float climbSpeed = 4;
public float normalMoveSpeed = 10;
public float slowMoveFactor = 0.25f;
public float fastMoveFactor = 3;
private float rotationX = 0.0f;
private float rotationY = 0.0f;
void Start()
{
// Screen.lockCursor = true;
}
void Update()
{
rotationX += Input.GetAxis("Mouse X") * cameraSensitivity * Time.deltaTime;
rotationY += Input.GetAxis("Mouse Y") * cameraSensitivity * Time.deltaTime;
rotationY = Mathf.Clamp(rotationY, -90, 90);
transform.localRotation = Quaternion.AngleAxis(rotationX, Vector3.up);
transform.localRotation *= Quaternion.AngleAxis(rotationY, Vector3.left);
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
{
transform.position += transform.forward * (normalMoveSpeed * fastMoveFactor) * Input.GetAxis("Vertical") * Time.deltaTime;
transform.position += transform.right * (normalMoveSpeed * fastMoveFactor) * Input.GetAxis("Horizontal") * Time.deltaTime;
}
else if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl))
{
transform.position += transform.forward * (normalMoveSpeed * slowMoveFactor) * Input.GetAxis("Vertical") * Time.deltaTime;
transform.position += transform.right * (normalMoveSpeed * slowMoveFactor) * Input.GetAxis("Horizontal") * Time.deltaTime;
}
else
{
transform.position += transform.forward * normalMoveSpeed * Input.GetAxis("Vertical") * Time.deltaTime;
transform.position += transform.right * normalMoveSpeed * Input.GetAxis("Horizontal") * Time.deltaTime;
}
if (Input.GetKey(KeyCode.Q)) { transform.position += transform.up * climbSpeed * Time.deltaTime; }
if (Input.GetKey(KeyCode.E)) { transform.position -= transform.up * climbSpeed * Time.deltaTime; }
//if (Input.GetKeyDown(KeyCode.End))
//{
// Screen.lockCursor = (Screen.lockCursor == false) ? true :][1]
false;
//}
}
}
No errors are showing up. During play the player can fly the camera out of the sphere but I want them confined to the sphere.
I think you must look your camera position on every frame and also check if it's going out of bound of the sphere here is some code which might help you(it is not tested)
public class TestScriptForStackOverflow : MonoBehaviour {
public Transform CameraTrans, SphereTrans;
private float _sphereRadius;
void Start() {
//if we are talking about sphere its localscale.x,y,z values are always equal
_sphereRadius = SphereTrans.localScale.x / 2;
}
void Update() {
if (IsOutsideTheSphere(_sphereRadius, CameraTrans.position, SphereTrans.position)) {
//lets find direction of camera from sphere center
Vector3 direction = (CameraTrans.position - SphereTrans.position).normalized;
//this is bound point for specific direction which is point is on the end of the radius
Vector3 boundPos = SphereTrans.position + direction * _sphereRadius;
//finally assign bound position to camera to stop it to pierce the sphere bounds
CameraTrans.position = boundPos;
}
}
private bool IsOutsideTheSphere(float sphereRadius, Vector3 cameraPosition, Vector3 sphereCenterPosition) {
//distance betweeen cameraPosition and sphereCenterPosition
float distanceBetween = (cameraPosition - sphereCenterPosition).magnitude;
//returns true if distance between sphere center and camera position is longer then sphere radius
return distanceBetween > sphereRadius;
}
If there is something you don't understand ask me in comments
I have a stationary cube in my scene that I'm orbiting a camera around. I have my MainCamera nested under a GameObject that I'm calling 'OrbitalCamera'.
I setup the script so that a click (or tap) and drag will rotate the camera around the object in space so it feels like you're rotating the cube (ie: if I click the top of a face on the cube, and pull down, I'm rotating the X value) but you'll actually be rotating the camera.
For the most part, my script works. However, after rotating the Y so much, the camera is upside down and the X gets inverted. Here's my script:
public class OrbitalCamera : MonoBehaviour {
public bool cameraEnabled;
[SerializeField] private float touchSensitivity;
[SerializeField] private float scrollSensitivity;
[SerializeField] private float orbitDampening;
protected Transform xFormCamera;
protected Transform xFormParent;
protected Vector3 localRotation;
protected float cameraDistance;
void Start () {
cameraEnabled = true;
xFormCamera = transform;
xFormParent = transform.parent;
cameraDistance = transform.position.z * -1;
}
void LateUpdate () {
if (cameraEnabled) {
// TODO:: FIX PROBLEM WHERE WHEN CAMERA IS ROTATED TO BE UPSIDEDOWN, CONTROLS GET INVERSED
if (Input.GetMouseButton(0)) {
if (Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0) {
localRotation.x += Input.GetAxis("Mouse X") * touchSensitivity;
localRotation.y -= Input.GetAxis("Mouse Y") * touchSensitivity;
}
}
}
Quaternion qt = Quaternion.Euler(localRotation.y, localRotation.x, 0);
xFormParent.rotation = Quaternion.Lerp(xFormParent.rotation, qt, Time.deltaTime * orbitDampening);
}
}
Is there a good method to achieve this type of 360 camera? I'd like dragging from right to left to always move the camera left and dragging left to right to always move the camera right -- no matter how the camera is oriented.
Perhaps you could clamp the above/below pan at 89 degrees?
I recently helped a friend make a mouse gimbal, and found allowing freedom beyond 89 degrees was problematic and unnecessary. It seems like your application is the same, at least for one of the two planes.
In your LateUpdate() call, you could perhaps add:
localRotation.x += Input.GetAxis("Mouse X") * touchSensitivity;
localRotation.x = Clamp(localRotation.x);
Then, of course, create your clamp function, which should be fairly straight forward:
float Clamp(float val) // prevent values from ~90 - ~270
{
int lowVal = 89;
int highVal = 271;
int midVal = 180;
if (val > lowVal & val < highVal)
{
if (val > midVal) val = highVal;
else val = lowVal;
}
return val;
}
A slightly different application, but I'm sure you can see how I've set this up: I apply rotation in two steps. Step 1 - a simple Rotate() call, Step 2 - clamping some/all of the rotation:
using UnityEngine;
public class MouseGimbal : MonoBehaviour
{
[SerializeField] [Range(0,89)] float maxRotationDegrees = 10.0f; // At 90+ gimbal oddities must be dealt with.
[SerializeField] bool ClampToMaxRotationDegrees = true; // Disable for free rotation.
[SerializeField] float rotationSpeed = 10.0f;
const float fullArc = 360.0f;
const float halfArc = 180.0f;
const float nullArc = 0.0f;
void Update () { Tilt(); }
void Tilt()
{
// Apply the 'pre-clamp' rotation (rotation-Z and rotation-X from X & Y of mouse, respectively).
if (maxRotationDegrees > 0) { SimpleRotation(GetMouseInput()); }
// Clamp rotation to maxRotationDegrees.
if (ClampToMaxRotationDegrees) { ClampRotation(transform.rotation.eulerAngles); }
}
void ClampRotation(Vector3 tempEulers)
{
tempEulers.x = ClampPlane(tempEulers.x);
tempEulers.z = ClampPlane(tempEulers.z);
tempEulers.y = nullArc; // ClampPlane(tempEulers.y); // *See GIST note below...
transform.rotation = Quaternion.Euler(tempEulers);
///Debug.Log(tempEulers);
}
float ClampPlane(float plane)
{
if (OkayLow(plane) || OkayHigh(plane)) DoNothing(); // Plane 'in range'.
else if (BadLow(plane)) plane = Mathf.Clamp(plane, nullArc, maxRotationDegrees);
else if (BadHigh(plane)) plane = Mathf.Clamp(plane, fullArc - maxRotationDegrees, fullArc);
else Debug.LogWarning("WARN: invalid plane condition");
return plane;
}
Vector2 GetMouseInput()
{
Vector2 mouseXY;
mouseXY.x = -Input.GetAxis("Mouse X"); // MouseX -> rotZ.
mouseXY.y = Input.GetAxis("Mouse Y"); // MouseY -> rotX.
return mouseXY;
}
void SimpleRotation(Vector2 mouseXY)
{
Vector3 rotation = Vector3.zero;
rotation.x = mouseXY.y * Time.deltaTime * rotationSpeed;
rotation.z = mouseXY.x * Time.deltaTime * rotationSpeed;
transform.Rotate(rotation, Space.Self);
}
void DoNothing() { }
bool OkayHigh(float test) { return (test >= fullArc - maxRotationDegrees && test <= fullArc); }
bool OkayLow(float test) { return (test >= nullArc && test <= maxRotationDegrees); }
bool BadHigh(float test) { return (test > halfArc && !OkayHigh(test)); }
bool BadLow(float test) { return (test < halfArc && !OkayLow(test)); }
}
When I developed an orbital camera, I created 3 objects:
- x_axis (rotate with vertical mouse moviment)
- y_axis (rotate with horizontal mouse moviment)
- camera (look_at object) (translated Vector3(0,0,-10))
I'm using this mouseorbit script attached to a camera.
The problem is when i move the camera with the mouse and rotating it so the camera is under the terrain.
I want that when it get to the terrain height then stop don't move down i mean don't get to this view under the character maximum to be in the terrain height..
To stop on terrain height i mean something like that when it's getting to this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseOrbit : MonoBehaviour
{
/* These variables are what tell the camera how its going to function by
* setting the viewing target, collision layers, and other properties
* such as distance and viewing angles */
public Transform viewTarget;
public LayerMask collisionLayers;
public float distance = 6.0f;
public float distanceSpeed = 150.0f;
public float collisionOffset = 0.3f;
public float minDistance = 4.0f;
public float maxDistance = 12.0f;
public float height = 1.5f;
public float horizontalRotationSpeed = 250.0f;
public float verticalRotationSpeed = 150.0f;
public float rotationDampening = 0.75f;
public float minVerticalAngle = -60.0f;
public float maxVerticalAngle = 60.0f;
public bool useRMBToAim = false;
/* These variables are meant to store values given by the script and
* not the user */
private float h, v, smoothDistance;
private Vector3 newPosition;
private Quaternion newRotation, smoothRotation;
private Transform cameraTransform;
/* This is where we initialize our script */
void Start()
{
Initialize();
}
/* This is where we set our private variables, check for null errors,
* and anything else that needs to be called once during startup */
void Initialize()
{
h = this.transform.eulerAngles.x;
v = this.transform.eulerAngles.y;
cameraTransform = this.transform;
smoothDistance = distance;
NullErrorCheck();
}
/* We check for null errors or warnings and notify the user to fix them */
void NullErrorCheck()
{
if (!viewTarget)
{
Debug.LogError("Please make sure to assign a view target!");
Debug.Break();
}
if (collisionLayers == 0)
{
Debug.LogWarning("Make sure to set the collision layers to the layers the camera should collide with!");
}
}
/* This is where we do all our camera updates. This is where the camera
* gets all of its functionality. From setting the position and rotation,
* to adjusting the camera to avoid geometry clipping */
void LateUpdate()
{
if (!viewTarget)
return;
/* We check for right mouse button functionality, set the rotation
* angles, and lock the mouse cursor */
if (!useRMBToAim)
{
/* Check to make sure the game isn't paused and lock the mouse cursor*/
if (Time.timeScale > 0.0f)
Cursor.lockState = CursorLockMode.Locked;
h += Input.GetAxis("Mouse X") * horizontalRotationSpeed * Time.deltaTime;
v -= Input.GetAxis("Mouse Y") * verticalRotationSpeed * Time.deltaTime;
h = ClampAngle(h, -360.0f, 360.0f);
v = ClampAngle(v, minVerticalAngle, maxVerticalAngle);
newRotation = Quaternion.Euler(v, h, 0.0f);
}
else
{
if (Input.GetMouseButton(1))
{
/* Check to make sure the game isn't paused and lock the mouse cursor */
if (Time.timeScale > 0.0f)
Cursor.lockState = CursorLockMode.Locked;
h += Input.GetAxis("Mouse X") * horizontalRotationSpeed * Time.deltaTime;
v -= Input.GetAxis("Mouse Y") * verticalRotationSpeed * Time.deltaTime;
h = ClampAngle(h, -360.0f, 360.0f);
v = ClampAngle(v, minVerticalAngle, maxVerticalAngle);
newRotation = Quaternion.Euler(v, h, 0.0f);
}
else
{
Cursor.lockState = CursorLockMode.Confined;
}
}
/* We set the distance by moving the mouse wheel and use a custom
* growth function as the time value for linear interpolation */
distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 10, minDistance, maxDistance);
smoothDistance = Mathf.Lerp(smoothDistance, distance, TimeSignature(distanceSpeed));
/*We give the rotation some smoothing for a nicer effect */
smoothRotation = Quaternion.Slerp(smoothRotation, newRotation, TimeSignature((1 / rotationDampening) * 100.0f));
newPosition = viewTarget.position;
newPosition += smoothRotation * new Vector3(0.0f, height, -smoothDistance);
/* Calls the function to adjust the camera position to avoid clipping */
CheckSphere();
smoothRotation.eulerAngles = new Vector3(smoothRotation.eulerAngles.x, smoothRotation.eulerAngles.y, 0.0f);
cameraTransform.position = newPosition;
cameraTransform.rotation = smoothRotation;
}
/* This is where the camera checks for a collsion hit within a specified radius,
* and then moves the camera above the location it hit with an offset value */
void CheckSphere()
{
/* Add height to our spherecast origin */
Vector3 tmpVect = viewTarget.position;
tmpVect.y += height;
RaycastHit hit;
/* Get the direction from the camera position to the origin */
Vector3 dir = (newPosition - tmpVect).normalized;
/* Check a radius for collision hits and then set the new position for
* the camera */
if (Physics.SphereCast(tmpVect, 0.3f, dir, out hit, distance, collisionLayers))
{
newPosition = hit.point + (hit.normal * collisionOffset);
}
}
/* Keeps the angles values within their specificed minimum and maximum
* inputs while at the same time putting the values back to 0 if they
* go outside of the 360 degree range */
private float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
/* This is our custom logistic growth time signature with speed as input */
private float TimeSignature(float speed)
{
return 1.0f / (1.0f + 80.0f * Mathf.Exp(-speed * 0.02f));
}
}
It looks like the script i grabbed already handles terrain collision... i just need to make sure to set the collision layers on it to include the terrain. But not sure how to do it.
What i tried:
I added now a new layer in the inspector called it Terrain.
Then in the hierarchy on the Terrain i change it's layer to terrain.
Also in the script i selected Terrain. But it's still not working.
In the screenshot the top is the inspector of the camera with the script selected in Collision Layers Terrain.
In the bottom the terrain inspector selected Terrain as :Layer
Many answers to this question.
But here's my take on it since I am fairly certain this solution is interesting compared to all solutions you will find online related to unity 3rd person controllers.
Abstract
In Unity, you could take the usual approach of having an empty object and having that be the parent of the camera, etc... But what people in the industry would typically do is use a mathematical formula called Spherical coordinates.
This, by far, is the best approach for 3rd person controllers from my experience and its the most elegant and beautiful approach. All you need to do after implementing this approach, is shoot a ray from the camera down a meter, and if it detects anything, then change a single value in your spherical coordinates formula which would make the sphere around the player smaller which gives the effect of collision
Implementation
Here's a snippet of code which shows a single function needed to create the spherical coordinates formula.
private Vector3 sphericalCoordinates()
{
float m = distanceFromPlayer;
v = mouseY;
h = mouseX;
x = m * Mathf.Sin(v) * Mathf.Cos(h);
z = m * Mathf.Sin(v) * Mathf.Sin(h);
y = m * Mathf.Cos(v);
Vector3 pos = new Vector3(x, y, z);
return pos;
}
m = magnitude.
You can think of this as the radius from the sphere, this is what you change to give the collision effect.
I later use this snippet to bind the player with the camera in trigger.
[NOTE: very unclean code, I just wanted to show you a basic concept, definitely make it cleaner later]
Vector3 getCamRotWORLD()
{
Vector3 camRotWORLD = new Vector3(0, transform.rotation.eulerAngles.y, 0);
return camRotWORLD;
}
void adjustPlayerRot()
{
if (Input.GetKey(KeyCode.W))
{
player.transform.rotation = Quaternion.Euler(player.transform.rotation.x, getCamRotWORLD().y, player.transform.rotation.z);
player.transform.Translate(0, 0, playerScript.speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.A))
{
player.transform.rotation = Quaternion.Euler(player.transform.rotation.x, getCamRotWORLD().y - 90, player.transform.rotation.z);
player.transform.Translate(0, 0, playerScript.speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.S))
{
player.transform.rotation = Quaternion.Euler(player.transform.rotation.x, getCamRotWORLD().y - 180, player.transform.rotation.z);
player.transform.Translate(0, 0, playerScript.speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.D))
{
player.transform.rotation = Quaternion.Euler(player.transform.rotation.x, getCamRotWORLD().y + 90, player.transform.rotation.z);
player.transform.Translate(0, 0, playerScript.speed * Time.deltaTime);
}
}
Here's how my update looks like in case you really would like to snatch the implementation instead of trying to experiment with it yourself.
private void Update()
{
mouseX -= Input.GetAxis("Mouse X") * (sensitivity * Time.deltaTime);
mouseY -= Input.GetAxis("Mouse Y") * (sensitivity * Time.deltaTime);
playerCam.transform.LookAt(player.transform);
playerCam.transform.position = new Vector3(
sphericalCoordinates().x + player.transform.position.x,
sphericalCoordinates().y,
sphericalCoordinates().z + player.transform.position.z
);
}
I have a main camera in Unity3D that I want to rotate depending on mouse input, so it works as a first person video-game where you move the mouse depending on where do you want to look at.
The starting values of the camera (Transform tab in Inspector tab in Unity) are:
Position: X = -1, Y = 1, Z = -11.
Rotation: X = 0, Y = 0, Z = 0.
Scale: X = 1, Y = 1, Z = 1.
I added a Script component for the Main Camera. And it is the following class:
using UnityEngine;
using System.Collections;
public class CameraMove : MonoBehaviour {
float deltaRotation = 50f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(Input.GetAxis("Mouse X") < 0){
//Code for action on mouse moving left
transform.Rotate (new Vector3 (0f, -deltaRotation, 0f) * Time.deltaTime);
}
else if(Input.GetAxis("Mouse X") > 0){
//Code for action on mouse moving right
transform.Rotate (new Vector3 (0f, deltaRotation, 0f) * Time.deltaTime);
}
if(Input.GetAxis("Mouse Y") < 0){
//Code for action on mouse moving left
transform.Rotate (new Vector3 (deltaRotation, 0f, 0f) * Time.deltaTime);
}
else if(Input.GetAxis("Mouse Y") > 0){
//Code for action on mouse moving right
transform.Rotate (new Vector3 (-deltaRotation, 0f, 0f) * Time.deltaTime);
}
}
}
However, when I play the scene the camera doesn't rotate like it should. The values of the rotation change in x-axis, y-axis and even for z-axis.
What am I doing wrong?
That's a problem with how Quaternion is calculated. This happens when multiple axis are being modified. If you comment all the x rotation or the y rotation, and only rotate in one axis at a time, you will realize that this problem will go away.
To properly rotate your camera with the mouse input, use the eulerAngles or localEulerAngles variables. The option between these two depends on what you are doing.
public float xMoveThreshold = 1000.0f;
public float yMoveThreshold = 1000.0f;
public float yMaxLimit = 45.0f;
public float yMinLimit = -45.0f;
float yRotCounter = 0.0f;
float xRotCounter = 0.0f;
// 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);
transform.localEulerAngles = new Vector3(-yRotCounter, xRotCounter, 0);
}