Auto leveling 6DOF Unity - c#

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);
}

Related

Add offset without value increasing

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);
}

Why the object is moving the opposite direction when decreasing the movement speed value?

float distance1 = Vector3.Distance(transform.position, target.position);
if(distance1 < 10)
{
movementSpeed -= 0.01f;
}
transform.position = Vector3.MoveTowards(transform.position, target.position, Time.deltaTime * movementSpeed);
If for example I did it this way it will increase the movement speed slowly :
movementSpeed += Time.deltaTime * 0.01f;
transform.position = Vector3.MoveTowards(transform.position, destinationTransform.position, Time.deltaTime * movementSpeed);
but i want the object to slowly decrease the movement speed down when getting close to the target.
when i'm changing it to -= the object is moving backward.

Unity 3D - How to use LateUpdate in Mouselook script?

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;
}

Have camera follow player -object position and rotation in 3D-space (Unity3d)

My objective here is to have a smoothed out "follow camera", for my space-fighter proof of concept game. The camera should match roll off the target object in all axis.
To that end I've "stolen" and modified this code from the unity Answers-site, and it works beautifully for X and Y (pitch and yaw), but it refuses to roll.
Code:
public float Distance;
public float Height;
public float RotationDamping;
public GameObject Target;
void LateUpdate()
{
var wantedRotationAngleYaw = Target.transform.eulerAngles.y;
var currentRotationAngleYaw = transform.eulerAngles.y;
var wantedRotationAnglePitch = Target.transform.eulerAngles.x;
var currentRotationAnglePitch = transform.eulerAngles.x;
var wantedRotationAngleRoll = Target.transform.eulerAngles.z;
var currentRotationAngleRoll = transform.eulerAngles.z;
currentRotationAngleYaw = Mathf.LerpAngle(currentRotationAngleYaw, wantedRotationAngleYaw, RotationDamping * Time.deltaTime);
currentRotationAnglePitch = Mathf.LerpAngle(currentRotationAnglePitch, wantedRotationAnglePitch, RotationDamping * Time.deltaTime);
currentRotationAngleRoll = Mathf.LerpAngle(currentRotationAngleRoll, wantedRotationAngleRoll, RotationDamping * Time.deltaTime);
var currentRotation = Quaternion.Euler(currentRotationAnglePitch, currentRotationAngleYaw, currentRotationAngleRoll);
transform.position = Target.transform.position;
transform.position -= currentRotation * Vector3.forward * Distance;
transform.LookAt(Target.transform);
transform.position += transform.up * Height;
}
Image:
I would be more certain about this answer if you explained what you were trying to do, but you should consider moving by Height in the direction of currentRotation * Vector3.up instead of transform.up. Also, consider using currentRotation * Vector3.up to set the local up direction when calling LookAt:
transform.position = Target.transform.position;
transform.position -= currentRotation * Vector3.forward * Distance;
Vector3 currentUp = currentRotation * Vector3.up;
transform.LookAt(Target.transform, currentUp);
transform.position += currentUp * Height;

unity rotate object on x-axis when moving mouse up / down

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);
}

Categories

Resources