Unity 5.3.5f Not Registering Space Bar Being Pressed - c#

So I have a player movement script that is supposed to allow the player to double jump by counting the number of times the space bar is pressed. It was working a couple versions early, but now has just randomly stopped working. No idea why it randomly stopped working.
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public float jumpPower = 2f;
[SerializeField]
public bool isGrounded = true;
[SerializeField]
private LayerMask groundLayer, waterLayer;
private int numSpacePress = 0;
private Rigidbody2D rb;
// Ground Checker Stuff
public Transform groundChecker;
public float groundCheckRadius = 0.1f;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && isGrounded && numSpacePress < 2)
{
numSpacePress++;
Debug.Log("Num spaces pressed = " + numSpacePress);
rb.velocity = new Vector2(rb.velocity.x, jumpPower);
if (numSpacePress >= 2)
{
isGrounded = false;
}
}
Collider2D[] hits = Physics2D.OverlapCircleAll(groundChecker.position, groundCheckRadius);
foreach (Collider2D hit in hits)
{
if (hit.gameObject != gameObject)
{
Debug.Log("Hit = " + hit.gameObject.name);
if (((1 << hit.GetComponent<Collider2D>().gameObject.layer) & groundLayer) != 0)
{
isGrounded = true;
numSpacePress = 0;
}
}
}
}
}
What's Happening Gif, clearly in the gif I am pressing space twice, but it is only printing the number of spaces pressed by one. If the player is on the ground the number of spaces pressed is reset, but the gif also shows that the player is not touching the ground. Why is the space bar not being registered when pressed?

What was happening was a hit was occurring just after the space bar was pressed, which reset the variable counting the number of spaces pressed.
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public float jumpPower = 2f;
[SerializeField]
public bool isGrounded = true;
[SerializeField]
private LayerMask groundLayer, waterLayer;
private int numSpacePress = 0;
private Rigidbody2D rb;
// Ground Checker Stuff
public Transform groundChecker;
public float groundCheckRadius = 0.1f;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
Collider2D[] hits = Physics2D.OverlapCircleAll(groundChecker.position, groundCheckRadius);
foreach (Collider2D hit in hits)
{
if (hit.gameObject != gameObject)
{
Debug.Log("Hit = " + hit.gameObject.name);
if (((1 << hit.GetComponent<Collider2D>().gameObject.layer) & groundLayer) != 0)
{
isGrounded = true;
numSpacePress = 0;
}
}
}
if (Input.GetKeyDown(KeyCode.Space) && isGrounded && numSpacePress < 2)
{
numSpacePress++;
Debug.Log("Num spaces pressed = " + numSpacePress);
rb.velocity = new Vector2(rb.velocity.x, jumpPower);
if (numSpacePress >= 2)
{
isGrounded = false;
}
}
}
}

Related

Stopping player's movement upon clicking dialogue - Unity

