当前位置: 首页 > article >正文

【Unity3D】实现横版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.kler.cn/a/525707.html

相关文章:

  • ASP.NET代码审计 SQL注入篇(简单记录)
  • 登录授权流程
  • 代码随想录算法训练营第三十八天-动态规划-完全背包-279.完全平方数
  • 2024年记 | 凛冬将至
  • 腾讯云开发提供免费GPU服务
  • 一个简单的自适应html5导航模板
  • 31【api接口】
  • 构建具身智能体的时空宇宙!GRUtopia:畅想城市规模下通用机器人的生活图景
  • Effective Objective-C 2.0 读书笔记——关联对象
  • Node.js MySQL:深度解析与最佳实践
  • 程序代码篇---Python随机数
  • 【Java】微服务找不到问题记录can not find user-service
  • 每日一题——序列化二叉树
  • Python3 【集合】水平考试:精选试题和答案
  • 【redis进阶】redis 总结
  • 青少年编程与数学 02-008 Pyhon语言编程基础 07课题、数字
  • deepseek R1 14b硬件要求
  • Hive:struct数据类型,内置函数(日期,字符串,类型转换,数学)
  • SpringBoot 基础特性
  • 精灵图的知识
  • YOLOv8源码修改(4)- 实现YOLOv8模型剪枝(任意YOLO模型的简单剪枝)
  • Pytorch框架从入门到精通
  • 基于springboot+vue的扶贫助农系统的设计与实现
  • SSM开发(六) SSM整合下的CURD增删改查操作(IDEA版)
  • 有效运作神经网络
  • 初阶mysql修炼手册