How to freeze the rotation of a Rigidbody2D within scripts? - c#

I am trying to make a 2d platformer, but lets say that if the character collides with any object, then it just rotates. Is there a way to set the rotation to 0? or keep it on 0?
Ive tried making the box collider far wider, it made my character alteast not fall after moving right/left, but thats not enough. It just falls over if there are any objects colliding with it, unless its taller than him.
Heres the code i try to use:
using System.Collections;
public class PlayerController : MonoBehaviour
{
//Movement
public float speed;
public float jump;
float moveVelocity;
//Grounded Vars
bool grounded = true;
void Update ()
{
//Jumping
if (Input.GetKeyDown (KeyCode.Space) || Input.GetKeyDown (KeyCode.UpArrow) || Input.GetKeyDown (KeyCode.Z) || Input.GetKeyDown (KeyCode.W))
{
if(grounded)
{
GetComponent<Rigidbody2D> ().velocity = new Vector2 (GetComponent<Rigidbody2D> ().velocity.x, jump);
}
}
moveVelocity = 0;
//Left Right Movement
if (Input.GetKey (KeyCode.LeftArrow) || Input.GetKey (KeyCode.A))
{
moveVelocity = -speed;
}
if (Input.GetKey (KeyCode.RightArrow) || Input.GetKey (KeyCode.D))
{
moveVelocity = speed;
}
GetComponent<Rigidbody2D> ().velocity = new Vector2 (moveVelocity, GetComponent<Rigidbody2D> ().velocity.y);
}
//Check if Grounded
void OnTriggerEnter2D()
{
grounded = true;
}
void OnTriggerExit2D()
{
grounded = false;
}
}```

You are looking for Rigidbody2D.freezeRotation.

Related

Unity2D Jump doesn't work for unknown reasons

I am going back into game devloppment after a few months and, while I was making a respawn trigger (that doesn't work), my jump stopped working for no reasons. I didn't modified the code (I think). I followed a tutorial for the code. Please not that I am using the unity new input system and that my game is a 2D GAME Also, there is no errors shown in the logs, the problem is that when I press my jump key, it does nothing. I tried putting Debug.Log("Should Jump"); in the jump code to see if the Rigidbody2D was the problem but it still didn't worked (nothing showed up in the logs). I also verified that my floor was in the Ground layer and it was. I don't see the problem.
My code is the following:
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
[SerializeField] float speed;
[SerializeField] Transform groundCheck;
[SerializeField] LayerMask groundLayer;
bool facingRight = true;
PlayerInput playerInput;
bool isGrounded;
float groundTimer = 1f;
float airTimer;
void Start()
{
playerInput = GetComponent<PlayerInput>();
}
void Update()
{
Movement();
isGround();
}
void isGround()
{
if (Physics2D.OverlapCircle(groundCheck.position, 0.05f, groundLayer) && airTimer <- 0)
{
groundTimer = 0.15f;
isGrounded = true;
}
if (airTimer > 0)
{
airTimer -= Time.deltaTime;
}
else
{
if (groundTimer < 0)
isGrounded = false;
else
groundTimer -= Time.deltaTime;
}
}
void Movement()
{
transform.Translate(Mathf.Abs(playerInput.actions["Horizontal"].ReadValue<float>()) * speed * Time.deltaTime, 0, 0);
//if (playerInput.actions["Jump"].triggered)
if (playerInput.actions["Jump"].triggered && isGrounded && airTimer <- 0)
{
GetComponent<Rigidbody2D>().velocity = Vector2.zero;
GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 10), ForceMode2D.Impulse);
Debug.Log("Should Jump");
isGrounded = false;
airTimer = 0.06f;
}
//Just flipping
}
//More flipping
}
Help...
(It's late for me so, if you ask a question, I will probably not anwser (22:52 EST 19 June 2022))

How do I make a GameObject move towards another GameObject but stay within collider bounds of another GameObject?

I'm working on a Boss for my game, here's an image:
The selected collider is attached to the Pupil of the Eye of the boss, here's a pic of both colliders showing:
I also have a Player Objec.
The Boss is a floating All Seeing Eye that always moves towards the player.
What I'm trying to do is make the Pupil move separately from the Boss while still staying within the collider bounds I've made, and always move towards the player to give the illusion that the eye is always looking at the player. I tried using Vector2.MoveTowards() but it didn't work.
How might I solve this problem? Help would be appreciated thanks
Here's the current script attached to the Boss Object:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AllSeeingEyeController : MonoBehaviour
{
[SerializeField] private float moveSpeed = 5f;
[SerializeField] private GameObject myEye; // Accesses the Pupil GameObject of the Boss
private Transform player;
private bool spawningEyeballs = false;
private Rigidbody2D rb;
private Rigidbody2D myEyeRb; // Acesses the Pupil's rigidbidy2d, since that's how I think it should move
void Start()
{
player = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
rb = GetComponent<Rigidbody2D>();
myEyeRb = myEye.GetComponent<Rigidbody2D>();
}
void Update()
{
if (!spawningEyeballs) {
ChasePlayer();
} else {
rb.velocity = Vector2.zero;
}
}
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.CompareTag("Player")) {
DedaController2D main = other.gameObject.GetComponent<DedaController2D>();
main.knockbackCount = main.knockbackLength; //Activates Knockback
if (transform.position.x > other.transform.position.x) { //Player is Left of Enemy, Enemy knocks from Right
main.knockFromRight = true;
main.knockUpwards = true;
} else { //Player is Right of Enemy, Enemy knocks from Left
main.knockFromRight = false;
main.knockUpwards = true;
}
}
}
void ChasePlayer()
{
if (transform.position.x < player.position.x) { //Player is Right of Enemy, Enemy goes Right
rb.velocity = new Vector2(moveSpeed, rb.velocity.y);
transform.localScale = new Vector2(-1, 1);
} else if (transform.position.x > player.position.x){ //Player is Left of Enemy, Enemy goes Left
rb.velocity = new Vector2(-moveSpeed, rb.velocity.y);
transform.localScale = new Vector2(1, 1);
} else {
rb.velocity = new Vector2(0, rb.velocity.y);
}
if (transform.position.y < player.position.y) { //Player is Above Enemy, Enemy goes Up
rb.velocity = new Vector2(rb.velocity.x, moveSpeed / 2);
} else if (transform.position.y > player.position.y) { //Player is Below Enemy, Enemy goes Down
rb.velocity = new Vector2(rb.velocity.x, -moveSpeed / 2);
} else {
rb.velocity = new Vector2(rb.velocity.x, 0);
}
}
}

I animated my 2D game but my character doesn't move

I've been following Brackeys tutorials to make a 2D game and right now I'm on animation. The animation plays he attacks, the sprite flips both directions, etc.. but still stuck in the same spot. I've watched and rewatched the tutorial and can't figure it out.
Before adding animation everything worked perfectly. He moved across the screen, he jumped, etc.. So i know that him not moving is directly tied to trying to animating
This is my playermovement script I made from following his tutorial.
public class playermovement : MonoBehaviour
{
public CharacterController2D controller;
public Animator animator;
public float runSpeed = 40f;
float horizontalMove = 0f;
bool jump = false;
bool Attack = false;
void Update()
{
horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed;
animator.SetFloat("Speed", Mathf.Abs(horizontalMove));
if (Input.GetButtonDown("Jump"))
{
jump = true;
animator.SetBool("IsJumping", true);
}
if (Input.GetKeyDown(KeyCode.Mouse0))
{
animator.SetBool("Attack", true);
Attack = false;
}
}
public void OnLanding ()
{
animator.SetBool("IsJumping", false);
}
private void FixedUpdate()
{
controller.Move(horizontalMove * Time.fixedDeltaTime, false, jump);
jump = false;
}
}
This is my character controller
public class CharacterController2D : MonoBehaviour
{
[SerializeField] private float m_JumpForce = 400f; // Amount of force added when the player jumps.
[Range(0, 1)] [SerializeField] private float m_CrouchSpeed = .36f; // Amount of maxSpeed applied to crouching movement. 1 = 100%
[Range(0, .3f)] [SerializeField] private float m_MovementSmoothing = .05f; // How much to smooth out the movement
[SerializeField] private bool m_AirControl = false; // Whether or not a player can steer while jumping;
[SerializeField] private LayerMask m_WhatIsGround; // A mask determining what is ground to the character
[SerializeField] private Transform m_GroundCheck; // A position marking where to check if the player is grounded.
[SerializeField] private Transform m_CeilingCheck; // A position marking where to check for ceilings
[SerializeField] private Collider2D m_CrouchDisableCollider; // A collider that will be disabled when crouching
const float k_GroundedRadius = .2f; // Radius of the overlap circle to determine if grounded
private bool m_Grounded; // Whether or not the player is grounded.
const float k_CeilingRadius = .2f; // Radius of the overlap circle to determine if the player can stand up
private Rigidbody2D m_Rigidbody2D;
private bool m_FacingRight = true; // For determining which way the player is currently facing.
private Vector3 m_Velocity = Vector3.zero;
[Header("Events")]
[Space]
public UnityEvent OnLandEvent;
[System.Serializable]
public class BoolEvent : UnityEvent<bool> { }
public BoolEvent OnCrouchEvent;
private bool m_wasCrouching = false;
private void Awake()
{
m_Rigidbody2D = GetComponent<Rigidbody2D>();
if (OnLandEvent == null)
OnLandEvent = new UnityEvent();
if (OnCrouchEvent == null)
OnCrouchEvent = new BoolEvent();
}
private void FixedUpdate()
{
bool wasGrounded = m_Grounded;
m_Grounded = false;
// The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
// This can be done using layers instead but Sample Assets will not overwrite your project settings.
Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround);
for (int i = 0; i < colliders.Length; i++)
{
if (colliders[i].gameObject != gameObject)
{
m_Grounded = true;
if (!wasGrounded)
OnLandEvent.Invoke();
}
}
}
public void Move(float move, bool crouch, bool jump)
{
// If crouching, check to see if the character can stand up
if (!crouch)
{
// If the character has a ceiling preventing them from standing up, keep them crouching
if (Physics2D.OverlapCircle(m_CeilingCheck.position, k_CeilingRadius, m_WhatIsGround))
{
crouch = true;
}
}
//only control the player if grounded or airControl is turned on
if (m_Grounded || m_AirControl)
{
// If crouching
if (crouch)
{
if (!m_wasCrouching)
{
m_wasCrouching = true;
OnCrouchEvent.Invoke(true);
}
// Reduce the speed by the crouchSpeed multiplier
move *= m_CrouchSpeed;
// Disable one of the colliders when crouching
if (m_CrouchDisableCollider != null)
m_CrouchDisableCollider.enabled = false;
} else
{
// Enable the collider when not crouching
if (m_CrouchDisableCollider != null)
m_CrouchDisableCollider.enabled = true;
if (m_wasCrouching)
{
m_wasCrouching = false;
OnCrouchEvent.Invoke(false);
}
}
// Move the character by finding the target velocity
Vector3 targetVelocity = new Vector2(move * 10f, m_Rigidbody2D.velocity.y);
// And then smoothing it out and applying it to the character
m_Rigidbody2D.velocity = Vector3.SmoothDamp(m_Rigidbody2D.velocity, targetVelocity, ref m_Velocity, m_MovementSmoothing);
// If the input is moving the player right and the player is facing left...
if (move < 0 && !m_FacingRight)
{
// ... flip the player.
Flip();
}
// Otherwise if the input is moving the player left and the player is facing right...
else if (move > 0 && m_FacingRight)
{
// ... flip the player.
Flip();
}
}
// If the player should jump...
if (m_Grounded && jump)
{
// Add a vertical force to the player.
m_Grounded = false;
m_Rigidbody2D.AddForce(new Vector2(0f, m_JumpForce));
}
}
private void Flip()
{
// Switch the way the player is labelled as facing.
m_FacingRight = !m_FacingRight;
// Multiply the player's x local scale by -1.
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
private void OnCollisionEnter2D(Collision2D collision)
{
if(collision.gameObject.tag == "Enemy")
{
Destroy(collision.gameObject);
}
}
}
It's probably a bit late to help the OP now, but I had exactly the same issue today and finally figured it out.
I was scaling the main object for some of my animations. To fix it I went in and removed any scaling of the main container object and instead scaled the internal objects individually and now the flipping works.
Clearly the animation scaling interferes with the controller flip scaling.
Try This Code but make shure you Character has a 2DRigidbody and a 2DBoxcollider and watch out that the script has the name "Character2DController"
I hope it will help you ;)
using UnityEngine;
public class Character2DController : MonoBehaviour
{
public float MovementSpeed = 1;
public float JumpForce = 1;
public Animator animator;
private bool facingRight;
private Rigidbody2D _rigidbody;
void Start()
{
facingRight = true;
_rigidbody = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetAxis("Horizontal") < 0)
{
transform.localScale = new Vector2 (-1.5f, transform.localScale.y);
}
if (Input.GetAxis("Horizontal") > 0)
{
transform.localScale = new Vector2(1.5f, transform.localScale.y);
}
var movement = Input.GetAxis("Horizontal");
transform.position += new Vector3(movement, 0, 0) * Time.deltaTime * MovementSpeed;
animator.SetFloat("Movement Speed", Mathf.Abs(movement));
{
}
if ((Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.W) || Input.GetButtonDown("Jump")) && Mathf.Abs(_rigidbody.velocity.y) < 0.001f)
{
_rigidbody.AddForce(new Vector2(0, JumpForce), ForceMode2D.Impulse);
}
}`enter code here`
}
You may check the values from horizontalMove while debugging or add a Debug.Log statement to check its value while testing, just to make sure that the value is what is expected.
Also ensure that controller was assigned.

Any way of moving my player other then the controller script teleports

I'm trying to make a spring wall in my 2d platformer. However every way I've tried to move my character (addforce, transform.translate and even tried using the bouncy naterial) teleports my character rather then moving it. This doesn't happen with my controller script. I suspect something in my script is causing this interaction but I'm not sure exactly what. Here is my controller script. Any suggestions would be greatly appreciated :))
using UnityEngine;
using System.Collections;
public class controller : MonoBehaviour
{
//how fast he can go
public float topSpeed = 15f;
bool facingRight = true;
//what direction character is facing
bool grounded = false;
//check if the character is grounded
public Transform groundCheck;
//the transform is used to see if character has touched the ground yet
float groundRadius = 0.2f;
//creates a ground radius for the transform circle for ground detection
GameObject Player, Player2;
int characterselect;
//I'm pretty sure this stuff ^^ is unnessecary and is from when I had the character switch in this script but dont want to remove just in case
public float jumpForce = 700f;
//the characters jumpforce
public GameObject jumpParticles;
public LayerMask whatIsGround;
//what layer is the ground
void Start()
{
characterselect = 1;
Player = GameObject.Find("Player");
Player2 = GameObject.Find("Player2");
//loads game objects as variables I'm pretty sure this stuff ^^^^ is unnessecary and is from when I had the character switch in this script but dont want to remove just in case
}
void FixedUpdate()
{
//has the transform hit the ground yet returns a true or false value
grounded = Physics2D.OverlapCircle(groundCheck.position, groundRadius, whatIsGround);
// get direction
float move = Input.GetAxis("Horizontal");
//add velocity to the move direction times by the speed
GetComponent<Rigidbody2D>().velocity = new Vector2(move * topSpeed, GetComponent<Rigidbody2D>().velocity.y);
if (move > 0 && !facingRight) //if facing not right then use the flip function
flip();
else if (move < 0 && facingRight)
flip();
//the whole flip turned out not to be nesseary as my sprites were symetric
}
void Update()
{
//if the character is in fact touching the ground then when space is pressed the function will run
if(grounded&& Input.GetKeyDown(KeyCode.Space))
{
//adds the jump force to the rigidbody attached to the character
GetComponent<Rigidbody2D>().AddForce(new Vector2(0, jumpForce));
//Instantiate(jumpParticles, transform.position, transform.rotation);
//Destroy(jumpParticles, 3f);
}
{
//this was code I was working on for character switching but couldn't get it to work properly. I didn't delete it because it took me ages to do and was recycled in the characterswitch script
// if (Input.GetKeyDown(KeyCode.E))
// {
// if (characterselect==1)
// {
// characterselect = 2;
// }
// else if (characterselect==2)
// {
// characterselect = 1;
// }
// }
// if (characterselect==1)
// {
// Player.SetActive(true);
// Player2.SetActive(false);
// }
// else if (characterselect==2)
// {
// Player.SetActive(false);
// Player2.SetActive(true);
// }
}
if (Input.GetKeyDown(KeyCode.LeftShift))
{
topSpeed = topSpeed * 2;
}
else if (Input.GetKeyUp(KeyCode.LeftShift))
{
topSpeed = 15;
}
}
void flip()
{
//for when facing the other direction
facingRight = ! facingRight;
//load the local scale
Vector3 theScale = transform.localScale;
//flip character on the x axis
theScale.x *= -1;
//and then apply it to the local scale
transform.localScale = theScale;
}
Edit
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class boost : MonoBehaviour {
private Rigidbody2D rb2d;
// Use this for initialization
void OnCollisionEnter2D(Collision2D other){
if (other.gameObject.tag == "booster") {
Vector2 tempvect = new Vector2 (2, 0);
rb2d.MovePosition ((Vector2)transform.position + tempvect);
}
}
void Start () {
rb2d = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update () {
}
}
This is the code that I think should make it work the error comes at
rb2d.MovePosition ((Vector2)transform.position + tempvect);

Unity Click on 1 object to trigger another object

Please keep in mind that I'm new to Unity. I have 2 script that I want to "combline" but when I try then it don't Work.
I have a Script (Name : RobotController). This script controls the movement of the player. Up/Jump, Down, Left and Right. (This Works with Keyboard keys only atm)
This script Works just fine but now I want to add the feature of touch keys for phone. With this I mean that if a person click on the "up-Arrow" the player shall jump.
The Up-Arrow is an object.
This is were I get my problem. I have created the Up-Arrow with a collider and a script.
Up-Arrow script:
public class NewJumpScript : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnMouseOver()
{
if ((Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began) || (Input.GetMouseButtonDown(0)))
{
Debug.Log("test");
}
}
}
Here is the RobotController script´, with ground check and so on.
public class RobotController : MonoBehaviour {
//This will be our maximum speed as we will always be multiplying by 1
public float maxSpeed = 2f;
public GameObject player;
public GameObject sprite;
//a boolean value to represent whether we are facing left or not
bool facingLeft = true;
//a value to represent our Animator
Animator anim;
//to check ground and to have a jumpforce we can change in the editor
bool grounded = true;
public Transform groundCheck;
public float groundRadius = 1f;
public LayerMask whatIsGround;
public float jumpForce = 300f;
private bool isOnGround = false;
void OnCollisionEnter2D(Collision2D collision) {
isOnGround = true;
}
void OnCollisionExit2D(Collision2D collision) {
anim.SetBool ("Ground", grounded);
anim.SetFloat ("vSpeed", rigidbody2D.velocity.y);
isOnGround = false;
}
// Use this for initialization
void Start () {
player = GameObject.Find("player");
//set anim to our animator
anim = GetComponent <Animator>();
}
void FixedUpdate () {
//set our vSpeed
//set our grounded bool
grounded = Physics2D.OverlapCircle (groundCheck.position, groundRadius, whatIsGround);
//set ground in our Animator to match grounded
anim.SetBool ("Ground", grounded);
float move = Input.GetAxis ("Horizontal");//Gives us of one if we are moving via the arrow keys
//move our Players rigidbody
rigidbody2D.velocity = new Vector3 (move * maxSpeed, rigidbody2D.velocity.y);
//set our speed
anim.SetFloat ("Speed",Mathf.Abs (move));
//if we are moving left but not facing left flip, and vice versa
if (move > 0 && !facingLeft) {
Flip ();
} else if (move < 0 && facingLeft) {
Flip ();
}
}
void Update(){
if ((isOnGround == true && Input.GetKeyDown (KeyCode.UpArrow)) || (isOnGround == true && Input.GetKeyDown (KeyCode.Space))) {
anim.SetBool("Ground",false);
rigidbody2D.AddForce (new Vector2 (0, jumpForce));
}
if (isOnGround == true && Input.GetKeyDown (KeyCode.DownArrow))
{
gameObject.transform.localScale = new Vector3(transform.localScale.x, 0.2f, 0.2f);
}
if (isOnGround == true && Input.GetKeyUp (KeyCode.DownArrow))
{
gameObject.transform.localScale = new Vector3(transform.localScale.x, 0.3f, 0.3f);
}
}
//flip if needed
void Flip(){
facingLeft = !facingLeft;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
What needs to happen is that when The "Up-arrow" in the game is clicked then The person shall jump on the same tearms as in the RobotController script.
I hope you understand my question.
Thanks for your time and help.
I posted this same answer to both of the questions, because they are so similar. You can easily modify the code to your needs.
This is only one way to do it. There are probably many more, but this is the best I have encountered so far.
On the QUI button, script like this is needed:
private Mover playerMover;
void Start()
{
playerMover = GameObject.Find("Character").GetComponent<Mover>();
}
void OnMouseOver()
{
if (Input.GetMouseButton(0))
{
Debug.Log("pressed");
playerMover.MoveButtonPressed();
}
}
Notice that find is only done ones in start function, because it is computationally heavy.
And on the Character gameobject, script component like this is needed:
using UnityEngine;
using System.Collections;
public class Mover : MonoBehaviour {
public void MoveButtonPressed()
{
lastPressedTime = Time.timeSinceLevelLoad;
}
public double moveTime = 0.1;
private double lastPressedTime = 0.0;
void Update()
{
if(lastPressedTime + moveTime > Time.timeSinceLevelLoad)
{
// Character is moving
rigidbody.velocity = new Vector3(1.0f, 0.0f, 0.0f);
}
else
{
rigidbody.velocity = new Vector3(0.0f, 0.0f, 0.0f);
}
}
}

Categories