unity玩家血量控制,定时掉血,道具加血

Posted Min-篮球小菜鸡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity玩家血量控制,定时掉血,道具加血相关的知识,希望对你有一定的参考价值。

unity玩家血量控制,定时掉血,道具加血

首先将玩家,加血道具,掉血道具添加进场景中

为玩家挂接碰撞体和刚体

而两种道具只需要挂接碰撞体

 

下面是玩家的挂接脚本

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

public class RubyController : MonoBehaviour

    //设置玩家无敌时间间隔
    public float timelnvincible = 2.0f;
    //设置是否无敌变量
    bool islnvincible;
    //定义变量,进行无敌时间的计时,无敌时间计时器
    float invincibleTimer;

    //设置最大生命值(生命上限)
    public int maxHealth = 5;
    //设置当前生命值的属性health
    //C#中支持面向对象程序设计中的封装概念,对数据成员的保护
    //数据成员变量,默认一般都应该设为私有,只能通过当前类的方法或属性进行访问
    //属性是公有的,可以通过取值器get、赋值器set设定对应字段的访问规则,满足规则才能够访问
    int currentHealth;
    public int health
    
        get  return currentHealth; 
        //set currentHealth=value;
    


    //为了防止角色发生抖动(若要防止角色发生旋转,需要将角色中的Rigidbody 2D组件中的Constraints中的Z轴锁定)
    //声明刚体对象
    Rigidbody2D rigidbody2D;

    //获取用户输入
    float horizontal;
    float vertical;

    //该方法以单位每秒来表示移动速度
    //将速度暴露出来,使其可调
    public float speed = 3.0f;

    private void Start()
    
        //获取当前游戏对象的刚体组件
        rigidbody2D = GetComponent<Rigidbody2D>();
        //游戏开始前,玩家满血
        //初始化当前生命值
        currentHealth = maxHealth;
    

    //每帧调用一次Update
    void Update()
    
        horizontal = Input.GetAxis("Horizontal");
        vertical = Input.GetAxis("Vertical");

        //判断是否处于无敌状态,来进行计时器倒计时
        if(islnvincible)
            //如果无敌,进入倒计时
            //每次update减去一帧所消耗的时间
            invincibleTimer -= Time.deltaTime;
            if (invincibleTimer<0)
            
                islnvincible = false;
            
        
        
    
    //为了使物理计算保持稳定(只要牵扯物理引擎相关方法,都需要放到FixedUpdate函数中)
    //固定时间间隔执行的方法(不论硬件条件如何)
    private void FixedUpdate()
    
        Vector2 position = rigidbody2D.position;
        position.x = position.x + speed * horizontal * Time.deltaTime;//Time.deltaTime表示帧所需要的时间
        //因为每台机器的帧数刷新不同,所以需要乘上各台电脑的每帧刷新的时长,这样就能确保各台电脑每次按下按键后的移动距离都相同
        position.y = position.y + speed * vertical * Time.deltaTime;
        rigidbody2D.MovePosition(position);
    
    //更改生命值的方法
    public void ChangeHealth(int amount)
    
        //假设玩家受伤害的时间间隔是2秒
        if (amount<0)//当玩家扣血时
        
            //判断玩家当前是否处于无敌状态
            if (islnvincible)
            
                return;//当玩家处于无敌状态时,return后面的所有函数内的语句都不执行,不掉血也不输出信息
            
            islnvincible = true;
            invincibleTimer = timelnvincible;
        

        //限制方法,限制当前生命值的赋值范围:0-最大生命值
        currentHealth = Mathf.Clamp(currentHealth+amount,0,maxHealth);//Mathf是一个静态类中的静态方法,不需要创建对象即可直接调用,Mathf是一个通用的数学函数
        //在控制台输出生命信息
        Debug.Log("当前生命值:"+currentHealth+"/"+maxHealth);
    

    // Start is called before the first frame update
    //void Start()
    //
    //    //只有将垂直同步设置成0,才能锁帧,否则锁帧的代码无效(但实际操作上设置为1同样也可锁帧)
    //    //垂直同步的作用就是显著减少游戏画面撕裂、跳帧,因为画面的渲染不是整个画面一同渲染的,而是逐行逐列渲染的
    //    QualitySettings.vSyncCount = 0;
    //    //设置应用程序帧数为10
    //    Application.targetFrameRate = 10;

    //

    // Update is called once per frame
    //void Update()
    //
    //    //获取水平输入,按向左,会获得-0.1f;按向右会获得1.0f
    //    float horizontal = Input.GetAxis("Horizontal");
    //    //获取垂直输入,按向下,会获得-0.1f;按向上会获得1.0f
    //    float vertical = Input.GetAxis("Vertical");
    //    //创建一个Vector2对象positon,用来获取当前对象的位置
    //    //Vector2是一个系统类,是C#中自带的一个类(Unity中的类),Vector2 position来描述2D的位置
    //    Vector2 position = transform.position;
    //    //更改position的x坐标值,让其加上0.1
    //    position.x = position.x + 0.1f*horizontal;
    //    position.y= position.y+ 0.1f*vertical;
    //    //更新当前对象的位置到新的位置
    //    transform.position = position;
    //

