I want to add camera shake to my player camera using perlin noise.
I put the perlin noise on a float and added it to the rotation of my camera, but for the x rotation I needed to offset the xrot float with my noise. I tried adding it but because it's in the update function, it keeps adding every frame. Basically, how do i offset the value of a float in the update function without it increasing?
the code on a script that makes the noise values
public float xrotnoise = 0f;
public float yrotnoise = 0f;
public float zrotnoise = 0f;
public float speed = 10f;
float overtime = 0f;
public float strength = 10f;
void Update()
{
overtime = Time.time / speed;
xrotnoise = (Mathf.PerlinNoise(overtime, 0) / strength - ((Mathf.PerlinNoise(overtime, 0) / strength) / 2));
yrotnoise = (Mathf.PerlinNoise(overtime, 500) / (strength * 0.7f) - ((Mathf.PerlinNoise(overtime, 0) / strength) / 2));
zrotnoise = (Mathf.PerlinNoise(overtime, 1000) / (strength * 0.1f) - ((Mathf.PerlinNoise(overtime, 0) / strength) / 2));
}
the camera movement script
float xrot = 0f;
void Update()
{
float mousex = Input.GetAxis("Mouse X") * mousesens * Time.deltaTime;
float mousey = Input.GetAxis("Mouse Y") * mousesens * Time.deltaTime;
playerbody.Rotate(Vector3.up * mousex);
xrot -= mousey + GetComponent<cambob>().xrotnoise;
transform.localRotation = Quaternion.Euler(xrot, GetComponent<cambob>().yrotnoise, GetComponent<cambob>().zrotnoise);
xrot = Mathf.Clamp(xrot, -90f, 90f);
}
Related
My build suffers from terrible stutter/lag when I cirle objects.
In this forum I have been advised to set the rigid body to "Interpolate" and to use LateUpdate in my script.
Problem is...I dont know how?
When I try, I get compiler error or just cant move the cam.
I found another free FPS script that worked, by using camera follow lag, but i cant figure out how to use that code either.
How can I use LateUpdate in my current script?
void Start() {
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
void Update() {
float x = Input.GetAxis("Mouse X") * sensitivity * Time.deltaTime;
float y = Input.GetAxis("Mouse Y") * sensitivity * Time.deltaTime * -1f;
transform.Rotate(0f, x, 0f);
headRotation += y;
headRotation = Mathf.Clamp(headRotation, -headRotationLimit, headRotationLimit);
cam.localEulerAngles = new Vector3(headRotation, 0f, 0f);
}
Here is an edited version of my FPS player rotation method, use this as a guide for how it can be done and modify it for your needs including a couple of methods I use to limit how far the Camera can rotate (the player can look up and down)
// Set the Camera in the inspector so that it can be rotated
public Camera camera;
// Rotation variables for both the player and camera
private Quaternion _playerRotation;
private Quaternion _cameraRotation;
// The speed you want to be able to look
private float _lookSpeed = 3f;
// Set the initial rotations to the rotation variables
private void Awake()
{
_playerRotation = transform.localRotation;
_cameraRotation = camera.transform.localRotation;
}
// Method to be called from LateUpdate
private void UpdateRotation()
{
Vector2 input = new Vector2(
Input.GetAxis("Mouse X"),
Input.GetAxis("Mouse Y")
);
if (input != Vector2.zero)
{
_playerRotation *= Quaternion.Euler(0f, _lookSpeed * input.x, 0f);
_cameraRotation *= Quaternion.Euler(_lookSpeed * -input.y, 0f, 0f);
_cameraRotation = ClampRotationAroundXAxis(_cameraRotation, -50f , 75f);
}
transform.localRotation = Quaternion.Slerp(transform.localRotation, _playerRotation, 10f * Time.deltaTime);
camera.transform.localRotation = Quaternion.Slerp(camera.transform.localRotation, _cameraRotation, 10f * Time.deltaTime);
}
// A couple of rotation methods
// I suggest making these extensions for use anywhere in the game and for all rotations
private Quaternion ClampRotationAroundXAxis(Quaternion q, float minX = 0f, float maxX = 0f)
{
if (q.w != 0f)
{
q.x /= q.w;
q.y /= q.w;
q.z /= q.w;
q.w = 1f;
}
q.y = 0f;
q.z = 0f;
if (minX != 0f || maxX != 0f)
{
q = ClampRotationXAxis(q, minX, maxX);
}
return q;
}
private Quaternion ClampRotationXAxis(Quaternion q, float min, float max)
{
if (q.w != 0f)
{
q.x /= q.w;
q.y /= q.w;
q.z /= q.w;
q.w = 1f;
}
float angle = 2f * Mathf.Rad2Deg * Mathf.Atan(q.x);
angle = Mathf.Clamp(angle, min, max);
q.x = Mathf.Tan(0.5f * Mathf.Deg2Rad * angle);
return q;
}
I developing an 6DOF game. I have some problems with the auto leveling (so the ship will always goes horizontal). The auto leveling worked, but I can't turn anymore on the x-axis more than 90 degrees. The spaceship must fly free in any direction. I hope someone can help me.
// Update is called once per frame
void Update()
{
yaw = Input.GetAxis("Mouse X") * speed;
pitch = Input.GetAxis("Mouse Y") * speed;
roll = Input.GetAxis("Roll") * speed;
float ver = 0;
float up = 0;
float hor = 0;
up = Input.GetAxis("Up");
hor = Input.GetAxis("Horizontal");
ver = Input.GetAxis("Vertical");
ver *= speed * Time.deltaTime;
up *= speed * Time.deltaTime;
hor *= speed * Time.deltaTime;
transform.Rotate(Vector3.up, yaw);
transform.Rotate(Vector3.left, pitch);
transform.Rotate(Vector3.forward, -roll);
Vector3 cross = Vector3.Cross(Vector3.up, transform.forward);
Quaternion rotator = Quaternion.FromToRotation(transform.right, cross)
// Apply rotation
transform.rotation = Quaternion.Slerp(transform.rotation, rotator * transform.rotation, Time.deltaTime);
transform.Translate(hor, up, ver);
}
As requested in comments (note: untested):
void Update() {
var yaw = Input.GetAxis("Mouse X");
var pitch = Input.GetAxis("Mouse Y");
var roll = Input.GetAxis("Roll");
var up = Input.GetAxis("Up"); // better name is 'heave' (up/down)
var hor = Input.GetAxis("Horizontal"); // better name is 'sway' (left/right)
var ver = Input.GetAxis("Vertical"); // better name is 'surge' (forward/back)
// If no rotation input, then 'auto-correct' for roll (up direction)
if ( Mathf.Approximately(yaw + pitch + roll, 0)) {
// Find what the 'up' rotation is
var levelRotation = Quaternion.LookRotation(transform.forward, Vector3.up);
// Apply it over time (Limit the angular change with Time.deltaTime)
transform.rotation = Quaternion.RotateTowards(transform.rotation, levelRotation, Speed * Time.deltaTime);
}
// Else there IS input rotation, so deal with that instead.
else {
// Scale inputs for speed (rotation speed should probably be different from translation speed)
yaw *= Speed * Time.deltaTime;
pitch *= Speed * Time.deltaTime;
roll *= Speed * Time.deltaTime;
var rotation = Quaternion.Euler(yaw, pitch, roll);
transform.rotation *= rotation;
}
// Acale and apply translation
ver *= speed * Time.deltaTime;
up *= speed * Time.deltaTime;
hor *= speed * Time.deltaTime;
transform.Translate(hor, up, ver);
}
I am going for a RuneScape-style camera that rotates around the player using WASD. Rotating horizontally works fine but when I mix the two (as in pitching up or down) the camera rotates around the player really awkwardly, the camera might invert or will sort of gimbal I guess.
Here's my code:
public float pitch;
public float zoomSpeed = 4f;
public float minZoom = 5f;
public float maxZoom = 15f;
public Transform target;
public Vector3 offset;
public float yawSpeed = 100f;
private float currentZoom = 10f;
private float currentYaw = 0f;
private float currentPitch = 0f;
void Update()
{
currentZoom -= Input.GetAxis("Mouse ScrollWheel") * zoomSpeed;
currentZoom = Mathf.Clamp(currentZoom, minZoom, maxZoom);
currentYaw -= Input.GetAxis("Horizontal") * yawSpeed * Time.deltaTime;
currentPitch -= Input.GetAxis("Vertical") * yawSpeed * Time.deltaTime;
Debug.Log("Yaw: " + currentYaw + " Pitch: " + currentPitch);
}
void LateUpdate()
{
transform.position = target.position - offset * currentZoom;
transform.LookAt(target.position + Vector3.up * pitch);
transform.RotateAround(target.position, Vector3.up, currentYaw);
transform.RotateAround(target.position, Vector3.forward, currentPitch);
}
Any help would be gladly appreciated!
It looks to me that you are using currentPitch, but rotating it around the forward axis? Which would create roll on the world foward axis?
If your up vector is always world up, then the yaw you have will work. But what you want to do is recalculate the right vector from your current location to your target after you apply the yaw.
void LateUpdate() {
transform.position = target.position - offset * currentZoom;
transform.LookAt(target.position + Vector3.up * pitch);
transform.RotateAround(target.position, Vector3.up, currentYaw);
transform.RotateAround(target.position, Vector3.Cross((target.position - transform.position).normalized, Vector3.up), currentPitch);
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseOrbit : MonoBehaviour {
public Transform target;
public float distance = 5.0f;
public float xSpeed = 120.0f;
public float ySpeed = 120.0f;
public float yMinLimit = -20f;
public float yMaxLimit = 80f;
public float distanceMin = .5f;
public float distanceMax = 15f;
private Rigidbody rigidbody;
float x = 0.0f;
float y = 0.0f;
float minFov = 15f;
float maxFov = 90f;
float sensitivity = 10f;
// Use this for initialization
void Start()
{
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
rigidbody = GetComponent<Rigidbody>();
// Make the rigid body not change rotation
if (rigidbody != null)
{
rigidbody.freezeRotation = true;
}
}
void Update()
{
// Updating camera distance on every frame
distance = RayCast3.distance3;
//Setting maximum distance so the camera doesnt go too far
if (distance > 2)
{
distance = 2;
}
}
void LateUpdate()
{
if (target)
{
x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(y, x, 0);
//distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
//distance += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
float fov = Camera.main.fieldOfView;
fov += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
fov = Mathf.Clamp(fov, minFov, maxFov);
Camera.main.fieldOfView = fov;
RaycastHit hit;
if (Physics.Linecast(target.position, transform.position, out hit))
{
distance -= hit.distance;
}
Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * negDistance + target.position;
transform.rotation = rotation;
transform.position = position;
}
}
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360F)
angle += 360F;
if (angle > 360F)
angle -= 360F;
return Mathf.Clamp(angle, min, max);
}
}
Now i'm using fov:
And it's working fine.
float fov = Camera.main.fieldOfView;
fov += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
fov = Mathf.Clamp(fov, minFov, maxFov);
Camera.main.fieldOfView = fov;
But now i want to use the distance variable and not fov.
So i tried first the line:
distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
It didn't work so i tried the line:
distance += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
But in both lines the character is stuttering and it's not zooming in out with the mouse wheel.
It's really simple. Get mouse scroll wheel speed then multiply it by some speed value. You can also multiply it by Time.deltaTime if you want. Finally use transform.Translate to move the camera with that value.
This will move in z-axis:
private float zoomSpeed = 2.0f;
void Update()
{
float scroll = Input.GetAxis("Mouse ScrollWheel");
transform.Translate(0, 0, scroll * zoomSpeed, Space.World);
}
Or where camera is facing:
private float zoomSpeed = 5.0f;
void Update()
{
float scroll = Input.GetAxis("Mouse ScrollWheel");
transform.position += this.transform.forward * scroll * zoomSpeed;
}
You should calculate a delta between your camera point and your target point. Normalize it and multiply it with the scrollwheel delta. Add this on your camera position. I used the camera target as angle to zoom-in.
Pseudo:
var delta = cameraTarget - cameraPosition;
delta.Normalize();
cameraPosition += delta * ScrollWheel.delta * sensitivity;
// you can even move your cameraTarget in the same direction
cameraTarget += delta * ScrollWheel.delta * sensitivity;
You can use the distance instead of calculating a delta.
I am starting a new game and right now my player can view 360* but I want to limit how far the player looks up in the sky and down (straight up and down).
Here's my code
Vector2 mouseLook;
Vector2 smoothV;
public float sensitivity = 5.0f;
public float smoothing = 2.0f;
GameObject player;
void Start () {
player = this.transform.parent.gameObject;
}
// Update is called once per frame
void Update () {
var md = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
md = Vector2.Scale(md, new Vector2(sensitivity * smoothing, sensitivity * smoothing));
smoothV.x = Mathf.Lerp(smoothV.x, md.x, 1f / smoothing);
smoothV.y = Mathf.Lerp(smoothV.y, md.y, 1f / smoothing);
mouseLook += smoothV;
transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);
player.transform.localRotation = Quaternion.AngleAxis(mouseLook.x, player.transform.up);
}
}
You have to use Mathf.Clamp to do this. Below is what I use to rotate the camera up/down and left/right. You can modify the yMaxLimit and yMinLimit variables to the angles you want to limit it to. There should be no limit while moving in the x direction.
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;
Transform player;
void Start()
{
player = Camera.main.transform;
}
// 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);
//xRotCounter = xRotCounter % 360;//Optional
player.localEulerAngles = new Vector3(-yRotCounter, xRotCounter, 0);
}