前言
欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第26篇中,我们将探索如何用unity制作一个unity2d横版卷轴动作类游戏,我会附带项目源码,以便你更好理解它。
本节主要实现物品的交互
不同设备播放不同按钮动画
素材
https://crusenho.itch.io/ps4-xbox-controller-buttons
绘制交互按钮 和 箱子
配置不同设备的按钮闪烁动画
新增Sign,触发器控制提示按钮的显示隐藏 监听输入设备播放不同的按钮动画
using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.DualShock; public class Sign : MonoBehaviour { private Animator _animator; // 动画组件 public Transform playerTrans; // 玩家变换组件 public GameObject signSprite; // 标志精灵对象 private bool canPress; // 是否可以按下交互键 PlayerInputControl inputControl; // 玩家输入控制器 private void Awake() { _animator = signSprite.GetComponent<Animator>(); // 获取标志精灵对象上的动画组件 inputControl = new PlayerInputControl(); // 初始化玩家输入控制器 InputSystem.onActionChange += OnActionChange; // 注册输入系统的动作变化事件 } private void OnEnable() { inputControl.Enable(); // 启用玩家输入控制器 } private void OnDisable() { // 禁用输入控制 inputControl.Disable(); } //根据输入设备播放不同的按钮动画 private void OnActionChange(object arg1, InputActionChange change) { if (change == InputActionChange.ActionStarted) { if (IsMobilePlatform()) { _animator.Play("Mobile"); return; } var d = ((InputAction)arg1).activeControl.device; // 获取触发动作的输入设备 switch (d.device) { case Keyboard: // 如果是键盘 _animator.Play("Keyboard"); // 播放键盘动画 break; case DualShockGamepad: // 如果是PS手柄 _animator.Play("Ps"); // 播放PS手柄动画 break; default: break; } } } // 检测是否在移动设备上运行 bool IsMobilePlatform() { // 使用SystemInfo.deviceType检测当前设备类型是否为Handheld(移动设备) if (SystemInfo.deviceType == DeviceType.Handheld) { return true; } else { // 对于Standalone平台,再结合Application.platform检测是否为Android或iOS if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer) { return true; } else { return false; } } } private void Update() { signSprite.GetComponent<SpriteRenderer>().enabled = canPress; signSprite.transform.localScale = playerTrans.localScale; // 设置标志精灵对象的缩放与玩家变换组件相同 } private void OnTriggerStay2D(Collider2D other) { if (other.CompareTag("Interactable")) // 如果与交互对象碰撞 { canPress = true; // 设置可以按下交互键 } } private void OnTriggerExit2D(Collider2D other) { canPress = false; // 离开交互对象范围后取消可以按下交互键 } }
配置
效果
接口实现场景互动
这里我们使用
接口
的形式,让代码更通用,这样我们不就需要特别定义是宝箱,我要怎么做,是传送门,我们要怎么做,只要你连接了这个接口之后,我都可以用比如TriggerAction的方法,进行交互
配置交互按钮
新增接口
interface IInteractable { void TriggerAction(); }
新增Chest,控制宝箱互动
public class Chest : MonoBehaviour, IInteractable { private SpriteRenderer spriteRenderer; public Sprite openSprite; public Sprite closeSprite; public bool isDone; private void Awake() { spriteRenderer = GetComponent<SpriteRenderer>(); } private void OnEnable() { spriteRenderer.sprite = isDone ? openSprite : closeSprite; } public void TriggerAction() { Debug.Log("打开箱子"); if(!isDone){ OpenChest(); } } //打开箱子 private void OpenChest(){ spriteRenderer.sprite = openSprite; GetComponent<Collider2D>().enabled = false; isDone = true; } }
修改Sign
IInteractable targetItem; private void Awake() { //... inputControl.Player.Interaction.started += PlayerInteraction; } private void PlayerInteraction(InputAction.CallbackContext context){ if(canPress){ targetItem.TriggerAction(); } } private void OnTriggerStay2D(Collider2D other) { if (other.CompareTag("Interactable")) // 如果与交互对象碰撞 { canPress = true; // 设置可以按下交互键 targetItem = other.GetComponent<IInteractable>(); } }
配置
效果
ps:这里只实现简单的交互效果,如果你想实现打开宝箱随机掉落战利品物品,可以参考我之前的文章:
源码
源码不出意外的话我会放在最后一节