在加血道具和减血物体中,由于碰撞需要,需要将碰撞体组件中的Is Trigger勾上,这样玩家不仅可以通过碰撞体触发事件,还能够不被道具影响行进路线

下面是加血道具挂接脚本

为了让加血道具只能够使用一次,当玩家并不满血,拾到加血道具时,加血道具会消失(被销毁)

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

public class HealthCollectible : MonoBehaviour

    //草莓加的血量
    public int amount = 1;
    //用来记录碰撞次数
    //int collideCount=0;
    //添加触发器碰撞事件,每次发生碰撞时,执行器中的代码
    private void OnTriggerEnter2D(Collider2D other)
    
        //collideCount = collideCount + 1;
        //Debug.Log($"和当前物体发生碰撞的对象是:other,当前是第collideCount次碰撞");
        
        //获取Ruby游戏对象的脚本组件对象
        RubyController rubyController = other.GetComponent<RubyController>();
        
        if (rubyController!=null)
        
            //当获取到脚本组件对象的时候再执行下列代码,防止出现错误
            if (rubyController.health<rubyController.maxHealth)
            
                //更改生命值
                rubyController.ChangeHealth(amount);
                //销毁当前游戏对象
                //可以让草莓被吃掉
                Destroy(gameObject);
            
            else
            
                Debug.Log("当前玩家满血,不需要加血");
            
           
        
        else
        
            // 当未获取到对象时(出错了),则报出提示错误
            Debug.LogError("rubyController游戏组件并未获取到......");
        
       
    

减血道具与加血道具类似,将影响血量值改为负数即可

但与加血道具不同的一点是,若不控制每次减血的时间间隔(由于每次刷新都将响应减血),则在一秒内,所有血量都将清空。

所以我们需要设置一个控制器,来解决血量的瞬间减少的问题,该控制器设置在玩家的脚本身上(看上面的玩家脚本,都带有注释),实现的是,玩家走上地刺,每两秒钟间隔会扣一次血,捡到草莓时,草莓消失,玩家加血。

 

下面是减血道具的挂接脚本

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

public class DamageZone : MonoBehaviour

    public int damageNum = -1;//减少的血量
    private void OnTriggerStay2D(Collider2D other)
    
        RubyController rubyController = other.GetComponent<RubyController>();
        if (rubyController!=null)//当获取对象不为空时再进行血量控制函数的调用
        
            rubyController.ChangeHealth(damageNum);
        
    

如有疑问欢迎留言或私信

谢谢!

unity3d的playmaker插件使用教程,六血量显示及处理

这里展示了如何处理和显示血量,如何使用全局变量在多个状态机下传递信息,如何使用类似if的判断,如何进行数据类型转换。


准备工作,血量显示的文本框

技术分享


加血的道具

技术分享


模拟玩家的桶

技术分享


首先,新建一个空的Game Object,命名为HealthManager,管理整个过程

技术分享


添加Setup、UpdateGUI、AddHealth、Listener状态。
添加Add_Health事件。

技术分享


