How can I lock the rotation of a player in Unity?

3.1k views Asked by At

I'm currently making a 2D game as a beginner and I made a spinning platform. But when it's rotating the player's rotation (z-axis) also changes because it's a child of the platform. I need this when I use moving platforms. Now I want to lock the z-axis of the rotation of the player. I already tried it in 3 different ways, but none of them seems to be working. Does anybody know how to do this?

These are the three ways I tried:

// 1
PlayerTrans.transform.Rotate(
    PlayerTrans.transform.rotation.x, 
    PlayerTrans.transform.rotation.y, 
    0);

// 2
PlayerTrans.transform.Rotate(
    PlayerTrans.transform.rotation.x, 
    PlayerTrans.transform.rotation.y, 
    0, 
    Space.Self);

// 3
PlayerTrans.transform.localRotation = Quaternion.Euler(new Vector3(
    PlayerTrans.transform.localEulerAngles.x, 
    PlayerTrans.transform.localEulerAngles.y, 
    0f));

and this is, what my code looks like for staying on the moving platforms. I used raycasting for this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Raycasting : MonoBehaviour
{
    // Start is called before the first frame update
    Transform PlayerTrans;
    public float RayCastRange = 3;
    void Start()
    {
        PlayerTrans = transform.parent;
    }

    // Update is called once per frame
    void Update()
    {
        RaycastHit2D PlattformCheck = Physics2D.Raycast(transform.position, -Vector2.up, RayCastRange);

        if (PlattformCheck.collider != null)
        {
            if (PlattformCheck.collider.gameObject.tag == "Platform")
            {
                PlayerTrans.transform.SetParent(PlattformCheck.collider.gameObject.transform);
            }
            else
            {
                PlayerTrans.transform.SetParent(null);
            }
        }
        else
        {
            PlayerTrans.transform.SetParent(null);
        }
    }
}
2

There are 2 answers

0
gbe On

You should raycast directly down and then apply velocities to both objects (un-child the player from the platforms). You could do something like this for the player:

public LayerMask mask; //set ‘mask’ to the mask of the
//platform in the Unity Editor.
public Vector3 velocity;

void Update()
{
  RaycastHit hit;
  if (Physics.Raycast(transform.position, -Vector3.up, out hit, 0.1f, mask))
  //0.1f is the distance to the platform to be able to be moved by the platform.
  {
    velocity = hit.collider.gameObject.GetComponent<Platform>().velocity;
  }
  float h = Input.GetAxis(“Horizontal”);
  //this one is for CharacterController:
  cc.Move(velocity);
  //this one is for rigidbody:
  rb.velocity = velocity;
  velocity = 0;
}

It takes the velocity from the ‘Platform’ script and moves the player based on it. Now we should add the platform script. Call it ‘Platform’.

public Vector3 velocity;
public Vector3 a; //a and b are the two points you want the platform to go between.
public Vector3 b;

public float period = 2f; //the amount of seconds per cycle.
float cycles;

void Update()
{
  cycles = Time.time / period;
  float amplitude = Mathf.Sin(Mathf.PI * 2f * cycles);
  Vector3 location = Vector3.Lerp(a, b, amplitude);
  velocity = transform.position - location;
  transform.position = velocity;
}

This script interpolates between the point a and b, then it finds the velocity and applies it. The player takes this velocity and it moves the player. Comment if you found an error.

0
amitklein On

There are 2 ways that might help you:

  1. Just freeze the rotation from the inspector:

enter image description here

  1. you can use some LookAt function (there is one for 3D but you can look and find ones for 2D) and just look at the camera.

(if you cant find it let me know and I will add it)