Unity Mouselook from any Player Orientation - unity3d

I am working on a first person game where the character is able to latch on to any flat surface and walk on it (kind of like moon boots). I am having issues with the camera since most implementations of mouse look I have been able to find depend on the player being oriented straight up and down in the world, so as soon as my "flipping" animation (the player orienting to the new surface) has finished, the camera will instantly flip back to straight up and down as defined by the world. What I need is a way to implement mouse look so that it does not reset the rotation after my animation. I am currently using:
transform.Rotate(-Input.getAxis("Mouse Y") turnSpeed Time.deltaTime, Input.getAxis("Mouse X") turnSpeed Time.deltaTime, 0);
in order to perform my mouse look rotations while avoiding the standard method, but this is clearly incorrect since I get some weird rotations when turning the camera horizontally. Is there a better way to implement mouse look so that it works correctly regardless of the orientation of the player?

You can plance camera inside player Transform and add this script to player:
public class MouseLook : MonoBehaviour {
[SerializeField]
Camera Camera;
[Range(10f,50f)]
public float Speed = 30;
void Update () {
transform.rotation = Quaternion.AngleAxis(Input.GetAxis("Mouse X") * speed * Time.deltaTime, transform.rotation * Vector3.up)*transform.rotation;
Camera.transform.rotation = Quaternion.AngleAxis(-Input.GetAxis("Mouse Y") * Speed * Time.deltaTime, Camera.transform.rotation * Vector3.right)* Camera.transform.rotation;
}
}
You add reference to Camera in inspector. You will have to check not to rotate above +/- 90 degrees on camera to avoid over rotating to back. If you will have issue with that I will help you.

Related

my camera doesn't follow the player when i say start the game

I'm trying to make a simple hyper casual. I couldn't understand what's wrong with my codes.
My code:
public class CameraFollow : MonoBehaviour
{
public Transform Target;
public Vector3 offset;
void LateUptade()
{
transform.position = Vector3.Lerp(transform.position, Target.position + offset, Time.deltaTime * 2);
}
}
Two Things to note in your code.
Its LateUpdate and not LateUptade.
In lerp If the third input is 1 the camera will instantly jump to target+offset and if you want the camera to move slowly from its position to target+offse then you need to increase the value of the third input from 0 to 1 every frame.
You can also use Cinemachine to make camera follow player. Check out this Camera follow player tutorial for different ways to make the camera follow player.
Do not put Time.deltaTime in Lerp. The lazy solution is to simply write a constant that is between 0 and 1.
Additionally there is a typo in the function name. It should be LateUpdate and not LateUptade.
transform.position = Vector3.Lerp(transform.position, Target.position + offset, 0.3f);

How do I rotate a 3d player by Y-axis behind a mouse?

please tell me how I make the player spin behind the mouse. That is, to be always pointed at the mouse. I tried to do it, but it only worked that way, but in this version it just moves the mouse, but is not directed at it
private void RotatePlayer()
{
transform.rotation = Quaternion.AngleAxis(transform.eulerAngles.y + Input.GetAxis("Mouse X") * _rotationSpeed, Vector3.up);
}

Unity / Mirror - Is there a way to keep my camera independent from the player object's prefab after start?

