【制作100个unity游戏之26】unity2d横版卷轴动作类游10(附带项目源码)

简介: 【制作100个unity游戏之26】unity2d横版卷轴动作类游10(附带项目源码)

前言

欢迎来到【制作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:这里只实现简单的交互效果,如果你想实现打开宝箱随机掉落战利品物品,可以参考我之前的文章:

【Unity实战】按物品掉落率,随机掉落战利品物品系统

【unity实战】基于权重的随机事件

源码

源码不出意外的话我会放在最后一节

目录
相关文章
|
3天前
|
存储 JSON 关系型数据库
【unity实战】制作unity数据保存和加载系统——大型游戏存储的最优解
【unity实战】制作unity数据保存和加载系统——大型游戏存储的最优解
12 2
|
3天前
|
图形学
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)(上)
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)
10 2
|
3天前
|
存储 JSON 图形学
【unity实战】制作unity数据保存和加载系统——小型游戏存储的最优解
【unity实战】制作unity数据保存和加载系统——小型游戏存储的最优解
6 0
|
3天前
|
图形学
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)(下)
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)(下)
8 0
|
3天前
|
存储 JSON 关系型数据库
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版13(完结,附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版13(完结,附带项目源码)
9 0
|
3天前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版3(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版3(附带项目源码)
14 2
|
3天前
|
图形学
【制作100个unity游戏之28】花半天时间用unity复刻童年4399经典小游戏《黄金矿工》(附带项目源码)
【制作100个unity游戏之28】花半天时间用unity复刻童年4399经典小游戏《黄金矿工》(附带项目源码)
13 0
|
3天前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版2(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版2(附带项目源码)
8 1
|
3天前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版12(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版12(附带项目源码)
9 0
|
3天前
|
存储 图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版11(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版11(附带项目源码)
8 0