【Unity3D】实现横版2D游戏——单向平台(简易版)

news/2025/2/1 23:01:49 标签: unity, 单向平台, 横版2D游戏

目录

问题


项目Demo直接使用免费资源:Hero Knight - Pixel Art (Asset Store搜索)

打开Demo场景,进行如下修改,注意Tag是自定义标签SingleDirCollider

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SingleDirCollider : MonoBehaviour
{
    public float minY { get; private set; }
    public float maxY { get; private set; }

    private void Awake()
    {
        var bounds = GetComponent<BoxCollider2D>().bounds;
        minY = bounds.min.y;
        maxY = bounds.max.y;
    }
}

 对HeroKnight增加如下脚本:

核心思路:利用Physics2D.IgnoreCollision(碰撞器1,碰撞器2,[true])忽略或恢复传入的2个碰撞器之间的碰撞。

利用OnTriggerEnter2D去做提前检测角色和平台是否接触,而不是OnCollisionEnter2D,如果使用OnCollisionEnter2D,你会看到碰撞物理效果会先发生,导致忽略碰撞就没有意义了,角色会直接碰到单向平台往下掉。为了保证触发比碰撞先执行,需要将触发器往下偏移一点。当触发时检测到角色在平台之下则直接忽略碰撞直到OnTriggerExit2D触发时,检测角色在平台之上或平台之下才进行恢复碰撞

角色身上会挂有5个小圆形触发器,并且必然在碰撞之前触发的,平台的碰撞器不需要改为触发器,小球触发器也能检测到碰撞器执行触发的。

注意:传递到协程的参数不要是Collision2D,而是Collider2D,假设传的是Collision2D,可能在等待若干秒后Collision2D的collider(Collider2D)已经置空了,因为碰撞消息已经结束了。

利用OnCollisionStay2D 当玩家处于平台上时,按下↓键就会忽略碰撞,从而直接让玩家坠落,直到OnTriggerExit2D触发时,检测角色在平台之上或平台之下才进行恢复碰撞

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HeroColliderController : MonoBehaviour
{
    BoxCollider2D heroCollider;
    bool isOn;
    private void Awake()
    {
        heroCollider = GetComponent<BoxCollider2D>();
    }

    IEnumerator StartIgnoreCollision(Collider2D collider2D)
    {
        Debug.Log("忽略碰撞");
        Physics2D.IgnoreCollision(heroCollider, collider2D); //这2个碰撞体互相忽略碰撞

        //等待人物完整地达到平台上 或 平台下时 退出死循环
        while (isOn)
        {
            yield return new WaitForEndOfFrame();
        }
        Debug.Log("恢复");
        Physics2D.IgnoreCollision(heroCollider, collider2D, false); //恢复
        isOn = false;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        //实现从下往上跳跃穿过单向平台效果
        if (collision != null && collision.gameObject.tag == "SingleDirCollider" && !isOn)
        {
            //this.transform.position.y + 0.062f是人物minY
            if (collision.GetComponent<SingleDirCollider>().maxY > (this.transform.position.y + 0.062f))
            {
                IgnoreCollision(collision);
            }
        }
    }

    private void OnCollisionStay2D(Collision2D collision)
    {
        //实现按下↓键位 让角色从单方向平台往下掉效果
        if (Input.GetKeyDown(KeyCode.DownArrow) && collision.gameObject.tag == "SingleDirCollider")
        {
            IgnoreCollision(collision.collider);
        }
    }

    public void IgnoreCollision(Collider2D collision)
    {
        isOn = true;
        StartCoroutine(StartIgnoreCollision(collision));
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision != null && collision.gameObject.tag == "SingleDirCollider" && isOn)
        {
            var singleDirCollider = collision.GetComponent<SingleDirCollider>();
            //this.transform.position.y + 0.062f是人物minY, this.transform.position.y + 1.31f是人物maxY
            //当人物完整地位于平台之上 或 之下时
            if (singleDirCollider.maxY < (this.transform.position.y + 0.062f) || singleDirCollider.minY > (this.transform.position.y + 1.31f))
            {
                //协程死循环退出
                isOn = false;
            }
        }
    }
}

该案例无法适应复杂平台,例如斜面平台、凹凸不平的,只能应用在平面且带有厚度。
因为是利用触发器来检测什么时候开始忽略碰撞、什么时候恢复碰撞的,最好是利用2D射线检测来做。推荐参考做,它内部实现了一套不依赖Unity物理的移动,即自己实现了类似让角色能站立在一个碰撞盒的效果:GitHub - prime31/CharacterController2D

大概看了下就是会一直有一个对自身受力方向做射线,检测到底板的话就会让Y轴速度恒定在0,来保持角色在平台上的效果,而穿越平台则是忽略单向平台所在Layer层的射线检测,等穿越完成后再恢复,而按↓键让角色从平台往下掉也是同理。

问题

OnCollisionStay2D 只会在角色移动时会触发,并非一直触发,检查2D刚体确实是持续触发的状态的,所以最好还是射线吧

解决修改为:


http://www.niftyadmin.cn/n/5839622.html

相关文章

深度学习篇---深度学习框架

文章目录 前言第一部分&#xff1a;框架简介1. PyTorch简介特点动态计算图易于上手强大的社区支持与Python的集成度高 核心组件 2. TensorFlow简介特点静态计算图跨平台强大的生态系统Keras集成 核心组件 3. PaddlePaddle简介特点易于使用高性能工业级应用丰富的预训练模型 核心…

TCL C++开发面试题及参考答案

进程和线程的区别 进程和线程都是操作系统中重要的概念,它们在很多方面存在着明显的区别。 从概念上来说,进程是资源分配的基本单位,每个进程都有自己独立的地址空间、内存、文件描述符等资源。例如,当我们在计算机上同时运行多个应用程序,像浏览器、文本编辑器等,每个应…

了解传输层UDP协议

目录 一、UDP协议端格式 二、UDP的特点 三、基于UDP的应用层协议 一、UDP协议端格式 UDP协议是一个传输层的一个重要的协议&#xff0c;要了解这个协议&#xff0c;其最主要的工作就是去理解协议报文格式。 16位UDP长度&#xff0c;是表示整个数据报的最大长度&#xff08;字…

pytorch深度Q网络

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 DQN 引入了深度神经网络来近似Q函数&#xff0c;解决了传统Q-learning在处理高维状态空间时的瓶颈&#xff0c;尤其是在像 Atari 游戏这样的复杂环境中。DQN的核心思想是使用神经网络 Q(s,a;θ)Q(s, a; \theta)Q(s,…

2025数学建模美赛|赛题翻译|E题

2025数学建模美赛&#xff0c;E题赛题翻译 更多美赛内容持续更新中...

双写+灰度发布:高并发场景下的维度表拆分零事故迁移实践

目录 0 文章摘要 1业务场景描述 2 迁移及实施过程 2.1 拆分设计与数据探查 2.1 历史数据迁移(全量)

仿真设计|基于51单片机的温度与烟雾报警系统

目录 具体实现功能 设计介绍 51单片机简介 资料内容 仿真实现&#xff08;protues8.7&#xff09; 程序&#xff08;Keil5&#xff09; 全部内容 资料获取 具体实现功能 &#xff08;1&#xff09;LCD1602实时监测及显示温度值和烟雾浓度值&#xff1b; &#xff08;2…

langgraph实现 handsoff between agents 模式 (1)

官网示例代码 from typing_extensions import Literal from langchain_core.messages import ToolMessage from langchain_core.tools import tool from langgraph.graph import MessagesState, StateGraph, START from langgraph.types import Command from langchain_openai…