I have a problem where when I click the dialogue while passing through an NPC or while moving, the character will continue moving in the direction of the joystick before it is set active to false.
I have tried setting the horizontal and vertical input to zero and even the movement direction which is the calculated horizontal and vertical input, but the character still moves in the last direction it was moving. I'm not sure if the if statement that I created is correct but that was the idea that came to mind.
This is the script for the movement of the player:
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerMovement : MonoBehaviour
{
[SerializeField] private GameObject interactButton;
public float speed, rotationSpeed, ySpeed, originalStepOffset;
public Joystick joystick;
private Animator animator;
private CharacterController characterController;
void Start()
{
animator = GetComponent<Animator>();
characterController = GetComponent<CharacterController>();
originalStepOffset = characterController.stepOffset;
}
// Update is called once per frame
void FixedUpdate()
{
float horizontalInput = joystick.Horizontal;
float verticalInput = joystick.Vertical;
Vector3 movementDirection = new Vector3(horizontalInput, 0, verticalInput);
movementDirection = Quaternion.Euler(0, 45f, 0) * movementDirection;
float magnitude = Mathf.Clamp01(movementDirection.magnitude) * speed;
movementDirection.Normalize();
ySpeed += Physics.gravity.y * Time.deltaTime;
if(characterController.isGrounded)
{
characterController.stepOffset = originalStepOffset;
ySpeed = -0.5f;
}
else
{
characterController.stepOffset = 0;
}
Vector3 velocity = movementDirection * magnitude;
velocity = AdjustVelocityToSlope(velocity);
velocity.y += ySpeed;
//transform.Translate(movementDirection * speed * Time.deltaTime, Space.World);
characterController.Move(velocity * Time.deltaTime);
if (movementDirection != Vector3.zero)
{
if(EventSystem.current.currentSelectedGameObject != null)
{
if (EventSystem.current.currentSelectedGameObject.name == "InteractButton")
{
horizontalInput = 0f;
verticalInput = 0f;
movementDirection = Vector3.zero;
animator.SetBool("IsMoving", false);
}
else
{
//transform.forward = movementDirection;
animator.SetBool("IsMoving", true);
Quaternion toRotation = Quaternion.LookRotation(movementDirection, Vector3.up);
transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime);
}
}else
{
animator.SetBool("IsMoving", true);
Quaternion toRotation = Quaternion.LookRotation(movementDirection, Vector3.up);
transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime);
}
} else
{
animator.SetBool("IsMoving", false);
}
}
private Vector3 AdjustVelocityToSlope(Vector3 velocity)
{
var ray = new Ray(transform.position, Vector3.down);
if(Physics.Raycast(ray, out RaycastHit hitInfo, 0.2f))
{
var slopeRotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
var adjustedVelocity = slopeRotation * velocity;
if(adjustedVelocity.y < 0)
{
return adjustedVelocity;
}
}
return velocity;
}
}
The function that will make the button to set active to true and add its onclick listeners is a trigger enter function and a trigger exit for setting it active to false and removing the onclick listeners. It is attached to multiple NPC whenever I go near them, the button will appear. In case someone needs to see the script for the button here it is, but I'm gonna paste only until the related part:
using System;
using System.Collections;
using System.Drawing;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
[System.Serializable]
public class DialogueManager : MonoBehaviour
{
/*
// NPC INTERACTION
private static DialogueManager buttonOwner;
private Camera mainCamera;
*/
// NPC DATA
private Character characterJson;
// FOR DIALOG FLOW
private int multiDialogCycle;
public static int dialogId;
// GAME OBJECTS REFERENCE
[SerializeField] private GameObject dialogBox, addPanel, m1, id, darkPanel;
[SerializeField] private Button nameBtn, choiceOneBtn, choiceTwoBtn;
[SerializeField] private TextMeshProUGUI npcName, choiceOne, choiceTwo, dialogName, dialogMessage, addedText;
[SerializeField] private TextAsset characterData;
// FOR MULTIPLE DIALOGUES WITHOUT CHOICES
private bool clickEnable;
private string[] multiDialog;
// CHOICES STORAGE
private static Choice[] choices = new Choice[2];
//private TryInstantiate tryInstantiate = new TryInstantiate();
private GameData gameData;
private void Start()
{
// LOAD NPC DATA
characterJson = JsonUtility.FromJson<Character>(characterData.text);
// SET DEFAULT VALUE
//dialogId = 0;
multiDialogCycle = 0;
clickEnable = false;
// SET SCRIPTABLE OBJECT FOR DATA STORAGE
gameData = Resources.Load<GameData>("GameData/GameData");
}
private void Update()
{
if(nameBtn.gameObject.activeInHierarchy)
{
if(Input.GetKey(KeyCode.Space))
{
EventSystem.current.SetSelectedGameObject(nameBtn.gameObject);
}
}
// FOR ENDING DIALOGUES WITHOUT CHOICES
if (Input.GetMouseButtonDown(0) && clickEnable == true)
{
if (multiDialog.Length > 1 )
{
if(getDialog(dialogId).choices.Length == 0 && multiDialogCycle == multiDialog.Length - 1)
{
addArticles();
addObjectives();
addClues();
closeDialog();
Debug.Log(getDialog(dialogId).minigame);
}
else
{
if(getDialog(dialogId).minigame != "" && multiDialogCycle < multiDialog.Length - 1)
{
if(!gameData.idShown)
{
darkPanel.SetActive(true);
id.SetActive(true);
}
}else
{
multiDialogCycle++;
loadCharacterData();
}
}
}
else
{
if (getDialog(dialogId).minigame != "")
{
if(getDialog(dialogId).minigame == "spot_object")
{
m1.SetActive(true);
}
dialogBox.SetActive(false);
gameData.dialogActive = false;
}
else
{
addArticles();
addObjectives();
addClues();
closeDialog();
}
}
}
if(gameData.idShown)
{
multiDialogCycle++;
loadCharacterData();
gameData.idShown = false;
}
if (gameData.dialogActive && dialogId != 0 && getDialog(dialogId).minigame != "" && !gameData.loadedData)
{
updateID();
loadCharacterData();
}
// FOR NPC NAMES
/*
if (buttonOwner != this) return;
if (!mainCamera) mainCamera = Camera.main;
var position = mainCamera.WorldToScreenPoint(head.position + offset);
//uiUse.transform.position = position;
nameBtn.transform.position = position;
*/
}
private void OnTriggerEnter(Collider collisionInfo)
{
if (collisionInfo.CompareTag("Player"))
{
nameBtn.gameObject.SetActive(true);
nameBtn.GetComponent<Image>().sprite = Resources.Load<Sprite>("InteractionAsset/DIALOGUE");
nameBtn.transform.GetChild(0).GetComponent<TextMeshProUGUI>().color = new Color32(75,75,75,255);
//buttonOwner = this;
nameBtn.onClick.RemoveListener(onNameClick);
nameBtn.onClick.AddListener(onNameClick);
choiceOneBtn.onClick.RemoveListener(onChoiceClick);
choiceOneBtn.onClick.AddListener(onChoiceClick);
choiceTwoBtn.onClick.RemoveListener(onChoiceClick);
choiceTwoBtn.onClick.AddListener(onChoiceClick);
npcName.text = characterJson.name;
}
}
private void OnTriggerExit(Collider collisionInfo)
{
if (collisionInfo.CompareTag("Player"))
{
nameBtn.onClick.RemoveListener(onNameClick);
choiceOneBtn.onClick.RemoveListener(onChoiceClick);
choiceTwoBtn.onClick.RemoveListener(onChoiceClick);
nameBtn.gameObject.SetActive(false);
//buttonOwner = null;
}
}
// DIALOGUE SYSTEM
public void onNameClick()
{
nameBtn.gameObject.SetActive(false);
dialogBox.SetActive(true);
gameData.dialogActive = true;
FindObjectOfType<AudioManager>().Play("ButtonSound");
if (dialogBox.activeInHierarchy)
{
if (dialogMessage != null && dialogName != null)
{
loadCharacterData();
interactedNPC();
}
else
{
// Debug.Log("null dialog message");
}
}
}
public void updateID()
{
if (gameData.win && !gameData.loadedData)
{
dialogId = gameData.targetId_1;
gameData.loadedData = true;
}
else if (!gameData.win && !gameData.loadedData)
{
dialogId = gameData.targetId_2;
gameData.loadedData = true;
}
}
How can I atleast reset the Joystick's position. I am currently using the Joystick Pack from Unity Asset Store.
I for one would start the Conversation flow from the dialogue step. Once the dialog starts, you can either set a bool or any other type of property (even a referenced object such as the dialogue itself or the NPC that it's chatting to, but a bool is simpler) that would be a marker. Simply put: public bool IsTalking;. This could be in PlayerMovement or the main Player-like component (or SO) which you can access from PlayerMovement via GameObject or a different public variable.
Next, once the dialogue mechanism starts, you can set the marker (such as the bool or NPC ref) in the Player-like component or PlayerMovement to true, false when the chatting stops.
Then in PlayerMovement.FixedUpdate() you can just stop code execution:
// Update is called once per frame
void FixedUpdate()
{
// or if (Player.IsTalking == true) if you want the marker there,
// but you can have it inside PlayerMovement if you wish as long as
// you can reference it without overhead - meaning don't do crazy
// stuff like searching all game objects/components for PlayerMovement)
if (IsTalking == true)
{
if (characterController != null)
characterController.Move(Vector3.zero);
if (animator != null)
animator.SetBool("IsMoving", false);
return;
}
// everything starts executing once the player stops talking to NPCs
float horizontalInput = joystick.Horizontal;
float verticalInput = joystick.Vertical;
Vector3 movementDirection = new Vector3(horizontalInput, 0, verticalInput);
movementDirection = Quaternion.Euler(0, 45f, 0) * movementDirection;
float magnitude = Mathf.Clamp01(movementDirection.
As I understood you dialogue window is modal. Depending on your needs you can stop the internal increment of time progression with
Time.timeScale = 0f;
But this will stop e.g. (UI) animations and the proper function of the event system, so some people use
Time.timeScale = 0.0001f;
This has the drawback that the gameplay continues slowly and our player hero could be hit by a very slow rocket while the user was resting in a pause screen.

AI wandering state doesn't seem to work right

I've been trying to make an AI system that would follow specific waypoints and once the player character walks into the trigger zone, the AI would start chasing the character and vice versa.
It seems that this does kind of work, but the AI only moves to one waypoint and then stops until the player walks into the trigger zone; after which if the player walks out, it again only goes to one waypoint then stops again.
I have multiple waypoints and I just want it to keep cycling through them, but it just goes to one of them and stops.
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
using UnityEngine.AI;
using UnityEngineInternal;
public class AILocomotion : MonoBehaviour
{
public Transform playerTransform;
NavMeshAgent agent;
Animator animator;
public float maxTime = 1.0f;
public float maxDistance = 1.0f;
float timer = 0.0f;
bool moveTowards = false;
bool followWaypoint = false;
float deaccel= 0.5f;
float calVelocity = 0.0f;
public Transform[] points;
private int destPoint = 0;
public string animState;
void Start()
{
agent = GetComponent<NavMeshAgent>();
animator = GetComponent<Animator>();
moveTowards = false;
followWaypoint = true;
}
// Update is called once per frame
void Update()
{
if (moveTowards == true)
{
timer -= Time.deltaTime;
if (timer < 0.0f)
{
float sqDistance = (playerTransform.position - agent.destination).sqrMagnitude;
if (sqDistance > maxDistance * maxDistance)
{
agent.destination = playerTransform.position;
}
}
animator.SetFloat("Speed", agent.velocity.magnitude);
}
else if (!moveTowards && agent.velocity.magnitude>0.0f)
{
calVelocity = agent.velocity.magnitude;
calVelocity -= Time.deltaTime * deaccel;
animator.SetFloat("Speed", calVelocity);
}
//CHECKS IF BOTH CONDITIONS HAVE MET AND RUNS THE WAYPOINT FOLLOWING CODE
if (followWaypoint == true && (!agent.pathPending && agent.remainingDistance < 1.0f))
{
GotoNextPoint();
}
Debug.LogError("Bool" + followWaypoint);
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Player"))
{
moveTowards = true;
//DISABLES THE WAYPOINT FOLLOWING CODE TO RUN THE CHASE CODE INSTEAD
followWaypoint = false;
}
}
private void OnTriggerExit(Collider other)
{
if (other.gameObject.CompareTag("Player"))
{
moveTowards = false;
//RE-ENABLES THE WAYPOINT FOLLOWING CODE ONCE THE PLAYER LEAVES THE TRIGGER AREA
followWaypoint = true;
}
}
//THIS IS THE WAYPOINT FOLLOWING CODE
void GotoNextPoint()
{
animator.SetFloat("Speed", agent.velocity.magnitude);
// Returns if no points have been set up
if (points.Length == 0)
return;
// Set the agent to go to the currently selected destination.
agent.destination = points[destPoint].position;
Debug.LogError("DestPoint = " + destPoint);
// Choose the next point in the array as the destination.
// cycling to the start if necessary.
destPoint = Random.Range(0, points.Length);
}
}
Use OnTriggerStay instead of OntriggerEnter and Try

Infinite jump in unity 3D

My character keeps floating up if space bar is held down until you let go, I tried all day on how to make the character to jump normal but I am just stuck. I'm using unity to create the game. The issue started when I changed onfloor=true, before when it was false the character could only jump once. Here is the code for the character in C#
Thank you
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
private Transform rotateBody;
private Vector3 Direction;
private const float gravity = 0.1f;
private const float jump_force = 0.09f;
public Transform groundCheckTransform;
private bool shiftKeyWasPressed;
private bool jumpKeyWasPressed;
private float horizontalInput;
private Rigidbody RigidbodyComponent;
public LayerMask playerMask;
private int superJumpsRemaing;
private bool on_floor = true;
// Start is called before the first frame update
void Start()
{
RigidbodyComponent = GetComponent<Rigidbody>();
shiftKeyWasPressed = false;
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.Space) & Direction.y > 0){
jumpKeyWasPressed = true;
}
horizontalInput = Input.GetAxis("Horizontal");
if(Input.GetKeyDown(KeyCode.LeftShift)){
shiftKeyWasPressed = true;
}
horizontalInput = Input.GetAxis("Horizontal");
}
void FixedUpdate(){
Direction.y -= gravity;
Direction.x = 0;
if (Input.GetKey(KeyCode.Space)){
if (Direction.y < 0 && on_floor){
Direction.y = 0;
}
if(on_floor){
Direction.y += jump_force*2;
on_floor = true;
}
}else{
jumpKeyWasPressed = false;
}
if (Input.GetKey(KeyCode.D)){
Direction.x += 2;
}
if (Input.GetKey(KeyCode.A)){
Direction.x -= 2;
}
if (Input.GetKey(KeyCode.LeftShift))
if(shiftKeyWasPressed==true)
Direction.x *= 6;
if(Physics.OverlapSphere(groundCheckTransform.position, 0.1f, playerMask).Length == 0){
return;
}
if (jumpKeyWasPressed)
{
float jumpPower = 7;
if (superJumpsRemaing > 0){
jumpPower *=2;
superJumpsRemaing--;
}
RigidbodyComponent.AddForce(Vector3.up*jumpPower, ForceMode.VelocityChange);
jumpKeyWasPressed = false;
}
RigidbodyComponent.velocity = Direction;
}
private void OnTriggerEnter(Collider other)
{
if ( other.gameObject.layer == 8){
jumpKeyWasPressed = true;
if(Direction.y > 8)
jumpKeyWasPressed = false;
}
if (other.gameObject.layer == 6){
Destroy(other.gameObject);
}
if (other.gameObject.layer == 7){
Destroy(other.gameObject);
superJumpsRemaing++;
}
}
}
Your on_floor variable never becomes false which results in constantly adding y value when ever space button is held down. You need to add the check for ground collision and set on_floor to false whenever player hits ground object. You can use raycast towards downward direction for this something like:
public dist = 10;
public RaycastHit hit;
public void CheckGroundBelow()
{
dist = 10; //Distance to calculate height from
dir = Vector3(0,-1,0); //Downward Direction
if(Physics.Raycast(transform.position,dir,hit,dist)){
on_floor = true;
}
else
{
on_floor = false;
}
}
Here it checks if something is below your player's transform . If there is something within 10 m then it means player is on ground otherwise it ignores input . You can call it just above your if condition here you check for on_floor.
More about Raycast here : https://docs.unity3d.com/ScriptReference/Physics.Raycast.html
Alternatively you can also use Character Controller Component inside Unity which already has a check named as IsGrounded :
More about Character controller here : https://docs.unity3d.com/ScriptReference/CharacterController.html

Unity Crouch speed always active

I am a beginner and I have copy-pasted shamelessly a 2Dcontroller script, now the problem is that the movement speed of the character is affected by the crouching speed all the time, so what I want it to do is for the character to be affected only when the button is pressed down.
The following is the copy-paste.
using UnityEngine;
using UnityEngine.Events;
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;
}
the following is the player-character script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController2D controller;
public float horizontalMove = 0f;
public float runSpeed = 40f;
bool jump = false;
bool crouch = false;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed;
if (Input.GetButtonDown("Jump"))
{
jump = true;
}
if (Input.GetButtonDown("Crouch"))
{
crouch = true;
}else if (Input.GetButtonUp("Crouch"))
{
crouch = false;
}
}
private void FixedUpdate()
{
controller.Move(horizontalMove * Time.fixedDeltaTime, crouch, jump);
jump = false;
}
}
I am trying to follow this video.
https://www.youtube.com/watch?v=dwcT-Dch0bA&t=662s&ab_channel=Brackeys
Thank you in advance to anyone who takes the time to help me, have a nice day!!

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.

Categories