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;
}
Related
I've genuinely gone through a million tutorials, but it doesn't work out. With this code, I either have to activate the last line or the second last line to get x rotation or y rotation respectively, but I obviously want them to work together.
void MouseLook()
{
mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -60, 10);
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
transform.Rotate(Vector3.up * mouseX);
}
The one always seems to cancel the other out. This is from a Brackeys tutorial. I had to tweak some stuff so it's applicable, but I obviously am breaking the code that way. Please help!
Try this Stuff
public float mouseSensitivity = 10.0f;
public Transform target;
public float dstFromTarget = 2.0f;
public float yaw;
public float pitch;
public Vector2 pitchMinMax = new Vector2(-50, 85);
public float rotationSmoothTime = 0.02f;
Vector3 rotationSmoothVelocity;
Vector3 currentRotation;
void LateUpdate()
{
MouseLook();
}
void MouseLook()
{
//Mouse Movement
yaw += Input.GetAxis("Mouse X") * mouseSensitivity;
pitch -= Input.GetAxis("Mouse Y") * mouseSensitivity;
// Claemp
pitch = Mathf.Clamp(pitch, pitchMinMax.x, pitchMinMax.y);
// Positioning
transform.eulerAngles = currentRotation;
// Smoothening
currentRotation = Vector3.SmoothDamp(currentRotation, new Vector3(pitch, yaw), ref rotationSmoothVelocity, rotationSmoothTime);
transform.localRotation = Quaternion.Euler(currentRotation.x,currentRotation.y,currentRotation.z);
}
I'm struggling to change the axis from X and Y axis to X and Z axis. Can someone help me?
using System.Collections.Generic;
using UnityEngine;
public class CameraDragMove : MonoBehaviour
{
public float panSpeed = 10f;
void Update()
{
if (Input.GetMouseButton(0)) // right mouse button
{
var newPosition = new Vector3();
newPosition.x = Input.GetAxis("Mouse X") * panSpeed * Time.deltaTime;
newPosition.y = Input.GetAxis("Mouse Y") * panSpeed * Time.deltaTime;
// translates to the opposite direction of mouse position.
transform.Translate(-newPosition);
}
}
}
If you mean move along the X and Z axis as opposed to X and Y (and not both at once), you could do this instead of your current movement.
newPosition.x = Input.GetAxis("Mouse X") * panSpeed * Time.deltaTime;
newPosition.z = Input.GetAxis("Mouse Y") * panSpeed * Time.deltaTime;
In this, I am literally just changing the Z value of the Vector3. It may be worth looking into the Unity documentation if you don't know how stuff like this works.
I'm having an issue with the free roam camera I'm trying to implement. The camera can be rotated via keyboard (only on the Y axis) and via mouse (on the X and Y axis) while holding the middle mouse button. With my current implementation, if I rotate the camera using the keyboard and the rotate it using the mouse, it remove any rotation done by the keyboard as soon as I hit the middle mouse button. Of course I would like to not do that... Code is below. Can someone give tell me what I'm doing wrong?
private void RotateCameraKeyboard()
{
if (Input.GetKey(KeyCode.Q))
{
transform.RotateAround(transform.position, Vector3.up, -rotationSpeed * Time.deltaTime * 30);
}
if (Input.GetKey(KeyCode.E))
{
transform.RotateAround(transform.position, Vector3.up, rotationSpeed * Time.deltaTime * 30);
}
}
private void RotateCameraMouse()
{
if (Input.GetMouseButton(2))
{
pitch -= rotationSpeed * Input.GetAxis("Mouse Y");
yaw += rotationSpeed * Input.GetAxis("Mouse X");
pitch = Mathf.Clamp(pitch, -90f, 90f);
while (yaw < 0f)
{
yaw += 360f;
}
while (yaw >= 360f)
{
yaw -= 360f;
}
transform.eulerAngles = new Vector3(pitch, yaw, 0f);
}
}
Instead of using RotateAround (which in your case of using the transform.position as pivot is redundant anyway .. you could as well just use Rotate) additionally also add the according amount to your pitch and yawn.
I would simply generalize and use the same method for both inputs like e.g.
private void RotateCameraKeyboard()
{
if (Input.GetKey(KeyCode.Q))
{
Rotate(-rotationSpeed * Time.deltaTime * 30, 0);
}
if (Input.GetKey(KeyCode.E))
{
Rotate(rotationSpeed * Time.deltaTime * 30, 0);
}
}
private void RotateCameraMouse()
{
if (Input.GetMouseButton(2))
{
var pitchChange = rotationSpeed * Input.GetAxis("Mouse Y");
var yawChange = rotationSpeed * Input.GetAxis("Mouse X");
Rotate(yawChange, pitchChange);
}
}
private void Rotate(float yawChange, float pitchChange)
{
pitch = Mathf.Clamp(pitch + pitchChange, -90f, 90f);
yaw += yawChange;
while (yaw < 0f)
{
yaw += 360f;
}
while (yaw >= 360f)
{
yaw -= 360f;
}
transform.eulerAngles = new Vector3(pitch, yaw, 0f);
}
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.
I'm trying to create a RTS-esque camera control system for my game and I've hit a wall and am unsure how to proceed.
What I want to happen is the following:
Mouse Click + Drag = Move the camera around the world (works)
Mouse Scroll Wheel Click + Drag = Rotate camera around the world (works)
Mouse Scroll Wheel = Zoom in/out using MoveToward/Transform.Forward..etc (sorta works)
In another script I have FoV zoom working, but it is not ideal for the type of experience I want to create. Instead I am trying to physically move the camera in the direction it is pointed.
This current script is 90% functional in that it can do all the things listed above, but when I click + drag to move to a new location after scrolling to zoom, the camera resets to the original position.
Here is what happens in Update():
void Update ()
{
currentPosition = transform.position;
scrollAxis = Input.GetAxis ("Mouse ScrollWheel");
if (Input.GetMouseButtonDown (0))
{
mouseOrigin = Input.mousePosition;
isPanning = true;
}
// cancel on button release
if (!Input.GetMouseButton (0))
{
isPanning = false;
}
//move camera on X & Y
else if (isPanning)
{
Vector3 pos = Camera.main.ScreenToViewportPoint (Input.mousePosition - mouseOrigin);
Vector3 move = new Vector3 (pos.x * -panSpeed, pos.y * -panSpeed, 0);
Camera.main.transform.Translate (move, Space.Self);
transform.eulerAngles = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, 0 );
transform.localPosition = new Vector3( transform.position.x, transform.position.y - (transform.position.y - (initialPosition.y)), transform.position.z );
}
//rotate camera with mousewheel click
if (Input.GetMouseButton(2)) {
yRotation -= Input.GetAxis("Mouse Y") * rotationSpeed * Time.deltaTime;
yRotation = Mathf.Clamp(yRotation, -80, 80);
xRotation += Input.GetAxis("Mouse X") * rotationSpeed * Time.deltaTime;
xRotation = xRotation % 360;
transform.localEulerAngles = new Vector3(yRotation + initialRotation.x, xRotation + initialRotation.y, 0);
}
//zoom with scroll
if ( Input.GetAxis("Mouse ScrollWheel") > 0 && !isPanning) {
transform.Translate(Vector3.forward * Time.deltaTime * 10000f * scrollAxis, Space.Self );
transform.localPosition = new Vector3( transform.position.x, transform.position.y, transform.position.z );
}
}
Any help is much appreciated, thanks!
Solved it with the help of a friend.
Needed to reset the initialPosition Vector3 each time I zoomed, to prevent from snapping back to the original location.
if ( Input.GetAxis("Mouse ScrollWheel") > 0) {
transform.Translate(Vector3.forward * Time.deltaTime * 10000f * scrollAxis, Space.Self );
initialPosition = transform.position;
}