unity实现角色体力功能【体力条+体力计算】

导读:实现功能

1、角色体力计算

2、角色疲劳动画

3、体力条制作、跟随

默认做好角色的idle/run/walk动画、切换和玩家输入,我使用的是新输入系统,动画时单变量混合树,参数Sports。

【每一部分功能根据自己需求观看哦】

1、角色体力计算

实现效果

当角色奔跑时,每秒减少1体力

角色走路时,体力不变

角色站立不动,每秒体力加1体力

玩家体力耗尽,不可移动

(1)新建一个脚本挂载到角色身上

csharp 复制代码
//角色速度设置,根据isRunning来判断角色是否奔跑
private Animator animator;
private Vector2 playerInputVec;
private float walkSpeed = 2.0f;
private float runSpeed = 5.0f;
private float currentSpeed;
private float targetSpeed;
private bool isRuning;
//疲劳值设置
private float minTired = 0.0f;
public float MinTired
{
    get { return minTired; }
}

private float maxTired = 10.0f;
public float MaxTired
{
    get { return maxTired; }
}
private float currentTired;
public float CurrentTired
{
    get { return currentTired; }
}
private float TiredIndex;

void Start()
{
    animator = GetComponent<Animator>();
}

void FixedUpdate()
{
    MovePlayer();
    CalculateTired();
}

 //移动输入,新输入系统获取玩家输入
public void GetPlayerMoveInput(InputAction.CallbackContext context)
{
   playerInputVec = context.ReadValue<Vector2>();//上下左右
}
    
void MovePlayer()
{
    TiredIndex = currentTired >= maxTired ? 0 : 1;
    targetSpeed = isRuning ? runSpeed : walkSpeed;
    targetSpeed *= playerInputVec.magnitude;//当玩家没按下或没有推动摇杆,目标速度为0
    currentSpeed = Mathf.Lerp(currentSpeed, targetSpeed, 0.5f);
    animator.SetFloat("Sports", currentSpeed);
}

//计算体力值,根据当前的速度来判断角色时走还是跑还是站立不动
void CalculateTired()
{
    if (currentSpeed <= walkSpeed && currentTired >= minTired)
    {
        //角色站立不动,疲劳值每秒-1
        currentTired -= Time.deltaTime;
    }
    else if (currentSpeed >= runSpeed && currentTired <= maxTired)
    {
        //角色跑动,疲劳值+1
        currentTired += Time.deltaTime;
    }
    else
    {
        //角色走动,疲劳值不变
        return;
    }
    //将疲劳值限制在最大最小之间
    currentTired = Mathf.Clamp(currentTired, minTired, maxTired);
}

2、角色体力动画

(1)设置动画

打开角色的动画器,点击图层,新建一个图层命名位"States",该图层来放角色疲惫动画。

点击新建States层右侧的齿轮,可以看到下面的面板内容
其中的权重:代表该层动画的播放的程度【我们通过将疲劳值与权重相关联来表示角色不同程度的疲惫】

在下面的Assets中新建一个Avatar遮罩,并命名

点开新建的遮罩,在右侧选择"人形"(因为是人形动画),我们的疲惫动画只显示在角色的头和躯干,所以只让头和躯干是绿色就可以。

【这里意思是在该层放置的动画只播放躯干和头部的动画,所以选择下面的疲惫动画时建议选择头部和躯干是前后摇动的,显示角色劳累。】

设置好后,将这个遮罩拖到上面新建States层级的遮罩中,将正在混合设置为Additive【想给角色添加特色但又不取代动画】

然后将准备好的疲惫动画放到States层的动画器中,要将动画的循环打开。

这样动画设置好了,接下来通过代码来设置体力值并将体力值与该层的权重相关联。

(2)脚本编写

打开上面的角色脚本,添加如下代码

csharp 复制代码
private int tiredLayerIndex;
//关于TiredWeight根据自己情况设置值
private float TiredWeight = 6.0f;
void Start()
{
    animator = GetComponent<Animator>();
    //获取State动画层级
    tiredLayerIndex = animator.GetLayerIndex("State");
}

在CalculateTired()最后一行添加

csharp 复制代码
//将体力值与播放疲惫动画的权重相关联
    animator.SetLayerWeight(tiredLayerIndex,currentTired/MaxTired*TiredWeight);

3、体力条

实现效果:
消耗体力,体力条出现。疲劳值为零,体力条消失。
跟随
不同疲劳值体力条显示颜色不同

(1)体力条样式制作

【原理,两层sprite,底层是绿色,上层是灰色,随着疲劳值增加,上层的填充从0开始增加到1】

