admin 管理员组文章数量: 1087818
unity2D学习(11)角色受伤弹开、用UI Text显示血量
1 角色受伤弹开
想法:角色如果碰撞到敌人,就会显示受伤动画,且受伤后会向和敌人碰撞的相反方向弹开。
动画转移:
- idle->hurt:injured为true
- hurt->idle:injured为false,ground为true
- jump->hurt:injured为true
- run->hurt:injured为true
OnTriggerEnter2D 和OnCollisionEnter2D介绍
作用:都是碰撞/接触到会自动触发的函数
区别:
- OnTriggerEnter2D:取消物理碰撞,在触发时执行。
- OnCollisionEnter2D:造成物理碰撞,在碰撞时执行。
使用条件:
- OnTriggerEnter2D:双方都有碰撞体,运动一方必须是刚体,至少一方勾选Trigger触发器。
- OnCollisionEnter2D:双方都有碰撞体,运动一方必须是刚体,双方都不可勾选Trigger触发器。
这里使用OnCollisionEnter2D,因为角色碰撞到敌人受伤,需要造成物理碰撞。
Tag和Layer的介绍
作用:都是对GameObject进行分类
区别:
- Tag:是字符串。用于定义一类事物,如子弹、敌人之类的,方便查找游戏物件,以及在触碰时判断游戏物件。
- Layer:是个32位的值,最多只有32个Layer。和物理系统有关,让 Camera 指定哪些物件要被画出来、让 Light 指定哪些物件要被照明、让物理射线确认哪些物件要被侦测到。
这次的和敌人碰撞属于触碰时判断游戏物件,所以采用了Tag来判断触碰的对象是不是敌人。
为之前设置Crab敌人的Tag设置为Enemy。
受伤弹开
思路:受伤弹开,要朝着碰撞的相反方向弹开。
方向切换代码:
void Flip(){face = (face == 1) ? -1 : 1;//在墙上跳出的话,动画要和原来相反transform.localScale = new Vector2(face, 1);//切换方向}
判断碰撞方向,选择动画是否反转:
void AccordingDirectionFlip(Collision2D collision)//根据敌人方向,安排玩家转向{if (collision != null)//如果玩家出现视野中{int direction;if (collision.transform.position.x < transform.position.x){direction = -1;//玩家在敌人的左边}else{direction = 1;//玩家在敌人的右边}if (direction != face)//表示玩家朝向和敌人相对方位不一致{//Debug.Log(direction);Flip();}}}
受伤反弹:
void Hurt(Collision2D collision)//受伤代码入口{onHurt = true;AccordingDirectionFlip(collision);rig.velocity = new Vector2(face * moveForce * Time.deltaTime, jumpForce * Time.deltaTime);//反弹}
在OnCollisionEnter2D里面添加触发的内容:
void OnCollisionEnter2D(Collision2D collision){if (collision.gameObject.tag == "Enemy"){Hurt(collision);}}
游戏效果:
关于动画切换的代码可以在文章末尾总代码中查看,因为牵扯到之前的代码有点多,思路主要是添加了一个Bool类型OnHurt来判断是否在受伤状态。
2 入门UI显示血量
想法:角色受伤后会扣除一定的血量,然后这些血量用UI Text在画面中显示。
设置UI显示血量:
新建UI画布Canvas
在新建的Canvas下新建两个Text,一个Text用来标识血量,另一个Text用来显示血量数值,分别命名为Hp、HpNumber。
修改Text的内容、大小、颜色,到合适游戏的情况。
把UI Text的显示固定在左上角,先把锚点固定在左上角(下图被红色圆圈圈起来的),因为在画面上拖动的UI Text的位置都是相对于锚点。把下图的Rect Transform方框里面选择固定在左上角,然后拖动之前的建立好的Text到左上角。
用代码修改血量:
需要的头文件using UnityEngine.UI;需要的变量private Text HpNumberText;private float HP;//角色血量初始化的时候获取"HpNumber"的UI TextHpNumberText= GameObject.Find("HpNumber").GetComponent<Text>();//获取ui对于的textHP=100f;//初始角色血量在OnCollisionEnter2D里面进行血量显示的修改void OnCollisionEnter2D(Collision2D collision){if (collision.gameObject.tag == "Enemy"){HP -= 25f;//碰到一次敌人减去25血量HpNumberText.text = HP.ToString();Hurt(collision);}}
3 总代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class PlayerController : MonoBehaviour
{private Rigidbody2D rig;//刚体private Animator Anim;//角色的Animator[Header("Layers")]public LayerMask groundLayer;//用来开启layer[Space][Header("Speed")][SerializeField] private float moveSpeed=360f;//移动速度private float climbSpeed=100f;//爬行速度[Space][Header("Force")]private float moveForce=150f;//移动力private float jumpForce=575f;//跳跃力[Space][Header("Frequency")]private int jumpMax=2;//跳跃次数的上线private int jumpNum=0;//当前跳跃的次数[Space][Header("Booleans")][SerializeField] private bool falling = false;//用来标记是否是下落状态[SerializeField] private bool onWall;//是否在墙上[SerializeField] private bool onJumping;//是否正在跳跃中[SerializeField] private bool onGround;//是否正在地上[SerializeField] private bool onHurt;//是否受伤[Space][Header("Collision")]private float collisionRadius = 0.15f;//碰撞半径public Vector2 bottomOffset, rightOffset, leftOffset;//下左右相对于角色中心的二维向量private Collider2D coll;//角色的碰撞器[Space][Header("UI")]private Text HpNumberText;[Space]private float face;//记录角色朝向private float HP;//角色血量//初始化void Start(){rig = GetComponent<Rigidbody2D>();//获取主角刚体组件Anim = GetComponent<Animator>();//获取主角动画组件coll = GetComponent<Collider2D>();//获取角色碰撞器HpNumberText= GameObject.Find("HpNumber").GetComponent<Text>();//获取ui对于的textgroundLayer = 1 << 8;//开启Ground的layer层,Ground在layer8onWall = false;//初始不在墙上onJumping = false;//初始不正在跳跃onGround = true;//初始在地上face = 1;//初始朝向向右边moveSpeed = 360f;//移动速度HP = 100f;bottomOffset = new Vector2(0,-1.6f);rightOffset = new Vector2(0.61f,-1.3f);leftOffset = new Vector2(-0.72f,-1.3f);onHurt = false;}//固定的时间间隔执行,不受游戏帧率的影响void FixedUpdate(){Movement();changeAnimator();}//控制移动void Movement(){Debug.Log("sfjalsf");//当按下你设置的建则返回一个有加速度的值,从1或者-1 过渡到0//得到正数对应正半轴,负数对应负半轴的方向float moveMultiple = Input.GetAxis("Horizontal");//当按下你设置好的键盘就会返回1和-1这两个值float faceDirection = Input.GetAxisRaw("Horizontal");//获取纵轴float verticalMove = Input.GetAxis("Vertical");if (onGround)//在地上{move(moveMultiple, faceDirection);//左右移动if (touchWall())//是否可爬墙,碰到墙{if (verticalMove>0)//是否有爬墙的行为,按向上键{onGround = false;onWall = true;Climb(verticalMove);}}if (Input.GetButtonDown("Jump")){onGround = false;onJumping = true;Jump();}}else if (onJumping)//在空中跳跃{if (touchWall())//可以爬墙{onJumping = false;//关闭现在状态onWall = true;//开启下一个状态Climb(verticalMove);//爬行jumpNum = 0;//跳跃次数清零}else if (Input.GetButtonDown("Jump"))//二段跳{Jump();}}else if (onWall)//在墙上{if(Input.GetButtonDown("Jump")){onWall = false;onJumping = true;Flip();Jump();}else if (touchWall())//如果碰到墙,就说明还在爬{Climb(verticalMove);}else//如果说爬到了末端,就可以有跳跃行为,不然的话难爬到地面{onWall = false;onJumping = true;Jump();}}}void Flip()//翻转{face = (face == 1) ? -1 : 1;//在墙上跳出的话,动画要和原来相反transform.localScale = new Vector2(face, 1);}bool isGround()//判断是否碰地{return Physics2D.OverlapCircle((Vector2)transform.position + bottomOffset, collisionRadius, groundLayer);//判断是否碰到地面}bool touchWall()//判断是否碰到墙{return Physics2D.OverlapCircle((Vector2)transform.position + rightOffset, collisionRadius, groundLayer)|| Physics2D.OverlapCircle((Vector2)transform.position + leftOffset, collisionRadius, groundLayer); }void move(float moveMultiple,float faceDirection)//移动代码{//角色左右移动if (moveMultiple != 0){//velocity表示速度,Vector表示向量rig.velocity = new Vector2(moveMultiple * moveSpeed * Time.deltaTime, rig.velocity.y);//输入x,y向量,数值*方向}//角色朝向修改if (faceDirection != 0){//Scale,代表缩放,Localscale代表的是当前物体相对于父物体的缩放,通过正负不修改大小来实现左右朝向修改transform.localScale = new Vector2(faceDirection, 1);face = faceDirection;//face参数的获取,在每次按下左右按键的时候获取}}void Jump()//跳跃代码{if(jumpNum < jumpMax){rig.velocity = new Vector2(face*moveForce*Time.deltaTime, jumpForce * Time.deltaTime);jumpNum++;} }void Hurt(Collision2D collision)//受伤{onHurt = true;AccordingDirectionFlip(collision);rig.velocity = new Vector2(face * moveForce * Time.deltaTime, jumpForce * Time.deltaTime);}void AccordingDirectionFlip(Collision2D collision)//根据敌人方向,安排玩家转向{if (collision != null)//如果玩家出现视野中{int direction;if (collision.transform.position.x < transform.position.x){direction = -1;//玩家在敌人的左边}else{direction = 1;//玩家在敌人的右边}if (direction != face)//表示方向不一致{//Debug.Log(direction);Flip();}}}void Climb(float verticalMove)//爬墙代码{rig.velocity = new Vector2(rig.velocity.x,climbSpeed * verticalMove* Time.deltaTime);//输入x,y向量,数值*方向}void changeAnimator()//动画切换{if (onGround){Anim.SetFloat("speed", Mathf.Abs(rig.velocity.x));//速度是向量if (onHurt){Anim.SetBool("injured", true);//Anim.SetBool("ground", false);onGround = false;}}if (onWall)//如果在墙上{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;//当前跳跃次数清零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;//落地的话,当前跳跃次数清零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()//绘制辅助线{Gizmos.color = Color.red;//辅助线颜色//绘制圆形辅助线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;//碰到一次敌人减去25血量HpNumberText.text = HP.ToString();Hurt(collision);}}
}
本文标签: unity2D学习(11)角色受伤弹开用UI Text显示血量
版权声明:本文标题:unity2D学习(11)角色受伤弹开、用UI Text显示血量 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1694376481a251358.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论