2D Character not jumping issue in Unity - c#

I'm new to Unity and C#, trying to make a 2D game.
The animator controller screenshot with all the transition is attached, the (isGrounded) bool from idle to jump is false, from jump to idle is true, and from run to jump is false, but in this case, the character doesn't jump, it shakes in its place transitioning from idle to jump very quickly. When I remove the jump animation the character moves normally but of course no jumping. What could be the problem here?
This is also the CharacterController2D script:
public float jumpForce = 600f;
// player health
public int playerHealth = 1;
// LayerMask to determine what is considered ground for the player
public LayerMask whatIsGround;
internal void EnemyBounce(CharacterController2D characterController2D)
{
throw new NotImplementedException();
}
// Transform just below feet for checking if player is grounded
public Transform groundCheck;
// player can move?
// we want this public so other scripts can access it but we don't want to show in editor as it might confuse designer
[HideInInspector]
public bool playerCanMove = true;
// SFXs
public AudioClip coinSFX;
public AudioClip deathSFX;
public AudioClip fallSFX;
public AudioClip jumpSFX;
public AudioClip victorySFX;
// private variables below
// store references to components on the gameObject
Transform _transform;
Rigidbody2D _rigidbody;
Animator _animator;
AudioSource _audio;
// hold player motion in this timestep
float _vx;
float _vy;
// player tracking
bool _facingRight = true;
bool _isGrounded = false;
bool _isRunning = false;
bool _canDoubleJump = false;
// store the layer the player is on (setup in Awake)
int _playerLayer;
// number of layer that Platforms are on (setup in Awake)
int _platformLayer;
void Awake()
{
// get a reference to the components we are going to be changing and store a reference for efficiency purposes
_transform = GetComponent<Transform>();
_rigidbody = GetComponent<Rigidbody2D>();
if (_rigidbody == null) // if Rigidbody is missing
Debug.LogError("Rigidbody2D component missing from this gameobject");
_animator = GetComponent<Animator>();
if (_animator == null) // if Animator is missing
Debug.LogError("Animator component missing from this gameobject");
_audio = GetComponent<AudioSource>();
if (_audio == null)
{ // if AudioSource is missing
Debug.LogWarning("AudioSource component missing from this gameobject. Adding one.");
// let's just add the AudioSource component dynamically
_audio = gameObject.AddComponent<AudioSource>();
}
// determine the player's specified layer
_playerLayer = this.gameObject.layer;
// determine the platform's specified layer
_platformLayer = LayerMask.NameToLayer("Platform");
}
// this is where most of the player controller magic happens each game event loop
void Update()
{
// exit update if player cannot move or game is paused
if (!playerCanMove || (Time.timeScale == 0f))
return;
// determine horizontal velocity change based on the horizontal input
_vx = CrossPlatformInputManager.GetAxisRaw("Horizontal");
// Determine if running based on the horizontal movement
if (_vx != 0)
{
_isRunning = true;
}
else
{
_isRunning = false;
}
// set the running animation state
_animator.SetBool("Running", _isRunning);
// get the current vertical velocity from the rigidbody component
_vy = _rigidbody.velocity.y;
// Check to see if character is grounded by raycasting from the middle of the player
// down to the groundCheck position and see if collected with gameobjects on the
// whatIsGround layer
_isGrounded = Physics2D.Linecast(_transform.position, groundCheck.position, whatIsGround);
// allow double jump after grounded
if (_isGrounded)
{
_canDoubleJump = true;
}
// Set the grounded animation states
_animator.SetBool("Grounded", _isGrounded);
if (_isGrounded && CrossPlatformInputManager.GetButtonDown("Jump")) // If grounded AND jump button pressed, then allow the player to jump
{
DoJump();
}
else if (_canDoubleJump && CrossPlatformInputManager.GetButtonDown("Jump")) // If candoublejump and jump button pressed, then allow player to double jump
{
DoJump();
// disable double hump after double jumping since you can only really do it once
_canDoubleJump = false;
}
// If the player stops jumping mid jump and player is not yet falling
// then set the vertical velocity to 0 (he will start to fall from gravity)
if (CrossPlatformInputManager.GetButtonUp("Jump") && _vy > 0f)
{
_vy = 0f;
}
// Change the actual velocity on the rigidbody
_rigidbody.velocity = new Vector2(_vx * moveSpeed, _vy);
// if moving up then don't collide with platform layer
// this allows the player to jump up through things on the platform layer
// NOTE: requires the platforms to be on a layer named "Platform"
Physics2D.IgnoreLayerCollision(_playerLayer, _platformLayer, (_vy > 0.0f));
}
// Checking to see if the sprite should be flipped
// this is done in LateUpdate since the Animator may override the localScale
// this code will flip the player even if the animator is controlling scale
void LateUpdate()
{
// get the current scale
Vector3 localScale = _transform.localScale;
if (_vx > 0) // moving right so face right
{
_facingRight = true;
}
else if (_vx < 0)
{ // moving left so face left
_facingRight = false;
}
// check to see if scale x is right for the player
// if not, multiple by -1 which is an easy way to flip a sprite
if (((_facingRight) && (localScale.x < 0)) || ((!_facingRight) && (localScale.x > 0)))
{
localScale.x *= -1;
}
// update the scale
_transform.localScale = localScale;
}
// if the player collides with a MovingPlatform, then make it a child of that platform
// so it will go for a ride on the MovingPlatform
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag == "MovingPlatform")
{
this.transform.parent = other.transform;
}
}
// if the player exits a collision with a moving platform, then unchild it
void OnCollisionExit2D(Collision2D other)
{
if (other.gameObject.tag == "MovingPlatform")
{
this.transform.parent = null;
}
}
//make the player jump
void DoJump()
{
// reset current vertical motion to 0 prior to jump
_vy = 0f;
// add a force in the up direction
_rigidbody.AddForce(new Vector2(4, jumpForce));
// play the jump sound
PlaySound(jumpSFX);
}
// do what needs to be done to freeze the player
void FreezeMotion()
{
playerCanMove = false;
_rigidbody.velocity = new Vector2(0, 0);
_rigidbody.isKinematic = true;
}
// do what needs to be done to unfreeze the player
void UnFreezeMotion()
{
playerCanMove = true;
_rigidbody.isKinematic = false;
}
// play sound through the audiosource on the gameobject
void PlaySound(AudioClip clip)
{
_audio.PlayOneShot(clip);
}
// public function to apply damage to the player
public void ApplyDamage(int damage)
{
if (playerCanMove)
{
playerHealth -= damage;
if (playerHealth <= 0)
{ // player is now dead, so start dying
PlaySound(deathSFX);
StartCoroutine(KillPlayer());
}
}
}
// public function to kill the player when they have a fall death
public void FallDeath()
{
if (playerCanMove)
{
playerHealth = 0;
PlaySound(fallSFX);
StartCoroutine(KillPlayer());
}
}
// coroutine to kill the player
IEnumerator KillPlayer()
{
if (playerCanMove)
{
// freeze the player
FreezeMotion();
// play the death animation
_animator.SetTrigger("Death");
// After waiting tell the GameManager to reset the game
yield return new WaitForSeconds(2.0f);
if (GameManager.gm) // if the gameManager is available, tell it to reset the game
GameManager.gm.ResetGame();
else // otherwise, just reload the current level
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
public void CollectCoin(int amount)
{
PlaySound(coinSFX);
if (GameManager.gm) // add the points through the game manager, if it is available
GameManager.gm.AddPoints(amount);
}
// public function on victory over the level
public void Victory()
{
PlaySound(victorySFX);
FreezeMotion();
_animator.SetTrigger("Victory");
if (GameManager.gm) // do the game manager level compete stuff, if it is available
GameManager.gm.LevelCompete();
}
// public function to respawn the player at the appropriate location
public void Respawn(Vector3 spawnloc)
{
UnFreezeMotion();
playerHealth = 1;
_transform.parent = null;
_transform.position = spawnloc;
_animator.SetTrigger("Respawn");
}
public void EnemyBounce()
{
DoJump();
}
}
I also tried adding a separate Jump script, it doesn't work.

Just gonna take some notes while reading the code...
This:
// Determine if running based on the horizontal movement
if (_vx != 0)
{
_isRunning = true;
}
else
{
_isRunning = false;
}
// set the running animation state
_animator.SetBool("Running", _isRunning);
Can be replaced by
_isRunning = _vx != 0;
_animator.SetBool("Running", _isRunning);
or even just creating a property accessor
bool _isRunning {
get {
return _vx != 0;
}
}
As for your actual question; I can't see your transitions but I'm assuming there's something wrong with them, keep trying to debug it by removing SetBools, and check the Animator on what is being triggered. The Any State -> Idle looks suspicious.

Related

How to have a rigidbody object "ride" a falling platform, while still being able to move horizontally

I'm making a 2D game in Unity, which has falling platforms that the player can "ride" down. I want the player to still be able to move left or right (ie horizontally) while standing on a falling platform. Without additional code, just using the Rigidbody physics, the player does fall along with the platform, but the falling is choppy, and the game doesn't always see the player is standing on the platform (important because the player can only jump while standing on something).
I've tried setting the player object's transform.translate, which prevents the player from moving left or right as long as it is touching the platform. I've also tried setting the player object's transform.parent to the platform's transform, but that "glues" the player in place to the platform, preventing even jumping. I've also tried searching for a solution/example, and there are plenty of examples for riding a left-right moving platform, but I haven't been able to get those examples to work for a falling platform.
Here is the script controlling the players left-right movement and jumping. This is attached to the player object:
public class Player : MonoBehaviour
{
public float jumpForce = 5;
public float horizontalSpeed = 0.1F;
public LayerMask whatIsGround;
private Rigidbody2D rb2d;
private Collider2D myCollider;
private bool grounded;
private float lastHorizontalInput;
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
myCollider = GetComponent<Collider2D>();
}
void Update()
{
// If the player is trying to jump, only do so if the player is on a platform
grounded = Physics2D.IsTouchingLayers(myCollider, whatIsGround);
if (Input.GetKeyDown(KeyCode.Space) && grounded)
{
rb2d.velocity = new Vector2(rb2d.velocity.x, jumpForce);
}
MoveHorizonltally();
}
private void MoveHorizonltally()
{
float horizontalVelocity;
float horizontalInput = Input.GetAxis("Horizontal");
horizontalVelocity = GetHorizontalVelocity(horizontalInput);
if (horizontalVelocity != 0)
{
rb2d.position = new Vector2(rb2d.position.x + horizontalVelocity, rb2d.position.y);
}
}
private float GetHorizontalVelocity(float horizontalInput)
{
// Default to no horizontal motion
float result = 0;
bool leftPressed = Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow);
bool rightPressed = Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow);
// Only a left key is being pressed; the player is going left
if (leftPressed && !rightPressed)
{
result = -1 * horizontalSpeed;
}
// Only a right key is being pressed; the player is going right
else if (rightPressed && !leftPressed)
{
result = horizontalSpeed;
}
// Both keys are being pressed
else if (leftPressed && rightPressed)
{
// The most recent key press gets priority; ignore the oldest key press
if (lastHorizontalInput < 0)
{
// Oldest key pressed is a left direction, so go right
result = horizontalSpeed;
}
else
{
// Oldest key pressed is a right direction, so go left
result = -1 * horizontalSpeed;
}
}
lastHorizontalInput = horizontalInput;
return result;
}
}
Here is the script responsible for making the platform fall. This is attached to the platform object:
public class PlatformFalling : MonoBehaviour
{
public float fallSpeed;
private GameObject player;
public void Start()
{
player = GameObject.FindGameObjectWithTag("Player");
}
// Update is called once per frame
void Update()
{
bool playerIsOnPlatform = player.GetComponent<Collider2D>().IsTouching(GetComponent<Collider2D>()); ;
Vector2 fallDistance = Vector2.down * fallSpeed;
transform.Translate(fallDistance);
if (playerIsOnPlatform)
{
player.transform.Translate(fallDistance);
}
}
}

