unity2D learning (11) character injury bounces off, and UI Text displays blood volume

1 character is injured and bounces off

Idea: if a character collides with an enemy, it will display an animation of the injury, and it will bounce away in the opposite direction of the collision.

Animation transfer:

  • Idle - > hurt: adjusted to true
  • Hurt - > idle: adjusted is false, ground is true
  • Jump - > hurt: adjusted is true
  • Run - > hurt: adjusted to true

Introduction to OnTriggerEnter2D and OnCollisionEnter2D

Function: it is the function that will trigger automatically when collision / contact occurs

Difference:

  • OnTriggerEnter2D: cancels the physical collision and executes when triggered.
  • OnCollisionEnter2D: causes a physical collision, which is performed at the time of collision.

Service conditions:

  • OnTriggerEnter2D: both sides have collision bodies, one side of the motion must be a rigid body, and at least one side checks the Trigger.
  • OnCollisionEnter2D: there are collision bodies on both sides. One side of the motion must be a rigid body. Neither side can check Trigger.

OnCollisionEnter2D is used here, because the character collides with the enemy and is injured, which needs to cause physical collision.

Introduction to Tag and Layer

Function: it is used to classify GameObject s

Difference:

  • Tag: is a string. It is used to define a kind of things, such as bullets and enemies, to facilitate the search of game objects, and to judge game objects when touching.
  • Layer: it is a 32-bit value, with a maximum of 32 layers. Related to the physical system, let the Camera specify which objects to be drawn, let the Light specify which objects to be illuminated, and let the physical ray confirm which objects to be detected.

This collision with the enemy belongs to the game object judgment when touching, so Tag is used to judge whether the object touched is the enemy.

Set the Tag of the Crab Enemy to Enemy.

Injured open

Train of thought: when you are injured, bounce away in the opposite direction of collision.

Direction switching code:

    void Flip()
    {
        face = (face == 1) ? -1 : 1;//If you jump out of the wall, the animation should be the opposite of the original
        transform.localScale = new Vector2(face, 1);//Switching direction
    }

Determine the collision direction and select whether the animation reverses:

    void AccordingDirectionFlip(Collision2D collision)//According to the direction of the enemy, arrange the player to turn
    {
        if (collision != null)//If the player appears in view
        {
            int direction;
            if (collision.transform.position.x < transform.position.x)
            {
                direction = -1;//The player is on the left side of the enemy
            }
            else
            {
                direction = 1;//Players on the right side of the enemy
            }
            if (direction != face)//Indicates that the player's direction is inconsistent with the enemy's relative position
            {
                //Debug.Log(direction);
                Flip();
            }
        }
    }

Injury rebound:

    void Hurt(Collision2D collision)//Injury code entry
    {
        onHurt = true;
        AccordingDirectionFlip(collision);
        rig.velocity = new Vector2(face * moveForce * Time.deltaTime, jumpForce * Time.deltaTime);//rebound
    }

Add trigger content in OnCollisionEnter2D:

    void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Enemy")
        {
            Hurt(collision);
        }
    }

Game effect:

The code of animation switching can be viewed in the general code at the end of the article, because there are a lot of previous codes involved. The main idea is to add a Bool type OnHurt to judge whether it is in the injured state.

2 entry UI shows blood volume

Idea: after the character is injured, a certain amount of blood will be deducted, and then the blood volume will be displayed in the screen with UI Text.

Set UI display blood volume:

New UI Canvas canvas

Create two new texts under the new Canvas. One Text is used to identify the blood volume, and the other Text is used to display the blood volume value, named Hp and HpNumber respectively.

Modify the content, size and color of Text to fit the game.

Fix the display of UI Text in the upper left corner, first fix the anchor point in the upper left corner (the figure below is circled by a red circle), because the position of UI Text dragged on the screen is relative to the anchor point. Select and fix the Rect Transform box in the top left corner, and then drag the previously created Text to the top left corner.

Modify the blood volume with code:

    Required header file
    using UnityEngine.UI;
    //Required variables
    private Text HpNumberText;
    private float HP;//Role blood volume
    //Get UI Text of "HpNumber" during initialization
    HpNumberText= GameObject.Find("HpNumber").GetComponent<Text>();//Get text for ui
    HP=100f;//Initial character health
    //Modify the blood volume display in OnCollisionEnter2D
    void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Enemy")
        {
            HP -= 25f;//Hit an enemy and lose 25 HP
            HpNumberText.text = HP.ToString();
            Hurt(collision);
        }
    }