准备一个白色圆环PNG,导入unity,制成Sprite(2D和UI)

在unity中创建UI------image,命名PowerBG,在源图像中拖入这个圆环,并把颜色改为绿色

在该图像下方在新建一个图像,命名ShowPower,将圆环拖进源图像

将ShowPower的图像类型设置为已填充,填充方式Radial 360,填充原点为顶部,填充总数设置为1,不勾选顺时针

这样做好了体力条样式

(2)体力显示,颜色变化

当体力消耗三分之一,体力条变成黄色

当体力消耗三分之二,体力条变成红色

新建一个脚本,挂载到PowerBG上

csharp 复制代码
[SerializeField] 
public Image progressCircle;
public BlackCoatControl showPowerObject;//要显示体力的游戏对象
private float currentTired;
private Image changeColor;
private float changColorIndex=0.3f;

private void Start()
{
    changeColor = this.GetComponent<Image>();
    currentTired = showPowerObject.CurrentTired;
}

private void FixedUpdate()
{
    ToChange();
}

void ToChange()
{
    currentTired = showPowerObject.CurrentTired;
    ToChangeColor();
    progressCircle.fillAmount = currentTired / showPowerObject.MaxTired;
}

//根据体力条不同值,像是不同颜色提示玩家体力耗尽
void ToChangeColor()
{
    if (currentTired>=showPowerObject.MaxTired/3&&currentTired<showPowerObject.MaxTired*2/3)
    {
        changeColor.color = Color.Lerp(Color.green, Color.yellow, 0.7f);
    }

    if (currentTired>=showPowerObject.MaxTired*2/3)
    {
        changeColor.color = Color.Lerp(Color.yellow, Color.red, 0.7f);
    }
}

返回unity,将挂载脚本对象的子物体ShowPower拖到Progress Circle

将游戏对象拖到Show Power Object中

(3)体力条跟随

新建一个脚本挂载到上面的PowerBG对象上

csharp 复制代码
public Transform followed;
private Vector3 offset;
private Vector3 followedScreen;
private bool isRun;

private void Awake()
{
    //使用协程为了防止当播放画面变化,体力条与人物间距离出现偏差。
    StartCoroutine(Wait());
}

void Update()
{
    if (isRun)
    {
        //将要跟随对象得世界坐标位置转化为屏幕空间
        followedScreen = Camera.main.WorldToScreenPoint(followed.transform.position);
        transform.position = followedScreen;
        transform.position = new Vector2(transform.position.x - offset.x, offset.y);
    }

}

IEnumerator Wait()
{
    yield return new WaitForSeconds(1f);
    followedScreen = Camera.main.WorldToScreenPoint(followed.transform.position);
    offset.x = followedScreen.x - transform.position.x;
    offset.z = followedScreen.z - transform.position.z;
    offset.y = transform.position.y;
    isRun = true;
}

返回unity,将游戏对象或游戏对象的子级拖到Followed中,根据自己想要将体力条放的位置来设置。

(4)实现玩家消耗体力时,体力条才出现。不消耗时不显示

在玩家脚本中的添加:

csharp 复制代码
public GameObject Show;

void ShowPowerUI()
{
    if(currentTired!=0)
        Show.SetActive(true);
    else
    {
        Show.SetActive(false);
    }
}

void FixedUpdate()
    {
        ShowPowerUI();
        MovePlayer();
        CalculateTired();
    }

返回unity,在里面拖入上面的体力条对象

最后将PowerBG不显示

这样就完成了。

内容较多,哪里有问题感谢指出。

相关推荐
牙膏上的小苏打23332 小时前
Unity Surround开关后导致获取主显示器分辨率错误
unity·主屏幕
Unity大海4 小时前
诠视科技Unity SDK开发环境配置、项目设置、apk打包。
科技·unity·游戏引擎
浅陌sss9 小时前
Unity中 粒子系统使用整理(一)
unity·游戏引擎
维度攻城狮14 小时前
实现在Unity3D中仿真汽车,而且还能使用ros2控制
python·unity·docker·汽车·ros2·rviz2
为你写首诗ge17 小时前
【Unity网络编程知识】FTP学习
网络·unity
神码编程19 小时前
【Unity】 HTFramework框架(六十四)SaveDataRuntime运行时保存组件参数、预制体
unity·编辑器·游戏引擎
菲fay20 小时前
Unity 单例模式写法
unity·单例模式
火一线1 天前
【Framework-Client系列】UIGenerate介绍
游戏·unity
ZKY_241 天前
【工具】Json在线解析工具
unity·json
ZKY_241 天前
【Unity】处理文字显示不全的问题
unity·游戏引擎