添加全局变量

技术分享


如果在添加全局变量的时候,无法添加并出现以下错误

技术分享


是因为少了一个目录,在Assets\Plugins\PlayMaker目录下添加一个Resources目录即可。

技术分享


添加3个全局变量

添加current_health_i存储血量,类型整型

添加current_health_s用于显示血量,类型字符串

添加health_manager用于传递,类型是GameObject

技术分享


在Health_Cross下添加状态Rotate,添加Rotate动作让十字旋转

技术分享


添加判断范围的Cube。

昨天看了下playmaker的网站,说,有统一的父的话可以方便的获取全部的子。好像是这个意思。先照着做吧。

技术分享


在Cube上添加Setup状态和UpdateHealth状态,添加Health_Pick_Up事件。并在Setup状态下添加Trigger Event动作

技术分享


在UpdateHealth状态下添加Get Parent动作和Destory Object动作,当玩家接触时,销毁自身。

技术分享


这是,要把玩家触碰到信息发送给HealthManager,添加Send Event动作

技术分享


这个时候,全局变量health_manager就起作用了,设置如下

技术分享


这个时候,还需要将HealthManager下的Add_Health事件设置为全局事件,

技术分享


然后把状态机名填入,并选中全局事件Add_Health。

技术分享


全局变量health_manager还没赋值,在HealthManager的Setup状态下,添加Get Owner动作,

技术分享


运行预览,当玩家碰触到加血道具的时候,HealthManager的状态正确触发。

技术分享


在HealthManager的Setup状态下,添加动作:Set Int Value,设置血量为50,

技术分享


在UpdateGUI状态下,添加Convert Int To String动作,转换数据类型,并添加Set GUI Text动作显示血量。

技术分享


在AddHealth状态下添加动作Int Add,修改血量。

技术分享


运行预览,开始状态

技术分享


接触到加血道具,状态触发,血量显示正确

技术分享


添加一个减血的平台,就当是火堆啊,怪物放的陷阱啥的就好。

技术分享


添加Listener、DecreaseHealth状态,

添加decrease_health事件

技术分享


在Listener状态下添加Trigger Event动作,处理进入

技术分享


和加血一样,需要在HealthManager下添加Decrease_Health全局事件。

技术分享


在Cube火堆这边添加Send Event动作,

技术分享


运行预览

技术分享


进入Cube时,状态触发正确。

技术分享


这个时候,当玩家不断拾取加血道具的时候,血量会一直增加,血量小于0也可以继续。

现在来处理这个问题。

由于playmaker插件判断功能的限制,思路如下。
当加完血或减血以后,转到CheckHealth100状态
在这个状态下检测血量是否超过100,
如果超过100,在ResetHealth状态下把血量改回100
如果不超过100,转到CheckHealth0状态下,判断血量是否低于或等于100
当血量小于等于0时,游戏结束。

技术分享

在CheckHealth100状态添加Int Compare动作,第一个值是血量,第二个值是100,

相等、小于,大于分别触发不同动作。

感觉这一段,写代码来得简单些呢。

技术分享


血量超过100时,用Set Int Value动作将血量改回100

技术分享


当血量小于等于0的时候,游戏结束

技术分享


游戏结束就简单显示文字好了。

技术分享


运行预览,当玩家血量到100的时候

技术分享


再吃加血道具,血量不变

技术分享


当玩家血量小于0,显示Game Over.

技术分享





















































































以上是关于unity玩家血量控制,定时掉血,道具加血的主要内容,如果未能解决你的问题,请参考以下文章

FairyGUI & Unity使用动效功能实现血条UI扣血与加血的缓动效果

unity Mirror使用心得一(玩家角色创建,控制,及其攻击其他玩家的血量同步设置)

[UE4]客户端-服务器模式

2022-11-09:给定怪兽的血量为hp 第i回合如果用刀砍,怪兽在这回合会直接掉血,没有后续效果 第i回合如果用毒,怪兽在这回合不会掉血, 但是之后每回合都会掉血,并且所有中毒的后续效果会叠加 给

unity碰到物体血条减少

Java自学-多线程 交互