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); } } }