前言
欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇中,我们将探索如何制作一个类似于七日杀和森林的生存游戏。
本篇内容会比较多,我会分几篇来实现,感兴趣的可以关注一下,以免错过内容更新。
本节主要实现了玩家生命 食物 水状态控制的功能。
生命 食物 水
简单绘制UI
玩家状态脚本
public class PlayerState : MonoBehaviour { public static PlayerState Instance { get; set; } // 单例对象 [Header("玩家的健康状态")] public float currentHealth; // 当前生命值 public float maxHealth; // 最大生命值 [Header("玩家的饱食度状态")] public float currentCalories; // 当前饱食度 public float maxCalories; // 最大饱食度 [Header("玩家的水分状态")] public float currentHydrationPercent; // 当前水分百分比 public float maxHydrationPercent; // 最大水分百分比 private void Awake() { if (Instance == null) { Instance = this; } else { Destroy(gameObject); } } private void Start() { currentHealth = maxHealth; } }
挂载脚本,配置参数
生命值控制
新增HealthBar脚本
public class HealthBar : MonoBehaviour { private Image slider; // 用于显示血条的图片组件 public TextMeshProUGUI healthCounter; // 用于显示当前生命值的文本组件 private float currentHealth; // 当前生命值 private float maxHealth; // 最大生命值 void Awake() { slider = GetComponent<Image>(); } void Update() { currentHealth = PlayerState.Instance.currentHealth; // 获取当前生命值 maxHealth = PlayerState.Instance.maxHealth; // 获取最大生命值 float fillValue = currentHealth / maxHealth; // 计算血条的填充值 slider.fillAmount = fillValue; // 设置填充的值 healthCounter.text = currentHealth + "/" + maxHealth; // 设置生命值文本 } }
挂载脚本,配置参数
运行效果
饱食度控制
修改PlayerState
[Header("玩家的饱食度状态")] public float currentCalories; // 当前饱食度 public float maxCalories; // 最大饱食度 float distanceTravelled = 0;// 已行进距离 Vector3 lastPosition;// 上一帧位置 public GameObject playerBody;// 玩家角色对象 private void Start() { currentHealth = maxHealth; currentCalories = maxCalories; } private void Update() { //根据行进距离扣除饱食度 distanceTravelled += Vector3.Distance(playerBody.transform.position, lastPosition); // 计算已行进距离 lastPosition = playerBody.transform.position;// 更新上一帧位置 if (distanceTravelled >= 5)// 当已行进距离超过5时 { distanceTravelled = 0;// 重置已行进距离 currentCalories -= 1;// 减少饱食度 } }
配置参数
新增CaloriesBar,控制饱食度状态栏
public class CaloriesBar : MonoBehaviour { public TextMeshProUGUI caloriesCounter; private Image slider; private float currentCalories; private float maxCalories; void Awake() { slider = GetComponent<Image>(); } void Update() { currentCalories = PlayerState.Instance.currentCalories; maxCalories = PlayerState.Instance.maxCalories; float fillValue = currentCalories / maxCalories; slider.fillAmount = fillValue; caloriesCounter.text = currentCalories + "/" + maxCalories; } }
配置
效果
水分控制
修改PlayerState
[Header("玩家的水分状态")] public float currentHydrationPercent; // 当前水分百分比 public float maxHydrationPercent; // 最大水分百分比 private void Start() { currentHealth = maxHealth; currentCalories = maxCalories; currentHydrationPercent = maxHydrationPercent; StartCoroutine(decreaseHydration()); } //携程扣水分 IEnumerator decreaseHydration() { while (true) { currentHydrationPercent -= 1; yield return new WaitForSeconds(10f); } }
新增HydrationBar,控制水分显示
public class HydrationBar : MonoBehaviour { public TextMeshProUGUI hydrationCounter; private Image slider; private float currentHydration; private float maxHydration; void Awake() { slider = GetComponent<Image>(); } void Update() { currentHydration = PlayerState.Instance.currentHydrationPercent; maxHydration = PlayerState.Instance.maxHydrationPercent; float fillValue = currentHydration / maxHydration; slider.fillAmount = fillValue; hydrationCounter.text = currentHydration + "%"; } }
配置
效果
源码
源码不出意外的话我会放在最后一节