1.初始条件:

1.角色只绑定一个碰撞体,移动时施加力或给予速度,用跳跃次数JumpTimes或者bool值OnGround判断是否在地面。

2.只用一个tilemap搭建2D场景,因此所有tilemap的图块都是同一个tag,用于判断是否落回地面。


2.出现的问题:

  1. 当角色跳起来接触左右墙壁时按住左右移动键,会出现卡墙现象,就是角色不会因为重力掉下来,而接触墙壁停止在半空(不符合客观规律)
  2. 不知道碰撞体是碰到墙壁还是地面或天花板,因为所有图块都是同一个tag,导致如果直接在OnCollisionEnter2D方法函数里通过判断碰撞体的tag是否为地面Ground,是就重置跳跃次数或者OnGround变为true(碰到墙也可以重置跳跃,导致可以不断卡墙无限跳)

3.解决方案

1.通过添加空子物体并给予trigger于角色上,来检测四个方向的碰撞,从而区分是哪边碰到

缺点:每个prefab都要重复相同的绑定,且如果角色为不规则图形,可能出现bug,例如:

如果角色快要从高处移动到要掉落时,刚好trigger没接触地,判断已经离开地面,又不能跳跃和左右移动

2.通过采用四个tilemap搭建地图,从而各绑定一个tag区分上天花板,地面,左墙和右墙

 if (Input.GetKey(JumpButton) && JumpTimes > 0)   //跳跃
{
rg.velocity = new Vector2(rg.velocity.x, JumpForce);
JumpTimes -= Time.deltaTime;
}
if (Input.GetKey(MoveRightButton))
{
if (isRightWall == false)//判断是否碰到右墙
{
if (FaceToRight == false)
{
rg.transform.localScale = new Vector3(-Mathf.Abs(transform.localScale.x), transform.localScale.y, transform.localScale.z);//转向
}
rg.velocity = new Vector2(MoveSpeed, rg.velocity.y);//移动
}
FaceToRight = true;
} if (Input.GetKey(MoveLeftButton))
{
if (isLeftWall == false)
{
if (FaceToRight == true)
{
rg.transform.localScale = new Vector3(Mathf.Abs(transform.localScale.x), transform.localScale.y, transform.localScale.z);//转向
}
rg.velocity = new Vector2(-MoveSpeed, rg.velocity.y);//移动
}
FaceToRight = false;
}

3.通过添加射线检测于角色身上,检测角色是否离开地面,如果离开。将物理材质摩擦力变为0,这样就不会卡墙了

  private Ray2D ray;
public Transform tf; //射线终结点,用空物体绑到角色作为子物体,移动位置到角色下方接触地面
[SerializeField] private bool onGround = false; void FixedUpdate()
{ ray = new Ray2D(transform.position, Vector2.down);
Vector2 direction = new Vector2(tf.position.x, tf.position.y) - ray.origin;//从角色中心点到终结点的方向向量
Vector2 target = direction + new Vector2(transform.position.x,transform.position.y); //将子空物体的相对坐标转换为世界坐标,求出真正射线终结点坐标 Debug.DrawLine(ray.origin, target, Color.red); //画射线,测试用,实际可去掉
RaycastHit2D info = Physics2D.Raycast(ray.origin, direction,Mathf.Sqrt(direction.x*direction.x+direction.y*direction.y)); if (info.collider != null)
{
if (info.transform.gameObject.CompareTag("Ground"))
{
Debug.Log("碰到地板");
onGround = true;
JumpTimes = 0.5f;
rg.sharedMaterial = p1; //碰到地板就转换成有摩擦力的
}
else
{
Debug.Log("else");
}
}
Move();
}

(但实际运行时物理材质属性是无法改变的,但可以新建两个物理材质,一个摩擦力friction为正常的,另一个为friction=0,运行时再用代码改变)

private Rigidbody2D rg;
public PhysicsMaterial2D p1; //有摩擦力的
public PhysicsMaterial2D p2; //无摩擦力的
。。。
void Awake()
{
rg.sharedMaterial = p1;//改变物理材质,物理材质绑在Rigidbody2D
。。。
}
 public void Move()
{ if (Input.GetKey(JumpButton) && onGround) //跳跃条件:1.按下跳跃键 2.射线检测接触地面
{
rg.velocity = new Vector2(rg.velocity.x, JumpForce);
JumpTimes -= Time.deltaTime;
onGround = false;
rg.sharedMaterial = p2;
}
if (Input.GetKey(MoveRightButton))
{ if (FaceToRight == false)//用bool变量FaceToRight判断转向
{
rg.transform.localScale = new Vector3(-Mathf.Abs(transform.localScale.x), transform.localScale.y, transform.localScale.z);//左右转向时让图片翻转
}
rg.velocity = new Vector2(MoveSpeed, rg.velocity.y);//给予速度,移动
FaceToRight = true;
}
if (Input.GetKey(MoveLeftButton))
{ if (FaceToRight == true)
{
rg.transform.localScale = new Vector3(Mathf.Abs(transform.localScale.x), transform.localScale.y, transform.localScale.z);//转向
}
rg.velocity = new Vector2(-MoveSpeed, rg.velocity.y);//移动
FaceToRight = false;
} }

