Cannot Implicitly Convert "void" to "object". How do I fix this? - c#

So I have been working on my first game in Unity using C#, and I am having an error with the code but Visual Studio says that the code looks good. Anything I need to change? (If the code looks wonky, I followed a tutorial)
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;
}
}strong text

Are you using the Move method in another script?
If you're using that somewhere else and are attempting to assign to something using its result, it will result in that error.
Edit: Might also be the call to OverlapCircle(). It returns a Collider2D, but you're treating it as a boolean value by having it in an if check.
Try using it like:
if (Physics2D.OverlapCircle(m_CeilingCheck.position, k_CeilingRadius, m_WhatIsGround) != null)

Related

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.

UnityEngineComponent Velocity Error How do I fix it?

I am very new to unity and I am getting this error.
I really have no clue what to do to fix it so I hope someone can help me.
UnityEngine.Component' does not contain a definition for velocity' and no extension methodvelocity' of type `UnityEngine.Component' could be found. Are you missing an assembly reference?'
using UnityEngine;
namespace UnitySampleAssets._2D
public class PlatformerCharacter2D : MonoBehaviour
{
private bool facingRight = true; // For determining which way the player is currently facing.
[SerializeField] private float maxSpeed = 10f; // The fastest the player can travel in the x axis.
[SerializeField] private float jumpForce = 400f; // Amount of force added when the player jumps.
[Range(0, 1)] [SerializeField] private float crouchSpeed = .36f;
// Amount of maxSpeed applied to crouching movement. 1 = 100%
[SerializeField] private bool airControl = false; // Whether or not a player can steer while jumping;
[SerializeField] private LayerMask whatIsGround; // A mask determining what is ground to the character
private Transform groundCheck; // A position marking where to check if the player is grounded.
private float groundedRadius = .2f; // Radius of the overlap circle to determine if grounded
private bool grounded = false; // Whether or not the player is grounded.
private Transform ceilingCheck; // A position marking where to check for ceilings
private float ceilingRadius = .01f; // Radius of the overlap circle to determine if the player can stand up
private Animator anim; // Reference to the player's animator component.
private void Awake()
{
// Setting up references.
groundCheck = transform.Find("GroundCheck");
ceilingCheck = transform.Find("CeilingCheck");
anim = GetComponent<Animator>();
}
private void FixedUpdate()
{
// The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
grounded = Physics2D.OverlapCircle(groundCheck.position, groundedRadius, whatIsGround);
anim.SetBool("Ground", grounded);
// Set the vertical animation
anim.SetFloat("vSpeed", rigidbody2D.velocity.y);
}
public void Move(float move, bool crouch, bool jump)
{
// If crouching, check to see if the character can stand up
if (!crouch && anim.GetBool("Crouch"))
{
// If the character has a ceiling preventing them from standing up, keep them crouching
if (Physics2D.OverlapCircle(ceilingCheck.position, ceilingRadius, whatIsGround))
crouch = true;
}
// Set whether or not the character is crouching in the animator
anim.SetBool("Crouch", crouch);
//only control the player if grounded or airControl is turned on
if (grounded || airControl)
{
// Reduce the speed if crouching by the crouchSpeed multiplier
move = (crouch ? move*crouchSpeed : move);
// The Speed animator parameter is set to the absolute value of the horizontal input.
anim.SetFloat("Speed", Mathf.Abs(move));
// Move the character
rigidbody2D.velocity = new Vector2(move*maxSpeed, rigidbody2D.velocity.y);
// If the input is moving the player right and the player is facing left...
if (move > 0 && !facingRight)
// ... flip the player.
Flip();
// Otherwise if the input is moving the player left and the player is facing right...
else if (move < 0 && facingRight)
// ... flip the player.
Flip();
}
// If the player should jump...
if (grounded && jump && anim.GetBool("Ground"))
{
// Add a vertical force to the player.
grounded = false;
anim.SetBool("Ground", false);
rigidbody2D.AddForce(new Vector2(0f, jumpForce));
}
}
private void Flip()
{
// Switch the way the player is labelled as facing.
facingRight = !facingRight;
// Multiply the player's x local scale by -1.
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
}

Unity - how do I get my jump animation cycle to work?

I am new to unity and C# so would appreciate any help.
I have made my sprite jump which works fine, however, the only animation which will play is the landing animation. The takeoff animation won't play and the sprite stays in an idle position whilst jumping until the velocity goes below 0 then the landing animation plays.
What am I doing wrong? I am hoping to achieve a takeoff animation playing when the player jumps up and then move straight into a landing animation when it falls.
Here is my code:
using UnityEngine;
public class Player : MonoBehaviour
{
private Rigidbody2D myRigidbody;
private Animator myAnimator;
[SerializeField]
private float movementSpeed;
private bool facingRight;
private bool attack;
private bool slide;
[SerializeField]
private Transform[] groundPoints;
[SerializeField]
private float groundRadius;
[SerializeField]
private LayerMask whatIsGround;
private bool isGrounded;
private bool jump;
private bool airControl;
[SerializeField]
private float jumpForce;
// Use this for initialization
void Start()
{
facingRight = true;
myRigidbody = GetComponent<Rigidbody2D>();
myAnimator = GetComponent<Animator>();
}
void Update()
{
HandleInput();
}
// Update is called once per frame
void FixedUpdate()
{
float horizontal = Input.GetAxis("Horizontal");
HandleMovement(horizontal);
isGrounded = IsGrounded();
Flip(horizontal);
HandleAttacks();
HandleLayers();
ResetValues();
}
private void HandleMovement(float horizontal)
{
if (myRigidbody.velocity.y < 0)
{
myAnimator.SetBool("land", true);
}
if (!myAnimator.GetBool("slide") && !this.myAnimator.GetCurrentAnimatorStateInfo(0).IsTag("Attack")&&(isGrounded || airControl))
{
myRigidbody.velocity = new Vector2(horizontal * movementSpeed, myRigidbody.velocity.y);
}
if (isGrounded && jump)
{
isGrounded = false;
myRigidbody.AddForce(new Vector2(0, jumpForce));
myAnimator.SetTrigger("jump");
}
if (slide && !this.myAnimator.GetCurrentAnimatorStateInfo(0).IsName("Slide"))
{
myAnimator.SetBool("slide", true);
}
else if (!this.myAnimator.GetCurrentAnimatorStateInfo(0).IsName("Slide"))
{
myAnimator.SetBool("slide", false);
}
myAnimator.SetFloat("speed", Mathf.Abs(horizontal));
}
private void HandleAttacks()
{
if (attack && !this.myAnimator.GetCurrentAnimatorStateInfo(0).IsTag("Attack"))
{
myAnimator.SetTrigger("attack");
myRigidbody.velocity = Vector2.zero;
}
}
private void HandleInput()
{
if(Input.GetKeyDown(KeyCode.Space))
{
jump = true;
}
if (Input.GetKeyDown(KeyCode.LeftShift))
{
attack = true;
}
if (Input.GetKeyDown(KeyCode.LeftControl))
{
slide = true;
}
}
private void Flip(float horizontal)
{
if (horizontal > 0 && !facingRight || horizontal < 0 && facingRight)
{
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
private void ResetValues()
{
attack = false;
slide = false;
jump = false;
}
private bool IsGrounded()
{
if (myRigidbody.velocity.y <= 0)
{
foreach (Transform point in groundPoints)
{
Collider2D[] colliders = Physics2D.OverlapCircleAll(point.position, groundRadius, whatIsGround);
for (int i = 0; i < colliders.Length; i++)
{
if (colliders[i].gameObject != gameObject)
{
myAnimator.ResetTrigger("jump");
myAnimator.SetBool("land", false);
return true;
}
}
}
}
return false;
}
private void HandleLayers()
{
if (!isGrounded)
{
myAnimator.SetLayerWeight(1, 1);
}
else
{
myAnimator.SetLayerWeight(1, 0);
}
}
}
I think the way you have your animations set up is making this more challenging than necessary. Let's change some things that will hopefully make animating your character a little easier.
First, it is my opinion that using an animation trigger is unreliable when it comes to scripting jumping animations. A better approach is to create a float in your animator, which I have called velocityY, that represents the player's Rigidbody2D.velocity.y. I've also created a new bool called isGrounded, as I think this is clearer and more applicable to many "jump" scenarios.
Once these variables have been created you can link your three animations - idle, jump and land - in the following way:
Set the default animation to "idle".
Make a transition from "idle" to "jump" in which the conditions are:
velocityY > 0
isGrounded = false
Make a transition from "jump" to "land" with the conditions:
velocityY < 0
isGrounded = false
Make a transition from "land" to "idle" when isGrounded = true.
Finally, to animate your character when it falls (without jumping first), you can optionally make a transition from "idle" to "land" where:
velocityY < 0
isGrounded = false
Now to the code. Here's a working example that I tested in a project to achieve your desired results. Note that I did not include everything in your script, just the parts that let the character move and animate its jump correctly. Try using this script and playing around with the movement values, as well as the gravity multiplier on your player's Rigidbody2D component; the default values and a gravity multiplier of 3.5 felt fun to me!
using UnityEngine;
public class Player : MonoBehaviour
{
//Components on Player GameObject
private Rigidbody2D myRigidbody;
private Animator myAnimator;
//Movement variables
[SerializeField]
private float movementSpeed = 9; //Set default values so you don't always
[SerializeField] //have to remember to set them in the inspector
private float jumpForce = 15;
//Ground checking
[SerializeField]
private Transform groundPoint;
[SerializeField]
private float groundRadius = 0.1f;
[SerializeField]
private LayerMask whatIsGround;
private float velocityX;
private bool isGrounded;
private bool facingRight;
// Use this for initialization
private void Start()
{
facingRight = true;
myRigidbody = GetComponent<Rigidbody2D>();
myAnimator = GetComponent<Animator>();
}
private void Update()
{
Flip();
HandleInput();
HandleAnimations();
}
private void FixedUpdate()
{
HandleMovement(); //It's generally considered good practice to
//call physics-related methods in FixedUpdate
}
private void HandleAnimations()
{
if (!isGrounded)
{
myAnimator.SetBool("isGrounded", false);
//Set the animator velocity equal to 1 * the vertical direction in which the player is moving
myAnimator.SetFloat("velocityY", 1 * Mathf.Sign(myRigidbody.velocity.y));
}
if (isGrounded)
{
myAnimator.SetBool("isGrounded", true);
myAnimator.SetFloat("velocityY", 0);
}
}
private void HandleMovement()
{
isGrounded = Physics2D.OverlapCircle(groundPoint.position, groundRadius, whatIsGround);
velocityX = Input.GetAxis("Horizontal");
myRigidbody.velocity = new Vector2(velocityX * movementSpeed , myRigidbody.velocity.y);
}
private void HandleInput()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Jump();
}
}
private void Jump()
{
if (isGrounded)
{ //ForceMode2D.Impulse is useful if Jump() is called using GetKeyDown
myRigidbody.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
}
else
{
return;
}
}
private void Flip()
{
if (velocityX > 0 && !facingRight || velocityX < 0 && facingRight)
{
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
}
I also took some time to reorganize your code. You don't necessarily need to concern yourself with too much organization right now, but I thought it might interest you since you're still learning.
As you can see, each method in the script handles a concrete task. For example, there's a method solely for handling animation, and another that lets the player jump. It's a good idea to set up your code this way so that if you have to change one aspect later, such as player movement, then all of the related code is in the same place. I think this is especially true for creating methods that deal with player "actions" like jumping or attacking; if you have enough of them you could even create an entire Actions class.
One last thing to mention is this line of code:
isGrounded = Physics2D.OverlapCircle(groundPoint.position, groundRadius, whatIsGround);
I found that this was an easier way to determine when the player is grounded. I achieved this by adding a child GameObject to the player, adding a colorful icon for ease of placement (you can do this by clicking the colorful box near the name of a GameObject), and placing it in between the player's feet.

DoubleJumping Limits in Unity2D

Looking at help forums on Unity, I figured out quickly that the syntax I was looking at was really outdated (Same thing on here: Unity Doublejump in C#).
Here's the article I was talking about:
http://answers.unity3d.com/questions/753238/restrict-number-of-double-jumps.html
For instance, in the void Awake(), in the current version of Unity I'm using, it says that rigidbody2D.fixedAngle = true; was no longer supported, and I needed to use constraints on the gameObject I was trying to program (what axis should I use... the x,y or z?). After doing some editing and after looking up the error messages, I was able to change all of the rigidbody2D.velocity into the updated syntax, which was GetComponent ().velocity .
Here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour {
public float speed = 6.0f;
//public float j
Transform groundCheck;
//private float overlapRadius = 0.2f;
public LayerMask whatisGround;
private bool grounded = false;
private bool jump = false;
public float jumpForce = 700f;
private bool doubleJump = false;
public int dJumpLimit = 5;
void Start()
{
groundCheck = transform.Find ("groundcheck");
PlayerPrefs.SetInt ("doublejumps", dJumpLimit);
}
void Update()
{
if (Input.GetKey(KeyCode.Space))
{
jump = true;
}
//perhaps put A and D here?
}
void FixedUpdate()
{
//to check if Mario is on the ground
//overlap collider replace Overlap Circle???
//overlap point??
//grounded = GetComponent<Rigidbody2D> ().OverlapCollision(groundCheck.position, overlapRadius, whatisGround);
if (grounded)
doubleJump = false;
if (dJumpLimit < 1)
doubleJump = true;
bool canJump = (grounded || !doubleJump);
if (jump && canJump) {
GetComponent<Rigidbody2D> ().velocity = new Vector2 (GetComponent<Rigidbody2D> ().velocity.x, 0);
GetComponent<Rigidbody2D> ().AddForce (new Vector2 (0, jumpForce));
if (!doubleJump && !grounded) {
doubleJump = true;
dJumpLimit--;
}
}
jump = false;
//code that will work with the limits?
//GetComponent<Rigidbody2D>().velocity = new Vector2(speed,GetComponent<Rigidbody2D>().velocity.y);
//this will make it stack?
//GetComponent<Rigidbody2D>().velocity = new Vector2(speed,GetComponent<Rigidbody2D>().velocity.x);
//GetComponent<Rigidbody2D>().velocity = new Vector2(speed,GetComponent<Rigidbody2D>().velocity.y);
}
}
Good thing is that it was able to compile in the end. But I still don't know how the constraints work (they resist motion on the x,y,z axis right?). The jumps still don't have a capstone, and the variable dJumpLimit doesn't seem to stop all the jumping! I had also lot of trouble trying to decipher what the booleans were trying to accomplish, and it would help a lot if you tell me what the outdated code was trying to do, and what I failed doing so. That would help me a lot.Thanks so much for helping!!!
I have added the same code with some additional comments to help you.
The basic idea is to allow jumping under certain conditions, and allow double jumping under certain other conditions,
Try to think about it logically, Mario can only jump when he is on the ground, so we need to check that every frame. If he is grounded, and the player presses space, we make him jump.
Now, we want Mario to be able to double-jump but only if he is already in the air (otherwise it's just a regular jump) and only if he has not already double-jumped in this "current" jump.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour {
public float speed = 6.0f;
//public float j
Transform groundCheck; // For checking if grounded
//private float overlapRadius = 0.2f; // For checking if grounded
public LayerMask whatisGround; // A layer mask to distinguish what is considered as ground
private bool grounded = false; // True when Mario is touching ground
private bool jump = false; // Flag to check when player intends to jump
public float jumpForce = 700f; // How much force we will apply to our jump
private bool doubleJump = false; // This becomes true once we have double-jumped
public int dJumpLimit = 5; // A limit to prevent too many jumps happening
void Start()
{
// Find the Transform called "groundcheck"
groundCheck = transform.Find ("groundcheck");
// Set the PlayerPrefs integer called "doublejumps" to the value of dJumpLimit
PlayerPrefs.SetInt ("doublejumps", dJumpLimit);
}
void Update()
{
// If Space is being pressed...
if (Input.GetKey(KeyCode.Space))
{
jump = true; // Set jump bool to true to indicate our intention to jump
}
//perhaps put A and D here?
}
void FixedUpdate()
{
//to check if Mario is on the ground - this is necessary so we can't jump forever
//overlap collider replace Overlap Circle???
//overlap point??
//grounded = GetComponent<Rigidbody2D> ().OverlapCollision(groundCheck.position, overlapRadius, whatisGround);
// If Mario is touching ground...
if (grounded)
doubleJump = false; // Make sure that as we are grounded we are not allowed to "jump again"
if (dJumpLimit < 1)
doubleJump = true;
// Set a new bool to true if grounded is true OR doubleJump is false
bool canJump = (grounded || !doubleJump);
// If the player pressed space AND we are allowed to jump...
if (jump && canJump) {
// Apply existing x velocity to the x direction
GetComponent<Rigidbody2D> ().velocity = new Vector2 (GetComponent<Rigidbody2D> ().velocity.x, 0);
// Apply our jump force to the y direction
GetComponent<Rigidbody2D> ().AddForce (new Vector2 (0, jumpForce));
// If doubleJump is false AND we are not grounded...
if (!doubleJump && !grounded) {
doubleJump = true; // We have double jumped so set to true
dJumpLimit--; // Decrement one from dJumpLimit
}
}
jump = false; // Reset the jump bool to false
//code that will work with the limits?
//GetComponent<Rigidbody2D>().velocity = new Vector2(speed,GetComponent<Rigidbody2D>().velocity.y);
//this will make it stack?
//GetComponent<Rigidbody2D>().velocity = new Vector2(speed,GetComponent<Rigidbody2D>().velocity.x);
//GetComponent<Rigidbody2D>().velocity = new Vector2(speed,GetComponent<Rigidbody2D>().velocity.y);
}
}

Categories