【用unity实现100个游戏之17】从零开始制作一个类幸存者肉鸽(Roguelike)游戏5(附项目源码)(上):https://developer.aliyun.com/article/1552344
双手放置武器
控制武器移动转向排序
新增Hand,控制左右手翻转位置,具体的位置数据可以自己按情况修改
public class Hand : MonoBehaviour { public bool isLeft; // 是否是左手 public SpriteRenderer spriter; // 手的sprite renderer组件 SpriteRenderer player; // 玩家的sprite renderer组件 Quaternion rightRot = Quaternion.Euler(0, 0, -25); Quaternion rightRotReverse = Quaternion.Euler(0, 0, 25); Vector3 leftPos = new Vector3(0.4f, -0.2f, 0); Vector3 leftPosReverse = new Vector3(0.1f, -0.2f, 0); void Awake() { player = GetComponentsInParent<SpriteRenderer>()[1]; // 获取玩家的sprite renderer组件 } void LateUpdate() { bool isReverse = player.flipX; // 判断玩家是否水平翻转 if (isLeft) { // 处理左手 spriter.flipX = isReverse; spriter.sortingOrder = isReverse ? 6 : 4; transform.localPosition = !isReverse ? leftPos : leftPosReverse; } else { // 处理右手 transform.localRotation = isReverse ? rightRotReverse : rightRot; spriter.flipX = isReverse; spriter.sortingOrder = isReverse ? 4 : 6; } } }
左右手挂载脚本
效果
默认先隐藏武器,去除默认的武器精灵图片
修改ItemData
public Sprite hand;
物品数据,绑定对应的武器精灵图片数据
数据联动
修改Player
public Hand[] hands; hands = GetComponentsInChildren<Hand>();
修改Weapon
public void Init(ItemData data) { //。。。 Hand hand = player.hands[(int)data.itemType]; hand.spriter.sprite = data.hand; }
效果,现在开启不同的能力,会在左右手绑定对应的武器
完善升级界面
绘制升级UI
配置道具物品描述
修改Item,注意删除了原来的lateupdate方法
TextMeshProUGUI textName; TextMeshProUGUI textDesc; void Awake() { // 。。。 textLevel = texts[0]; textName = texts[1]; textDesc = texts[2]; textName.text = data.itemName; } void OnEnable() { textLevel.text = "Lv." + (level + 1); switch (data.itemType) { case ItemData.ItemType.Melee: case ItemData.ItemType.Range: textDesc.text = string.Format(data.itemDesc, data.damages[level] * 100, data.counts[level]); break; case ItemData.ItemType.Glove: case ItemData.ItemType.Shoe: textDesc.text = string.Format(data.itemDesc, data.damages[level] * 100); break; default: textDesc.text = string.Format(data.itemDesc); break; } }
和之前一样挂载,配置参数
运行效果
控制窗口开启关闭
新增LevelUp代码
public class LevelUp : MonoBehaviour { RectTransform rect; // 用于存储RectTransform组件的引用 void Awake() { rect = GetComponent<RectTransform>(); // 获取LevelUp对象上的RectTransform组件 } /// <summary> /// 显示LevelUp界面 /// </summary> public void Show() { rect.localScale = Vector3.one; // 将界面的缩放设置为(1, 1, 1),即正常大小 } /// <summary> /// 隐藏LevelUp界面 /// </summary> public void Hide() { rect.localScale = Vector3.zero; // 将界面的缩放设置为(0, 0, 0),即隐藏界面 } }
配置点击事件
修改GameManager,人物升级开启面板
public LevelUp uiLevelUp; //加经验和升级 public void GetExp(){ exp++; if(exp == nextExp[level]){ level ++; exp = 0; uiLevelUp.Show(); } }
修改LevelUp,默认给主角一个武器
Item[] items; items = GetComponentsInChildren<Item>(true); public void Select(int index){ items[index].OnClick(); }
修改GameManager
private void Start() { //... uiLevelUp.Select(0); }
效果
时间控制,升级暂停游戏
我们希望升级进行属性选择时,可以暂停游戏
修改GameManager
public bool isLive; public void Stop() { isLive = false; Time.timeScale = 0; } public void Resume() { isLive = true; Time.timeScale = 1; }
修改LevelUp
public void Show() { rect.localScale = Vector3.one; GameManager.instance.Stop(); } public void Hide() { rect.localScale = Vector3.zero; GameManager.instance.Resume(); }
效果
每次升级随机获取属性项目
修改levelUp
public void Show() { Next(); //。。。 } void Next() { // 1. 隐藏所有物品 foreach (Item item in items) { item.gameObject.SetActive(false); } // 2. 随机选择三个不同的索引 int[] ran = new int[3]; while (true) { ran[0] = Random.Range(0, items.Length); ran[1] = Random.Range(0, items.Length); ran[2] = Random.Range(0, items.Length); if (ran[0] != ran[1] && ran[1] != ran[2] && ran[0] != ran[2]) { break; } } // 3. 根据随机索引显示对应的物品 for (int index = 0; index < ran.Length; index++) { Item ranItem = items[ran[index]]; if (ranItem.level == ranItem.data.damages.Length) { //保留最后恢复生命效果 items[4].gameObject.SetActive(true); } else { ranItem.gameObject.SetActive(true); } } }
效果
控制等级上限
修改GameManager
//加经验和升级 public void GetExp() { exp++; if (exp == nextExp[Mathf.Min(level, nextExp.Length -1)]) { level++; exp = 0; uiLevelUp.Show(); } }
修改HUD
case InfoType.Exp: // 处理经验信息逻辑 float curExp = GameManager.instance.exp; float maxExp = GameManager.instance.nextExp[Mathf.Min(GameManager.instance.level, GameManager.instance.nextExp.Length - 1)]; mySlider.value = curExp / maxExp; break;
为了方便测试,可以把升级经验设置少点
效果
参考
【视频】https://www.youtube.com/watch?v=MmW166cHj54&list=PLO-mt5Iu5TeZF8xMHqtT_DhAPKmjF6i3x
源码
源码在最后一节