I'm currently trying to create a multiplayer game using mirror!
So far I've been successful in creating a lobby and set up a simple character model with a player locomotion script I've taken and learnt inside out from Sebastian Graves on YouTube (you may know him as the dark souls III tutorial guy)
This player locomotion script uses unity's package 'Input System' and is also dependent on using the camera's .forward and .right directions to determine where the player moves and rotates instead of using forces on the rigidbody. This means you actually need the camera free in the scene and unparented from the player.
Here is my HandleRotation() function for rotating my character (not the camera's rotation function):
private void HandleRotation()
{
// target direction is the way we want our player to rotate and move // setting it to 0
Vector3 targetDirection = Vector3.zero;
targetDirection = cameraManager.cameraTransform.forward * inputHandler.verticalInput;
targetDirection += cameraManager.cameraTransform.right * inputHandler.horizontalInput;
targetDirection.Normalize();
targetDirection.y = 0;
if (targetDirection == Vector3.zero)
{
// keep our rotation facing the way we stopped
targetDirection = transform.forward;
}
// Quaternion's are used to calculate rotations
// Look towards our target direction
Quaternion targetRotation = Quaternion.LookRotation(targetDirection);
// Slerp = rotation between current rotation and target rotation by the speed you want to rotate * constant time regardless of framerates
Quaternion playerRotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
transform.rotation = playerRotation;
}
It's also worth mentioning I'm not using cinemachine however I'm open to learning cinemachine as it may be beneficial in the future.
However, from what I've learnt and managed to find about mirror is that you have to parent the Main Camera under your player object's prefab so that when multiple people load in, multiple camera's are created. This has to happen on a Start() function or similar like OnStartLocalPlayer().
public override void OnStartLocalPlayer()
{
if (mainCam != null)
{
// configure and make camera a child of player
mainCam.orthographic = false;
mainCam.transform.SetParent(cameraPivotTransform);
mainCam.transform.localPosition = new Vector3(0f, 0f, -3f);
mainCam.transform.localEulerAngles = new Vector3(0f, 0f, 0f);
cameraTransform = GetComponentInChildren<Camera>().transform;
defaultPosition = cameraTransform.localPosition.z;
}
}
But of course, that means that the camera is no longer independent to the player and so what ends up happening is the camera rotates when the player rotates.
E.g. if I'm in game and looking to the right of my player model and then press 'w' to walk in the direction the camera is facing, my camera will spin with the player keeping the same rotation while my player spins in order to try and walk in the direction the camera is facing.
What my question here would be: Is there a way to create a system using mirror that doesn't require the camera to be parented to the player object prefab on start, and INSTEAD works by keeping it independent in the scene?
(I understand that using forces on a rigidbody is another method of creating a player locomotion script however I would like to avoid that if possible)
If anybody can help that would be greatly appreciated, Thank You! =]
With the constraint of your camera being attached to the player you will have to adapt the camera logic. What you can do is instantiate a proxy transform for the camera and copy that transforms properties to your camera, globally, every frame. The parent constraint component might do this for you. Then do all your transformations on that proxy.
Camera script with instantiation:
Transform proxy;
void Start(){
proxy = (new GameObject()).transform;
}
void Update(){
//transformations on proxy
transform.position = proxy.position;
transform.rotation = proxy.rotation;
}

Camera Shake Effect When Camera Following Player

I was working on a 3d game where the camera is continuously following the player object.
Now when a bomb hits the player object I want to play camera shake with blast particle effect.
I have coded this for camera shake:
public IEnumerator PlayCameraShakeAnimation(float duration, float magnitude)
{
Vector3 originalPosition = transform.localPosition;
float elapsedTime = 0f;
while(elapsedTime < duration)
{
float x = Random.Range(-1f, 1f) * magnitude;
float y = Random.Range(-1f, 1f) * magnitude;
transform.localPosition = new Vector3(x, y,originalPosition.z);
elapsedTime += Time.deltaTime;
yield return null;
}
transform.localPosition = originalPosition;
}
Camera Follow is the normal script I have written to follow the player.
Because of Camera Follow script is running, camera shake effect we can't able to show in the screen.
If I turn off Camera Follow script then we can able to see clearly camera shaking otherwise not.
If I turn off Camera Follow script for a small amount of time then I am losing smoothness in following of player because the player position gets updated after the blast. So when I start back following the player, it will get a high jerk in a movement to reach a target position.
Also, the Camera is following the player in position and rotation in both fields. Now provide me some suggestions to achieve the Camera Shake effect while following the player.
This is actually quite simple:
Separate it into two GameObjects:
parentObject
|--Camera
parentObject follows player.
Camera does the shaking in localPosition &rightarrow; relative to parentObject
Result: While parentObject follows the player the Camera is automatically moved along with it. No need to turn anything on and of ;)

Unity approach an object in spiral motion

In Unity I can handle circular motion around an object with a simple
transform.RotateAround(GameObject.Find("CubeTest").transform.position, Vector3.up, 20000*Time.deltaTime);
However, I want the object traveling in circular motion to approach this object whilst in orbit. Not entirely sure how to do this without screwing up.
GameObject cube = GameObject.Find("CubeTest");
transform.LookAt(cube.transform);
transform.Translate(transform.forward * Time.deltaTime * approachSpeed);
transform.RotateAround(cube.transform.position, Vector3.up,20000*Time.deltaTime);
I think that could do as you want? It moves towards the rotation point gradually, then rotates, giving the appearance of a deteriorating orbit.
If you came here looking for working 2D solution here you are.
From this blog post. I built this configurable script:
public class SpiralMovement : MonoBehaviour
{
[SerializeField] Transform moveable;
[SerializeField] public Transform destiny;
[SerializeField] float speed;
// As higher as smoother approach, but it can not be more than 90, or it will start getting away.
[SerializeField][Range(0f, 89f)] float angle = 60f;
void Update()
{
Vector3 direction = destiny.position - moveable.position;
direction = Quaternion.Euler(0, 0, angle) * direction;
float distanceThisFrame = speed * Time.deltaTime;
moveable.transform.Translate(direction.normalized * distanceThisFrame, Space.World);
}
}