3 total code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class PlayerController : MonoBehaviour
{
    private Rigidbody2D rig;//rigid body
    private Animator Anim;//Character's Animator
    [Header("Layers")]
    public LayerMask groundLayer;//To open the layer
    [Space]
    [Header("Speed")]
    [SerializeField] private float moveSpeed=360f;//Moving speed
    private float climbSpeed=100f;//Creep speed
    [Space]
    [Header("Force")]
    private float moveForce=150f;//Mobility
    private float jumpForce=575f;//Jumping force
    [Space]
    [Header("Frequency")]
    private int jumpMax=2;//Jump times online
    private int jumpNum=0;//Number of current jumps
    [Space]
    [Header("Booleans")]
    [SerializeField] private bool falling = false;//Used to mark whether it is falling
    [SerializeField] private bool onWall;//Is it on the wall
    [SerializeField] private bool onJumping;//Jumping or not
    [SerializeField] private bool onGround;//Is it on the ground
    [SerializeField] private bool onHurt;//Are you injured?
    [Space]
    [Header("Collision")]
    private float collisionRadius = 0.15f;//Collision radius
    public Vector2 bottomOffset, rightOffset, leftOffset;//The two-dimensional vector of the bottom left and right relative to the character Center
    private Collider2D coll;//Character's Collider
    [Space]
    [Header("UI")]
    private Text HpNumberText;
    [Space]
    private float face;//Record character orientation
    private float HP;//Role blood volume
    
    //Initialization
    void Start()
    {
        rig = GetComponent<Rigidbody2D>();//Get lead rigid body component
        Anim = GetComponent<Animator>();//Get the main character animation component
        coll = GetComponent<Collider2D>();//Get character Collider
        HpNumberText= GameObject.Find("HpNumber").GetComponent<Text>();//Get text for ui
        groundLayer = 1 << 8;//Turn on the layer layer of ground. Ground is on layer 8
        onWall = false;//Not on the wall initially
        onJumping = false;//Not jumping at first
        onGround = true;//First on the ground
        face = 1;//Initial orientation to the right
        moveSpeed = 360f;//Moving speed
        HP = 100f;
        bottomOffset = new Vector2(0,-1.6f);
        rightOffset = new Vector2(0.61f,-1.3f);
        leftOffset = new Vector2(-0.72f,-1.3f);
        onHurt = false;
    }
    //Fixed time interval execution, not affected by game frame rate
    void FixedUpdate()
    {
        Movement();
        changeAnimator();
    }
    //Control mobile
    void Movement()
    {
        Debug.Log("sfjalsf");
        //When you press the build you set, it will return a value with acceleration, from 1 or - 1 to 0
        //The positive number corresponds to the positive half axis and the negative number corresponds to the direction of the negative half axis
        float moveMultiple = Input.GetAxis("Horizontal");
        //When you press the keyboard you set, it will return to 1 and - 1
        float faceDirection = Input.GetAxisRaw("Horizontal");
        //Get vertical axis
        float verticalMove = Input.GetAxis("Vertical");
        if (onGround)//On the ground
        {
            move(moveMultiple, faceDirection);//Left and right movement
            if (touchWall())//Whether it can climb the wall or not
            {
                if (verticalMove>0)//If there is climbing behavior, press up
                {
                    onGround = false;
                    onWall = true;
                    Climb(verticalMove);
                }
            }
            if (Input.GetButtonDown("Jump"))
            {
                onGround = false;
                onJumping = true;
                Jump();
            }
        }
        else if (onJumping)//Jump in the air
        {
            if (touchWall())//You can climb the wall.
            {
                onJumping = false;//Close current state
                onWall = true;//Open next state
                Climb(verticalMove);//Crawl
                jumpNum = 0;//Clear the number of jumps
            }
            else if (Input.GetButtonDown("Jump"))//Two leg jump
            {
                Jump();
            }
        }
        else if (onWall)//On the wall
        {
            if(Input.GetButtonDown("Jump"))
            {
                onWall = false;
                onJumping = true;
                Flip();
                Jump();
                
            }
            else if (touchWall())//If you touch the wall, you are still climbing
            {
                Climb(verticalMove);
            }
            else//If you climb to the end, you can jump, otherwise it's hard to climb to the ground
            {
                onWall = false;
                onJumping = true;
                Jump();
            }
        }
    }
    void Flip()//Flip
    {
        face = (face == 1) ? -1 : 1;//If you jump out of the wall, the animation should be the opposite of the original
        transform.localScale = new Vector2(face, 1);
    }
    bool isGround()//Judge whether to touch the ground
    {
        return Physics2D.OverlapCircle((Vector2)transform.position + bottomOffset, collisionRadius, groundLayer);//Judge if it touches the ground
    }
    bool touchWall()//Judge if it touches the wall
    {
        return Physics2D.OverlapCircle((Vector2)transform.position + rightOffset, collisionRadius, groundLayer)
            || Physics2D.OverlapCircle((Vector2)transform.position + leftOffset, collisionRadius, groundLayer); 
    }
    void move(float moveMultiple,float faceDirection)//Mobile code
    {
        //Character moves left and right
        if (moveMultiple != 0)
        {
            //velocity represents speed, Vector represents Vector
            rig.velocity = new Vector2(moveMultiple * moveSpeed * Time.deltaTime, rig.velocity.y);//Input x, y vector, value * direction
        }
        //Character orientation modification
        if (faceDirection != 0)
        {
            //Scale stands for scaling. Localscale stands for scaling of the current object relative to the parent object. The left and right directions can be modified by not changing the size
            transform.localScale = new Vector2(faceDirection, 1);
            face = faceDirection;//Get the face parameter every time you press the left and right buttons
        }
    }
    void Jump()//Skip code
    {
        if(jumpNum < jumpMax)
        {
            rig.velocity = new Vector2(face*moveForce*Time.deltaTime, jumpForce * Time.deltaTime);
            jumpNum++;
        }   
    }
    void Hurt(Collision2D collision)//Injured
    {
        onHurt = true;
        AccordingDirectionFlip(collision);
        rig.velocity = new Vector2(face * moveForce * Time.deltaTime, jumpForce * Time.deltaTime);
    }
    void AccordingDirectionFlip(Collision2D collision)//According to the direction of the enemy, arrange the player to turn
    {
        if (collision != null)//If the player appears in view
        {
            int direction;
            if (collision.transform.position.x < transform.position.x)
            {
                direction = -1;//The player is on the left side of the enemy
            }
            else
            {
                direction = 1;//Players on the right side of the enemy
            }
            if (direction != face)//Indicates inconsistent direction
            {
                //Debug.Log(direction);
                Flip();
            }
        }
    }
    void Climb(float verticalMove)//Wall climbing code
    {
        rig.velocity = new Vector2(rig.velocity.x,climbSpeed * verticalMove* Time.deltaTime);//Input x, y vector, value * direction
    }
    void changeAnimator()//Animation switching
    {
        if (onGround)
        {
            Anim.SetFloat("speed", Mathf.Abs(rig.velocity.x));//Velocity is a vector
            if (onHurt)
            {
                Anim.SetBool("injured", true);
                //Anim.SetBool("ground", false);
                onGround = false;
            }
        }
        if (onWall)//If it's on the wall
        {
            Anim.SetBool("wall", true);
            if (Anim.GetBool("ground") == false)
            {
                Anim.SetBool("ground", true);
            }
        }
        else
        {
            Anim.SetBool("wall", false);
        }
        if (onJumping)
        {
            if (onHurt)
            {
                Anim.SetBool("injured", true);
                jumpNum = 0;//Clear the current jumping times
                falling = false;
                onJumping = false;
            }
            else if (Anim.GetBool("ground"))
            {
                falling = false;
                Anim.SetBool("ground", false);
            }
            else 
            {
                if (falling&&isGround())
                {
                    Anim.SetBool("ground", true);
                    jumpNum = 0;//When landing, the current number of jumps is cleared
                    falling = false;
                    onJumping = false;
                    onGround = true;
                }
                else if(rig.velocity.y < 0)
                {
                    falling = true;
                }
            }

        }
        if (onHurt)
        {
            if (falling && isGround())
            {
                Anim.SetBool("injured", false);
                Anim.SetBool("ground", true);
                falling = false;
                onGround = true;
                onHurt = false;
            }
            else if (rig.velocity.y < 0)
            {
                falling = true;
            }
        }
    }
    void OnDrawGizmos()//Draw guides
    {
        Gizmos.color = Color.red;//Guide color
        //Draw a circular guide
        Gizmos.DrawWireSphere((Vector2)transform.position + bottomOffset, collisionRadius);
        Gizmos.DrawWireSphere((Vector2)transform.position + rightOffset, collisionRadius);
        Gizmos.DrawWireSphere((Vector2)transform.position + leftOffset, collisionRadius);
    }
    void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Enemy")
        {
            HP -= 25f;//Lose 25 HP when encountering an enemy
            HpNumberText.text = HP.ToString();
            Hurt(collision);
        }
    }
}

 

72 original articles published, 26 praised and 10 thousand visited+
Private letter follow

Keywords: Mobile

Added by techgearfree on Thu, 05 Mar 2020 14:27:40 +0200