Jumping Perpendicular to rotating Object

I have a simple jumping game. In this game there are rotating platforms, and a player object.
Whenever the player clicks the mouse button, it should jump and sticks to the next platform and rotates with it, until he clicks again. I want the game object to jump perpendicular to the rotating platforms.
If i use Vector3.up the game object will fall down instead. But I want the player to jump in the direction of a green arrow and stick to the next platform.
I'm posting here, because I've posted on the Unity Forms 2 weeks ago and still got no answer.
TLDR:
here is what i've worked on recently :
my player code :
Rigidbody2D Rig;
public float Force =500;
public bool gamejump = true;
public Transform platformParent;
bool playerforce = false;
bool setpos = false;
Vector2 pos = new Vector2(0, 0);
public Collider2D Ccollider;
public bool bottom =false;
void Start()
{
Rig = GetComponent<Rigidbody2D>();
Ccollider = GetComponent<CircleCollider2D>();
}
private void FixedUpdate()
{
if (gamejump == true)
{
transform.SetParent(null);
Rig.isKinematic = false;
setpos = false;
}
else
{
transform.SetParent(platformParent);
Rig.AddForce(new Vector2(0, 0));
Rig.isKinematic = true;
if (setpos == false)
{
setpos = true;
transform.position = pos;
}
}
}
void OnTriggerStay2D(Collider2D other)
{
if (other.tag == "Rotate")
{
//if (Input.GetKey(KeyCode.Space))
if (Input.GetMouseButton(0))
{
gamejump = true;
if (bottom == true)
{
Rig.AddForce(other.transform.up * Force);
}
else
{
Rig.AddForce(other.transform.up * -Force);
}
}
}
}
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Rotate")
{
ContactPoint2D contact = collision.contacts[0];
pos = contact.point;
if (collision.contacts.Length>0)
{
bottom = true;
}
else
{
bottom = false;
}
gamejump = false;
}
}
}
and my platform code :
public bool counterclockwise;
Transform player;
player2 playerCode;
public Collider2D collidPlatform;
private int speed=100;
// Start is called before the first frame update
void Start()
{
player = GameObject.Find("player").GetComponent<Transform>();
playerCode = FindObjectOfType<player2>();
if (counterclockwise)
speed = -speed;
}
void FixedUpdate()
{
// float currentZ = transform.eulerAngles.z;
/* if (Limit == true)
{
if (currentZ > 180)
{
currentZ = 180;
}
Vector3 newEuler = new Vector3(0, 0, currentZ);
transform.eulerAngles = newEuler;
}
//transform.Rotate(new Vector3(0, 0, speed * Time.deltaTime));
}
*/
}
private void OnCollisionEnter2D(Collision2D collision)
{
playerCode.platformParent = transform;
playerCode.Ccollider = collidPlatform;
}
}
and still got crazy results, suddenly the player rotates in the air or dose not sticks to a platform and falls or when it sticks to a platform ,it
Increases platform's speed (i know it's because of rigid body that attaches to platforms but if i remove it and try to control it manually it dose not work the way i want ,so if you could give me suggestion on how to rotate platforms manually and without rigid body so i be able to control the speed .
if you make the player a child object of the platform using transform.parent, then jump using transform.up on the players local axis, if you want the player to land on the same position where they jumped, the player can remain parented to the rotating platform, otherwise you need to remove the player as a child object to the platform after you jump. But since you are using rigidbody physics, I think you will get mixed results from gravity.