二段跳咕了(其实知晓一段跳后,二段跳就不难实现了)

转载标明出处:作者AMzz 博客: https://www.cnblogs.com/AMzz/

Unity 横版2D移动跳跃问题——关于一段跳与二段跳的更多相关文章

  1. 简易2D横版RPG游戏制作

    Unity学习笔记1 简易2D横版RPG游戏制作 http://m.blog.csdn.net/article/details?id=24601905

  2. (译)【Unity教程】使用Unity开发Windows Phone上的横版跑酷游戏

    译者注: 目前移动设备的跨平台游戏开发引擎基本都是采用Cocos2d-x或者Unity.一般而言2d用cocos2d-x 3d用unity,但是对于Windows Phone开发者, cocos2d- ...

  3. [Unity+Android]横版扫描二维码

    原地址:http://blog.csdn.net/dingxiaowei2013/article/details/25086835 终于解决了一个忧伤好久的问题,严重拖了项目进度,深感惭愧!一直被一系 ...

  4. Unity3D开发一个2D横版射击游戏

    教程基于http://pixelnest.io/tutorials/2d-game-unity/ , 这个例子感觉还是比较经典的, 网上转载的也比较多. 刚好最近也在学习U3D, 做的过程中自己又修改 ...

  5. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程:简介及目录》(附上完整工程文件)

    介绍:讲述如何使用Genesis-3D来制作一个横版格斗游戏,涉及如何制作连招系统,如何使用包围盒实现碰撞检测,软键盘的制作,场景切换,技能读表,简单怪物AI等等,并为您提供这个框架的全套资源,源码以 ...

  6. 如何让格斗游戏的横版过关(2) Cocos2d-x 2.0.4

    在第一章<如何使横版格戏>基础上.添加角色运动.碰撞.敌人.AI和音乐音效,原文<How To Make A Side-Scrolling Beat 'Em Up Game Like ...

  7. Unity 4.3 2D 教程:新手上路

    这篇文章译自 Christopher LaPollo 先生的 Unity 4.3 2D 教程的第一部分 Unity 4.3 2D Tutorial: Getting Started 感谢这套优秀教程的 ...

  8. 介绍用C#和VS2015开发基于Unity架构的2D、3D游戏的技术

    [Unity]13.3 Realtime GI示例 摘要: 分类:Unity.C#.VS2015 创建日期:2016-04-19 一.简介 使用简单示例而不是使用实际示例的好处是能让你快速理解光照贴图 ...

  9. 怎样制作一个横版格斗过关游戏 Cocos2d-x 2.0.4

     本文实践自 Allen Tan 的文章<How To Make A Side-Scrolling Beat 'Em Up Game Like Scott Pilgrim with Coco ...

随机推荐

  1. Python制作有道翻译小工具

    该工具主要是利用了爬虫,爬取web有道翻译的内容. 然后利用简易GUI来可视化结果. 首先我们进入有道词典的首页,并点击翻译结果的审查元素 之后request响应网页,并分析网页,定位到翻译结果. 使 ...

  2. PMP 德尔菲技术

    1.德尔菲技术,必须遵守以下几个规则: 每个专家只与主持人单线联系. 专家之间完全背靠背,更不能进行讨论.为保证专家提出独立见解,甚至需要把专家分散在不同的物理地点. 专家以匿名的书面形式提出意见. ...

  3. [Luogu1291][SHOI2002]百事世界杯之旅

    题目描述 “……在2002年6月之前购买的百事任何饮料的瓶盖上都会有一个百事球星的名字.只要凑齐所有百事球星的名字,就可参加百事世界杯之旅的抽奖活动,获得球星背包,随声听,更克赴日韩观看世界杯.还不赶 ...

  4. ‎Cocos2d-x 学习笔记(15.1) EventDispatcher

    EventDispatcher对监听器进行管理,围绕着监听器工作.可以添加.删除.暂停/恢复监听器.分发事件到监听器. 1. 一些成员 /** 把ListenerID和同ID监听器的容器对应 */ s ...

  5. Halcon一日一练:图像采集设备的基本参数

    因操作图像处理之前,需要对图像进行采集.采集图像,我们首先要确定的是图像的像素和采集的效率.这些都需要对设备进行配置与操作.现实情况是图像设备有各自不同的采集方式,配置也各不相同.这就需要设备提供商提 ...

  6. python编程系列---进程池的优越性体验

    1.通过multiprocessing.Process()类创建子进程 import multiprocessing, time, os, random def work(index): " ...

  7. Html.CSS.JavaScript 学习经验

    HTML里面 不要使用 document.getElementsByName() 来获取 元素,会出错. 使用 document.getElementById()更好一些. substring()首字 ...

  8. markdown(typora)基本语法

    目录 * 标题 * 加粗 * 斜体 * 高亮 * 上标 * 下标 * 代码引用(>式和```式) * 代码引入(`式) * 插入链接(链接显示) * 插入链接(连接描述显示) * 插入图片(链接 ...

  9. django-ForeignKey,OneToOneField,ManyToManyField

    进入到django自带的related.py中,可以看到 1.ForeignKey 初始化的参数有: to, on_delete, related_name=None, related_query_n ...

  10. 网页开发利用jq自定义鼠标右击事件

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...