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);
}
}
Related
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)
I have a GameObject with a Rigidbody, Mesh Collider, Skinned Mesh Renderer, and the below script.
I'm trying to check if it is Grounded, but the Console continuously spits out "Not Grounded!" when it is, so obviously something is wrong here. Can anyone please help?
public class GroundCheck : MonoBehaviour
{
public float Height;
bool IsGrounded;
Ray ray;
MeshRenderer renda;
private void Start()
{
Height = renda.bounds.size.y;
}
void Update()
{
if (Physics.Raycast(transform.position, Vector3.down, Height))
{
IsGrounded = true;
Debug.Log("Grounded");
}
else
{
IsGrounded = false;
Debug.Log("Not Grounded!");
}
}
}
Another option for checking if the rigidBody is grounded is using the OnTriggerStay function.
void OnTriggerStay(Collider other)
{
if (other.Transform.Tag == "Ground")
{
IsGrounded = true;
Debug.Log("Grounded");
}
else
{
IsGrounded = false;
Debug.Log("Not Grounded!");
}
}
I've checked your code with a simple scene with a plane and a cube, and it works.
It only spawns NotGrounded when it's clearly "floating" arround or the object has the half of it's body outside the plane.
Check those things drawing the Ray, this should give your more information about what is going wrong with your mesh.
Also if the problem is how the game is perceiving the Height of your Skinned Mesh you can also use SkinnedMeshRenderer.localBounds who returns the AABB of the object.
There is a better way to check if your rigidbody is grounded than collision checking and rays. But first, why is collision checking not a good idea: If your level is a single model the walls will too be tagged with the "Ground" tag and hitting a wall will return true, which you don't want. Rays can be used, but that's too much math you don't need to waste time with.
Instead of using new objects and methods, just check if the position is changing:
private float lastYposition;
private bool grounded;
void Start() {
lastYposition = transform.position.y;
}
void Update() {
grounded = (lastYposition == transform.position.y); // Checks if Y has changed since last frame
lastYposition = transform.position.y;
}
From here it's up to you what logic you are going to add.
Get the closest contact point to the bottom. Check if the contact normal is within range.
void OnCollisionStay(Collision collision)
{
var bottom = renderer.bounds.center;
bottom.y -= renderer.bounds.extents.y;
float minDist = float.PositiveInfinity;
float angle = 180f;
// Find closest point to bottom.
for (int i = 0; i < collision.contactCount; i++)
{
var contact = collision.GetContact(i);
var tempDist = Vector3.Distance(contact.point, bottom);
if(tempDist < minDist)
{
minDist = tempDist;
// Check how close the contact normal is to our up vector.
angle = Vector3.Angle(transform.up, contact.normal);
}
}
// Check if the angle is too steep.
if (angle <= 45f) IsGrounded = true;
else IsGrounded = false;
}
void OnCollisionExit(Collision collision)
{
IsGrounded = false;
}
I came up with this answer after reading amitklein's answer.
private void Jump()
{
if (Input.GetKeyDown(KeyCode.Space))
{
if (transform.position.y == 0f)
{
rb.AddRelativeForce(Vector3.up * jumpForce);
}
}
}
I used this approach to jump using addrelativeforce of rigid body only when the position of y in 0.
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.
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);
Hi there fellow Overflowers!
I have recently dived into C# in Unity, because I believe that it has more functionality than UnityScript, and I come from a C++ background. Referencing some code from a 2D script in the Sample Assets, I have tried to create my own. The code is below:
using UnityEngine;
public class PlayerControl : MonoBehaviour {
//Variables
[HideInInspector]
public bool facingForward = true; //for Flip() Function
bool isGround = true; //for Grounded() Function
public float maxSpeed = 5.0f; //Terminal sideways velocity
public float HorizonAxis; //Checks for a/d movement
public float jumpFloat = 1000.0f; //Modular, use Unity Editor
public float moveFloat = 400.0f; // " "
void Start() {
//transform.position(0,0,0);
}
void Flip() {
facingForward = !facingForward; //switches boolean
Vector3 theScale = transform.localScale; //assigns vector to localscale of Player
theScale.x *= -1; //if x = 1, position becomes -1 and thus flips
transform.localScale = theScale; //reassigns the localscale to update theScale
}
bool Grounded() {
if (transform.position.y > 1) { //if position of gameObject is greater that 1, not grounded
isGround = false;
} else {
isGround = true;
}
return isGround; //function returns true or false for isGround
}
void Update() {
HorizonAxis = /*UnityEngine.*/Input.GetAxis ("Horizontal"); //assigns HorizonAxis to a/d movement from UnityEngine.Input
if (HorizonAxis * rigidbody2D.velocity.x > maxSpeed) { // if Input a/d by current x velocity of gameObject is greater than maxSpeed
rigidbody2D.velocity = new Vector2 (Mathf.Sign (rigidbody2D.velocity.x) * maxSpeed, rigidbody2D.velocity.y); //1 or -1 times the max speed, depending on direction
}
else if (HorizonAxis * rigidbody2D.velocity.x < maxSpeed) { //if Input a/d is less than terminal velocity
rigidbody2D.AddForce(Vector2.right * HorizonAxis * moveFloat); //add force to the right equivilant to Input by scalar moveFloat
}
if (Input.GetButtonDown ("Jump")) { //If Space
if(isGround) { //and isGround returns true
rigidbody2D.AddForce(new Vector2(0.0f, jumpFloat)); //add upwards force to bottom of rigidbody2D
isGround = false; //Resets isGround value
}
}
if (HorizonAxis > 0 && !facingForward) {//if UnityEngine.Input is to the right and facing left
Flip (); //execute
}
else if (HorizonAxis < 0 && facingForward) { //else
Flip (); //execute
}
}
}
Unfortunately, the code just doesn't work. I get no compile errors, but any Input does not effect the current position of the character. Should I be using transform.Translate to change the position, or stick with AddForce to a Vector2 until the character hits a maxSpeed?
Thanks heaps :)
I (kinda) fixed the jerky jumping issue, basically you look for the input in the Update() function which switches a Bool in FixedUpdate()
void Update () {
if (Input.GetKeyDown (KeyCode.Space) && playerGrounded) {
playerJumped = true;
}
}
Then in FixedUpdate() I looked for this Bool and did my AddForce
void FixedUpdate () {
if (playerJumped) {
playerJumped = false;
rigidbody2D.AddForce (new Vector2 (0, jumpForce),ForceMode2D.Impulse);
playerGrounded = false;
}
}
Setting playerJumped to false makes sure it doesn't run several times and the player can't jump again because I also set the grounded to false. grounded gets set back to true when the player collides with things tagged "ground".
I'm still new to Unity and C# overall so I can't guarantee this is the best (or even a good) way. Hope I could help somehow though ;)