Unity Standard assets Cross Platform input not working

I imported Unity Standard Assets cross platform input successfully
In imported cross Platfrom script UnityStandardAssets.CrossCrossPlatformInput is working perfectly
but when i use it in CharacterController2D script that not respoonding
shows errors
unknown package actually namespace in C#
and in file path for standard assets is
Assets\Standard Assets\CrossPlatformInput\Scripts
and CharacterController2D path is
Assets\Scripts
following CharacterController2D script is
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement; // include so we can load new scenes
using UnityStandardAssets.CrossCrossPlatformInput; //even this line shows error
public class CharacterController2D : MonoBehaviour {
// player controls
[Range(0.0f, 10.0f)] // create a slider in the editor and set limits on moveSpeed
public float moveSpeed = 3f;
public float jumpForce = 600f;
// player health
public int playerHealth = 1;
// LayerMask to determine what is considered ground for the player
public LayerMask whatIsGround;
// Transform just below feet for checking if player is grounded
public Transform groundCheck;
// player can move?
// we want this public so other scripts can access it but we don't want to show in editor as it might confuse designer
[HideInInspector]
public bool playerCanMove = true;
// SFXs
public AudioClip coinSFX;
public AudioClip deathSFX;
public AudioClip fallSFX;
public AudioClip jumpSFX;
public AudioClip victorySFX;
// private variables below
// store references to components on the gameObject
Transform _transform;
Rigidbody2D _rigidbody;
Animator _animator;
AudioSource _audio;
// hold player motion in this timestep
float _vx;
float _vy;
// player tracking
bool facingRight = true;
bool isGrounded = false;
bool isRunning = false;
bool canDoubleJump = false;
// store the layer the player is on (setup in Awake)
int _playerLayer;
// number of layer that Platforms are on (setup in Awake)
int _platformLayer;
void Awake () {
// get a reference to the components we are going to be changing and store a reference for efficiency purposes
_transform = GetComponent<Transform> ();
_rigidbody = GetComponent<Rigidbody2D> ();
if (_rigidbody==null) // if Rigidbody is missing
Debug.LogError("Rigidbody2D component missing from this gameobject");
_animator = GetComponent<Animator>();
if (_animator==null) // if Animator is missing
Debug.LogError("Animator component missing from this gameobject");
_audio = GetComponent<AudioSource> ();
if (_audio==null) { // if AudioSource is missing
Debug.LogWarning("AudioSource component missing from this gameobject. Adding one.");
// let's just add the AudioSource component dynamically
_audio = gameObject.AddComponent<AudioSource>();
}
// determine the player's specified layer
_playerLayer = this.gameObject.layer;
// determine the platform's specified layer
_platformLayer = LayerMask.NameToLayer("Platform");
}
// this is where most of the player controller magic happens each game event loop
void Update()
{
// exit update if player cannot move or game is paused
if (!playerCanMove || (Time.timeScale == 0f))
return;
// determine horizontal velocity change based on the horizontal input
_vx = CrossPlatformInputManager.GetAxisRaw ("Horizontal");
// Determine if running based on the horizontal movement
if (_vx != 0)
{
isRunning = true;
} else {
isRunning = false;
}
// set the running animation state
_animator.SetBool("Running", isRunning);
// get the current vertical velocity from the rigidbody component
_vy = _rigidbody.velocity.y;
// Check to see if character is grounded by raycasting from the middle of the player
// down to the groundCheck position and see if collected with gameobjects on the
// whatIsGround layer
isGrounded = Physics2D.Linecast(_transform.position, groundCheck.position, whatIsGround);
///checking if can do double jump or not
if (isGrounded)
{
canDoubleJump = true;
}
// Set the grounded animation states
_animator.SetBool("Grounded", isGrounded);
if(isGrounded && CrossPlatformInputManager.GetButtonDown("Jump")) // If grounded AND jump button pressed, then allow the player to jump
{
doJump ();
}
else if(canDoubleJump && CrossPlatformInputManager.GetButtonDown("Jump"))
{
doJump ();
canDoubleJump = false; //disabling dpuble jump after single jump
}
// If the player stops jumping mid jump and player is not yet falling
// then set the vertical velocity to 0 (he will start to fall from gravity)
if(CrossPlatformInputManager.GetButtonUp("Jump") && _vy>0f)
{
_vy = 0f;
}
// Change the actual velocity on the rigidbody
_rigidbody.velocity = new Vector2(_vx * moveSpeed, _vy);
// if moving up then don't collide with platform layer
// this allows the player to jump up through things on the platform layer
// NOTE: requires the platforms to be on a layer named "Platform"
Physics2D.IgnoreLayerCollision(_playerLayer, _platformLayer, (_vy > 0.0f));
}
// Checking to see if the sprite should be flipped
// this is done in LateUpdate since the Animator may override the localScale
// this code will flip the player even if the animator is controlling scale
void LateUpdate()
{
// get the current scale
Vector3 localScale = _transform.localScale;
if (_vx > 0) // moving right so face right
{
facingRight = true;
} else if (_vx < 0) { // moving left so face left
facingRight = false;
}
// check to see if scale x is right for the player
// if not, multiple by -1 which is an easy way to flip a sprite
if (((facingRight) && (localScale.x<0)) || ((!facingRight) && (localScale.x>0))) {
localScale.x *= -1;
}
// update the scale
_transform.localScale = localScale;
}
// if the player collides with a MovingPlatform, then make it a child of that platform
// so it will go for a ride on the MovingPlatform
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag=="MovingPlatform")
{
this.transform.parent = other.transform;
}
}
// if the player exits a collision with a moving platform, then unchild it
void OnCollisionExit2D(Collision2D other)
{
if (other.gameObject.tag=="MovingPlatform")
{
this.transform.parent = null;
}
}
// do what needs to be done to freeze the player
void FreezeMotion() {
playerCanMove = false;
_rigidbody.isKinematic = true;
}
// do what needs to be done to unfreeze the player
void UnFreezeMotion() {
playerCanMove = true;
_rigidbody.isKinematic = false;
}
// play sound through the audiosource on the gameobject
void PlaySound(AudioClip clip)
{
_audio.PlayOneShot(clip);
}
// public function to apply damage to the player
public void ApplyDamage (int damage) {
if (playerCanMove) {
playerHealth -= damage;
if (playerHealth <= 0) { // player is now dead, so start dying
PlaySound(deathSFX);
StartCoroutine (KillPlayer ());
}
}
}
//Public Jump function
public void doJump()
{
// reset current vertical motion to 0 prior to jump
_vy = 0f;
// add a force in the up direction
_rigidbody.AddForce (new Vector2 (0, jumpForce));
// play the jump sound
PlaySound(jumpSFX);
}
//EnemyJump function
public void EnemyJump()
{
doJump ();
}
// public function to kill the player when they have a fall death
public void FallDeath () {
if (playerCanMove) {
playerHealth = 0;
PlaySound(fallSFX);
StartCoroutine (KillPlayer ());
}
}
// coroutine to kill the player
IEnumerator KillPlayer()
{
if (playerCanMove)
{
// freeze the player
FreezeMotion();
// play the death animation
_animator.SetTrigger("Death");
// After waiting tell the GameManager to reset the game
yield return new WaitForSeconds(2.0f);
if (GameManager.gm) // if the gameManager is available, tell it to reset the game
GameManager.gm.ResetGame();
else // otherwise, just reload the current level
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
public void CollectCoin(int amount) {
PlaySound(coinSFX);
if (GameManager.gm) // add the points through the game manager, if it is available
GameManager.gm.AddPoints(amount);
}
// public function on victory over the level
public void Victory() {
PlaySound(victorySFX);
FreezeMotion ();
_animator.SetTrigger("Victory");
if (GameManager.gm) // do the game manager level compete stuff, if it is available
GameManager.gm.LevelCompete();
}
// public function to respawn the player at the appropriate location
public void Respawn(Vector3 spawnloc) {
UnFreezeMotion();
playerHealth = 1;
_transform.parent = null;
_transform.position = spawnloc;
_animator.SetTrigger("Respawn");
}
}
This is first time that I have used cross platform input
so I don't even know why this error is showing
Sorry to Bother you guys.
I think i found my error in this code
actually i mistakenly write
using UnityStandardAssets.CrossCrossPlatformInput;
instead of
using UnityStandardAssets.CrossPlatformInput;
that's why it's showing error Unknown Namespace Under Standard Unity Assests
Actually I am new to Unity and also new to game development
i think that's why this problem happen
also, you need to use a compiler definition as shown, i was stuck on it for a long time, but found it written in the guidelines that come along with standard asset package..
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
// CROSS_PLATFORM_INPUT
public class Player : MonoBehaviour
{
public float speed = 6f;
Vector2 moveVelocity;
public Rigidbody2D rb;
Vector2 movement;
void Update()
{
Vector2 moveInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
moveVelocity = moveInput * speed;
}
void FixedUpdate()
{
rb.MovePosition(rb.position + moveVelocity * Time.fixedDeltaTime);
}
public void Up()
{
FixedUpdate();
}
private void OnTriggerEnter2D(Collider2D target)
{
if (target.tag == "Enemy")
{
GameManager.instance.PlayerDied();
Debug.Log("ok");
}
if (target.tag == "Finish")
{
Debug.Log("ok");
GameManager.instance.PlayerWin();
}
}
}

How to set the yield wait for seconds back to 60 seconds when the player gets hit by an enemy?

Basically I want to make a player that can transform into demon at will whenever the user press the power-up button however I want the transformation to end after 60 seconds (when the transformation ends I want the player revert back to his original state). I also want the transformation to end if the player gets hit by an enemy. So far I've made this code and it works but I'm having trouble resetting the yield wait for seconds back to 60 seconds when if the player gets hit by an enemy and if the user decided to press the button to transform the player back into a demon. Can anyone help me with this problem?
In my hierarchy I have my player as the parent and my demon player as the child. A playermovement script attached to the player as well as the transformation script below:
public GameObject demon;
public BoxCollider2D col;
public Renderer rend;
public ParticleSystem par1;
public static Vector3 target;
void Start () {
target = transform.position;
}
void Update () {
target.z = transform.position.z;
}
public void DemonCharacter() {
StartCoroutine (PowerUpCoroutine ());
}
private IEnumerator PowerUpCoroutine() {
yield return new WaitForSeconds (0.3f);
par1.Play (); // particle system animation to cover transformation happening
par1.transform.position = target;
yield return new WaitForSeconds (0.2f);
demon.SetActive (true); // activates demon gameobject
rend.enabled = false; // deactivate players spriterenderer
col.enabled = false;
yield return new WaitForSeconds (60f);
demon.SetActive (false); // deactivates demon gameobject
rend.enabled = true; // activate players spriterenderer
col.enabled = true;
par1.Stop ();
}
And on my demon player, I attached this script;
I works but when the user clicks on the button to transform into a demon the yield waitforseconds doesn't stop, so when the player transform into a demon seconds later the demon player transforms back into the player rather than resetting the yield wait for seconds.
public BoxCollider2D Playercol;
public Renderer PlayerRend;
void Start()
{
}
void Update ()
{
}
void OnTriggerEnter2D(Collider2D col) {
if (col.tag == "enemy") {
demon.SetActive (false);
PlayerRend.enabled = true;
Playercol.enabled = true;
}
}
Another way than what #m.rogalski suggested would be to use a simple float variable as timer:
public GameObject demon;
public BoxCollider2D col;
public Renderer rend;
public ParticleSystem par1;
public static Vector3 target;
private float demonTimer;
void Start()
{
target = transform.position;
demonTimer = 0.0f;
}
void Update()
{
target.z = transform.position.z;
if (demonTimer > 0.0f)
{
demonTimer -= Time.deltaTime;
if (demonTimer <= 0.0f)
{
demon.SetActive(false);
rend.enabled = true;
col.enabled = true;
}
}
}
public void DemonCharacter()
{
par1.Play();
par1.transform.position = target;
demon.SetActive(true);
rend.enabled = false;
col.enabled = false;
demonTimer = 60.0f;
}
public void CancelDemon()
{
demonTimer = 0.0f;
}
Hope this helps,
My suggestion would be for you to modify your Coroutine to not use WaitForSeconds but use it's own timing calculations.
// create the flag indicating interruption
bool _interrupt = false;
// create your coroutine
IEnumerator PowerUpCoroutine()
{
// set the time you want to hold transformation
const float TRANSFORMATION_INTERVAL = 60.0f;
// currently elapsed time
float currentlyElapsed = 0.0f;
// add your logic for pre-transformation
while ( currentlyElapsed < TRANSFORMATION_INTERVAL && !_interrupt )
{
yield return null;
currentlyElapsed += Time.deltaTime;
}
// add post-transformation logic
// revert transformation process
_interrupt = false;
}
Now if you run this coroutine calling StartCoroutine(PowerUpCoroutine()); you can interrupt it setting _interrupt flag to true. eg :
public void Interrupt()
{
_interrupt = true;
}
// in some update :
if ( gotHitThisFrame == true )
Interrupt();

2d standard assets prefab characterRobotBoy jumped into the boxCollider

I am using the standard 2d assets to learn developing 2d game with Unity, and I place a sprite with box-collider-2d, and choose the default standard assets CharacterRobotBoy to mess around with.
But I find that if I jumped and it's highly likely that the character will jump into the sprite which was intended to be made as a ground, but this will not happen every time. hope could get some help with that.
find the problem hard to describe and upload a video on youtue
EDIT
will just paste the script from the demo asset as required.
File PlatformerCharacter2D.cs
using System;
using UnityEngine;
namespace UnityStandardAssets._2D
{
public class PlatformerCharacter2D : MonoBehaviour
{
[SerializeField] private float m_MaxSpeed = 10f; // The fastest the player can travel in the x axis.
[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%
[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
private Transform m_GroundCheck; // A position marking where to check if the player is grounded.
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.
private Transform m_CeilingCheck; // A position marking where to check for ceilings
const float k_CeilingRadius = .01f; // Radius of the overlap circle to determine if the player can stand up
private Animator m_Anim; // Reference to the player's animator component.
private Rigidbody2D m_Rigidbody2D;
private bool m_FacingRight = true; // For determining which way the player is currently facing.
private void Awake()
{
// Setting up references.
m_GroundCheck = transform.Find("GroundCheck");
m_CeilingCheck = transform.Find("CeilingCheck");
m_Anim = GetComponent<Animator>();
m_Rigidbody2D = GetComponent<Rigidbody2D>();
}
private void FixedUpdate()
{
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;
}
m_Anim.SetBool("Ground", m_Grounded);
// Set the vertical animation
m_Anim.SetFloat("vSpeed", m_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 && m_Anim.GetBool("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;
}
}
// Set whether or not the character is crouching in the animator
m_Anim.SetBool("Crouch", crouch);
//only control the player if grounded or airControl is turned on
if (m_Grounded || m_AirControl)
{
// Reduce the speed if crouching by the crouchSpeed multiplier
move = (crouch ? move*m_CrouchSpeed : move);
// The Speed animator parameter is set to the absolute value of the horizontal input.
m_Anim.SetFloat("Speed", Mathf.Abs(move));
// Move the character
m_Rigidbody2D.velocity = new Vector2(move*m_MaxSpeed, m_Rigidbody2D.velocity.y);
// 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 && m_Anim.GetBool("Ground"))
{
// Add a vertical force to the player.
m_Grounded = false;
m_Anim.SetBool("Ground", 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;
}
}
}
Script Platformer2DUserControl.cs
using System;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
namespace UnityStandardAssets._2D
{
[RequireComponent(typeof (PlatformerCharacter2D))]
public class Platformer2DUserControl : MonoBehaviour
{
private PlatformerCharacter2D m_Character;
private bool m_Jump;
private void Awake()
{
m_Character = GetComponent<PlatformerCharacter2D>();
}
private void Update()
{
if (!m_Jump)
{
// Read the jump input in Update so button presses aren't missed.
m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
}
}
private void FixedUpdate()
{
// Read the inputs.
bool crouch = Input.GetKey(KeyCode.LeftControl);
float h = CrossPlatformInputManager.GetAxis("Horizontal");
// Pass all parameters to the character control script.
m_Character.Move(h, crouch, m_Jump);
m_Jump = false;
}
}
}

Categories

Resources