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.
Related
I made a first person camera using parts of Brackeys Guide, I have camera moving on both the axis but the line for the xRotation clamp doesn't work when I run the game. How can I fix this?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseLook : MonoBehaviour
{
public float mouseSensitivity = 200f;
public Transform playerBody;
public Transform cam;
private float xRotation = 0f;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked; // stops you from click out off the sceen
}
// Update is called once per frame
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime; // mouse imput
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime; // mouse imput
xRotation = mouseY;
xRotation = Mathf.Clamp(xRotation, -80f, 73f); // stops you from breaking your neck
Quaternion localRotation = Quaternion.Euler(xRotation, 0f, 0f); // left and right movement
playerBody.Rotate(Vector3.up * mouseX); // left and right movement
cam.Rotate(Vector3.left * mouseY); // up and down movement
}
Setting new specific variables like roty and rotx, and clamping them individually.
It may be that the Vector3 vector has no value, if a value is generated, it can be
private Vector3 m_Dir
void Update () {
this.m_Dir = new Vector3 (localRotation, Vector3.up * mouseX,
tVector3.left * mouseY);
playerBody.Rotate(m_Dir);
cam.Rotate(m_Dir);
}
There are two main problems in the Update method:
xRotation = mouseY is not correct, since mouseY represents the delta angle you want to rotate in this frame, while xRotation represents the current angle at which the camera is rotated. You have to do a sum to get the next pitch of the camera, so xRotation += mouseY.
The quaternion localRotation is created but not actually used in the rotating logic, you still rotate the camera with cam.Rotate(Vector3.left * mouseY). Replace it with cam.localRotation = localRotation.
The final code should look like this:
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
// note: you shouldn't hardcode the min and max values,
// use some values that you can change in the inspector
xRotation = Mathf.Clamp(xRotation + mouseY, -80f, 73f);
cam.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
playerBody.Rotate(Vector3.up * mouseX);
I have this code:
using UnityEngine;
public class MouseLook : MonoBehaviour
{
float speed = 120f;
public Transform playerBody;
float xRotation = 200f;
float yRotation = 200f;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * speed * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * speed * Time.deltaTime;
playerBody.Rotate(Vector3.left * mouseY);
playerBody.Rotate(Vector3.up * mouseX);
xRotation -= mouseX;
yRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -25f, 30f);
yRotation = Mathf.Clamp(yRotation, -35f, 40f);
transform.localRotation = Quaternion.Euler(yRotation, xRotation, 0f);
}
}
The only problem is that when using it, the mouse is inverted on the X-axis. That is, when the mouse moves to the right, the camera moves to the left and vice versa. There is no such inversion with the Y-axis.
What wrong with this code?
When rotating an object around X axis, positive angles rotate down and negative angles rotate up. When rotating an object around Y axis, positive angles rotate right and negative angles rotate left.
Screen coordinates in Unity go from bottom left (0,0) to top right (x,y). When you move your mouse upward you get positive y values, when you move your mouse downward you get negative y values. Notice, that this is inverse of object rotation. That's why this line: yRotation -= mouseY; works fine (it inverts y values before rotating the object). However, for x values inversion isn't necessary since Screen space and Object space already align. You can just use: xRotation += mouseX; instead.
I don't know exactly what you are trying to achieve, but this looks weird to me: xRotation = Mathf.Clamp(xRotation, -25f, 30f);, because it clamps rotation to the left to 25 degrees and to the right to 30 degrees. Is this on purpose?
Try this code:
using UnityEngine;
public class MouseLook : MonoBehaviour
{
float speed = 120f;
public Transform playerBody;
float xRotation = 0f;
float yRotation = 0f;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * speed * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * speed * Time.deltaTime;
playerBody.Rotate(Vector3.left * mouseY);
playerBody.Rotate(Vector3.up * mouseX);
xRotation += mouseX;
yRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -25f, 30f);
yRotation = Mathf.Clamp(yRotation, -35f, 40f);
transform.localRotation = Quaternion.Euler(yRotation, xRotation, 0f);
}
}
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;
}
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 want to rotate a object on the x-axis when I move the mouse up or down (increase the x-rotation when moving mouse up, decrease when moving mouse down).
But I don't know how to do this.
I tried this script:
public float mouseSensitivity = 100.0F;
public float clampAngle = 80.0F;
float rotX = 0.0F, rotY = 0.0F;
void Update()
{
// Mouse Look
float mouseX = Input.GetAxis("Mouse X");
float mouseY = Input.GetAxis("Mouse Y");
rotX += mouseY * mouseSensitivity * Time.deltaTime;
rotY += mouseX * mouseSensitivity * Time.deltaTime;
rotX = Mathf.Clamp(rotX, -clampAngle, clampAngle);
Quaternion localRotation = Quaternion.Euler(rotX, 0, 0.0F);
transform.rotation = localRotation;
}
But this controls also rotation on the y axis. I also have rotation on the y-axis, but they are controlled via keyboard input:
if (Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S))
transform.Translate(Vector3.forward * Time.deltaTime * moveSpeed);
else if (Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.W))
transform.Translate(Vector3.forward * Time.deltaTime * -moveSpeed);
if (Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.D))
transform.Rotate(Vector3.up * Time.deltaTime * -rotateSpeed, Space.World);
else if (Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.A))
transform.Rotate(Vector3.up * Time.deltaTime * rotateSpeed, Space.World);
and I want the mouse up/down only control the rotation on the x-axis.
If someone can help me, that would be great!
void Update()
{
// Mouse Look
float mouseX = Input.GetAxis("Mouse X");
float mouseY = Input.GetAxis("Mouse Y");
rotX = mouseY * mouseSensitivity;
rotY = mouseX * mouseSensitivity;
transform.rotation *= Quaternion.Euler(rotX, 0, 0.0f);
}