Unity-2D

1.Unity中的2D模式:

1)游戏在二维上展示

启用 2D 模式时将会设置正交(即无透视)视图:摄像机沿 Z 轴观察,而 Y 轴向上增加。因此可以轻松可视化场景并放置 2D 对象。

2)设置项目默认模式:Edit > Project Settings > Default Behavior Mode

在 2D 项目模式下:

  • 所有图像(images)都会被当做 2D 图片,并设置成 sprite mode 精灵模式

  • Sprite Packer 会被启动

  • Scene 视图默认为 2D

  • 默认游戏对象没有实时方向光。

  • 摄像机的默认位置为 0,0,–10。(在 3D 模式下为 0,1,–10。)

  • The camera projection is set to be Orthographic. (In 3D Mode it is Perspective.)摄像机投射模式被设置为正交(没有远小近大,没有距离之分),而在 3D 模式下,是透视(远小近大,有距离之分)

  • 在 Lighting 窗口中:

    • Skybox is disabled for new scenes:天空盒默认关闭

    • Ambient Source is set to Color. (With the color set as a dark grey: RGB: 54, 58, 66.) 保围光源设置为 color ,默认为灰色

    • Realtime Global Illumination (Enlighten) is set to off.关闭实时光照

    • Baked Global Illumination is set to off.关闭全局光照烘焙

    • Auto-Building set to off.自动创建关闭

2.在Unity中创建2D游戏

1)Player的创建与控制:
  • 使用静态精灵创建Player:
    • 精灵 Sprite 是 Unity 中 2D 素材的默认存在形式,是 Unity 中的 2D 图形对象。

    • 在 2D 游戏中,使用 2D 素材的过程: PNG(JPG 等)----> Sprite ----> GameObject

2)Player的移动脚本:
  • 铺垫

    • Vector2 二维向量
      • 在数学中,Vector 向量/矢量指的是带方向的线段

      • 在 Unity 中,Transform 值使用 x 表示水平位置,使用 y 表示垂直位置,使用 z 表示深度。这 3 个数值组成一个坐标。由于此游戏是 2D 游戏,你无需存储 z 轴位置,因此你可以在此处使用 Vector2 来仅存储 x 和 y 位置。

      • Transform 中 position 的类型,也是 Vector2。C# 这种强类型语言,赋值时,左右必须是同一类型才能进行

    • Unity 默认 Input Manager 设置
      • 在 Unity 项目设置中,可以通过 Input Manager 进行默认的游戏输入控制设置 Edit > Project Settings > Input

      • 键盘按键,以 2 个键来定义轴:

        • 负值键 negative button,被按下时将轴设置为 -1

        • 正值键 positive button ,被按下时将轴设置为 1

      • Axis 轴 Axes 是它的负数形式

        • Horizontal Axis: 水平轴 对应 X 轴

        • Vertical Axis:纵轴 对应 Y 轴

    • Input类
      • 使用该类来读取传统游戏输入中设置的轴/鼠标/按键,以及访问移动设备上的多点触控/加速度计数据。若要使用输入来进行任何类型的移动行为,请使用 Input.GetAxis。 它为您提供平滑且可配置的输入 - 可以映射到键盘、游戏杆或鼠标。 请将 Input.GetButton 仅用于事件等操作。不要将它用于移动操作。Input.GetAxis 将使脚本代码更简洁。

    • 时间和帧率
      • 当前的代码中,帧数越高,同一时间内,执行 Update 的次数越多,角色移动速度越快。如果游戏以每秒 60 帧的速度运行,那么 Ruby 将移动 0.1 _ 60,因此每秒移动 6 个单位。但是,如果游戏以每秒 10 帧的速度运行,就像刚刚让游戏运行的那样,那么 Ruby 仅移动 0.1 _ 10,因此每秒移动 1 个单位!

      • 如果一个玩家的计算机非常陈旧,只能以每秒 30 帧的速度运行游戏,而另一个玩家的计算机能以每秒 120 帧的速度运行游戏,那么这两个玩家的主角的移动速度会有很大差异。这样就会使游戏的难易程度提高或降低,具体取决于运行游戏的计算机。

      • 而帧数是由硬件水平影响的(越好越高),不同电脑中,会导致游戏效果完全不同

  • 新建Player后,选中Player,在Inspector窗口中Add Component,自定义一个脚本,移动脚本的代码如下:

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

    public class RubyMover : MonoBehaviour
    {
       // Start is called before the first frame update
       void Start()
      {
           
      }
       public float speed = 0.1f;
       // speed访问权限设置为public,在Unity中可修改属性。
       // Update is called once per frame
       void Update()
      {
           float x = Input.GetAxis("Horizontal");
           float y = Input.GetAxis("Vertical");

           Vector2 position = transform.position;
           position.x += 0.1f * x * speed * Time.deltaTime;
           position.y += 0.1f * y * speed * Time.deltaTime;
           transform.position = position;

      }
    }
    3)2D游戏中瓦片地图的创建和使用:
    • 瓦片地图工作流程
      1. 预处理 sprite 资源:将图片资源拖拽到 project 中,生成 sprite;然后一般需要进行切割 slice ,将其配置成需要的各个 tile;

      2. 创建要在其上绘制瓦片的瓦片地图。此过程中还会自动创建 Grid 游戏对象作为瓦片地图的父级。

      3. 直接创建瓦片资源,或者通过将用作瓦片素材的精灵带入 Tile Palette 窗口自动生成瓦片。

      4. 创建一个包含瓦片资源的 Tile Palette,并使用各种笔刷来绘制到瓦片地图上。

    • 瓦片地图的高级使用
      • 使用普通的瓦片地图,构建整个世界,一个一个格子用笔刷来填充,非常费时,Unity 在不断地升级中,添加了很多种快速构建瓦片地图的方式,掌握了这些方法,能够极大减少绘制地图所用的时间。

        • 编程瓦片 Scriptable Tile

          • Unity 支持用代码创建自己的 Tile 类,自己书写瓦片的绘制规则。还可以为瓦片创建自定义编辑器。这与脚本化对象的自定义编辑器的工作方式相同。创建一个继承自 TileBase(或 TileBase 的任何有用子类,如 Tile)的新类。重写新的 Tile 类所需的所有方法。

        • 编程画笔 Scriptable Brush

          • Unity 也支持创建自己的 Brush 类,设计适合自己游戏的网格画笔。

            创建一个继承自 GridBrushBase(或 GridBrushBase 的任何有用子类,如 GridBrush)的新类。重写新的 Brush 类所需的所有方法。创建可编程画笔后,画笔将列在 Palette 窗口的 Brushes 下拉选单 中。默认情况下,可编程画笔脚本的实例将经过实例化并存储在项目的 Library 文件夹中。对画笔属性的任何修改都会存储在该实例中。如果希望该画笔有多个具备不同属性的副本,可在项目中将画笔实例化为资源。这些画笔资源将在 Brush 下拉选单中单独列出。

    • 2D Tilemap Extras (2D 瓦片地图扩展)
      • Animated Tile 动画瓦片

        • 动画瓦片在游戏运行时,按顺序显示 Sprite 列表以创建逐帧动画

      • Rule Tile 规则瓦片

        • 可以为每个瓦片创建规则,在绘制时,unity 会自动响应这些规则,绘制地图时更加智能

        • RuleTile 使用步骤:

          • 准备 Tile 素材,配置素材属性,分割素材;

          • 新建 RuleTile,为其添加规则,设置每个 Tile 的相邻规则;

          • 将设置好的 RuleTile 拖拽到 Tile Palette 中,就可以使用了。

      • Rule Override Tile / Advanced Rule Override Tile 规则覆盖瓦片

        • 可以用已经生成好的 Rule Tile,作为 Rule Override Tile 的规则来源,只替换对应的瓦片素材,而沿用原先的规则,可以快速的创建规则瓦片的方法。

4)场景中的图形顺序:
  • 伪透视图
    • 透视图指的是有深度、距离感的图,一般要三维中的深度轴来表现场景的深度,而二维游戏中没有这个深度,只能通过前后来仿造深度效果,称为“伪透视图”

    • 先前通过调整瓦片的 Order in Layer 属性来解决了瓦片地图的排序问题,但并非总是希望一个游戏对象在另一个游戏对象之上,比如,在同一个瓦片地图中,玩家角色在一个物体之前(比如一棵树)时,应该是玩家遮挡树,而玩家移动到树后时,应该是树遮挡玩家,这就需要“伪造”透视图。

    • 在 2D 游戏中,场景里的 “前后” 是由 Y 轴决定的,需要让 Unity 根据游戏对象的 y 坐标来绘制游戏对象Y 轴 y 坐标值越小,越靠前,应该遮挡 y 坐标值较大的游戏对象,也就是 y 坐标较小的游戏对象后绘制,就会位于上层

    • 在游戏中,如果要设置 2D 伪透视试图,需要在项目设置中进行更改:

      • Edit > Project Settings > Graphics > Camera Settings > Transparency Sort Mode = Custom Axis > Transparency Sort Axis x = 0 / y = 1 / z = 0

      • 此设置告诉 Unity 在 y 轴上基于精灵的位置来绘制精灵。

    • 按 Play 以进入运行模式并测试你的更改。现在,你的角色比箱子高时,角色应该会绘制在箱子的后面;而角色比箱子低时,绘制在箱子的前面。

    • Sprite 轴心 pivot

      • 每个 Sprite 都有一个轴心(中心点),Unity 根据 pivot 对 sprite 进行定位,这个 pivot 可以在 sprite editor 中调整,可以将其设置到 sprite 上任意位置

      • 在 2D Rpg 游戏场景中的游戏对象,如果想要实现较为真实的 “伪透视” 效果,最好将游戏对象的 sprite 中 pivot 都设置到素材的最下方正中。

      • 然后将游戏对象的 Sprite Sort Point 由 Center 改为 Pivot 即可.

5 )物理系统:
  • 铺垫:
    • Unity中内置的物理系统可以模仿地球上的物理系统,使Unity中创建的一切精灵都具有类似地球上的物理属性。

  • 物理系统中比较重要的脚本组件:
    • Rigidbody :项目中的刚体组件

      • 定义了对象收到外力后,如何模拟其行为,如翻滚,掉落。当为一个对象添加了 Rigidbody 组件后,就会模拟受重力而掉落。如果再加上collider组件,则会响应外部的力,而运动。添加 Rigidbody后,我们就不能通过 transform 组件来移动物体了,只能由物理系统来模拟驱动。当然这不是绝对的,某些特定情境,需要关掉物理模拟,将物体摆放到指定位置,再重新打开物理模拟。有时,我们希望对象参与物理模拟,但是其行为还是由逻辑控制,比如,对于游戏内的NPC,我们需要由代码控制其运动,同时又需要添加rigidbody,这样才能被Trigger检测到,对于这种情况,可以将 Rigidbody 设置为动力学物体(Is Kinemiac)。

    • ···collider : 项目中碰撞体组件:

      • 定义了物体的形状来进行碰撞模拟。物理碰撞体的形状不需要严格和物体一致,只要能表示其物理形状即可。比如一个复杂的人,我们可以用一个胶囊体来定义其碰撞形状。

      • Unity内建了很多碰撞体,以下时常用的碰撞体:

        • BoxCollider 立方体碰撞体 SphereCollider 球形碰撞体 CapsuleCollider 胶囊碰撞体 MeshCollider 从对象的网格创建碰撞体。MeshCollider之间不支持碰撞检测,效率太低。可以将MeshCollider的Convex选项打开,则能支持MeshCollider之间的碰撞检测,同时提高性能。 WheelCollider 创建载具的轮子的碰撞体 TerrainCollider 处理Unity地形系统的碰撞

        • 2D中相应的BoxCollider2D,CircleCollider2D,CapsuleCollider2D,以及其它转为2D建立的碰撞体类型,如PolygonCollider2D。

        • Box,Sphere,Circle,Capsule这些简单碰撞体的效率相对都是较高的,建议使用这些简碰撞体。

      • 当一个精灵比较复杂时(如创建的一个人物角色),可以采用组合碰撞体的方式,对角色不同的身体部位分别采用不同的碰撞体组件。

    • 触发器:
      • 为碰撞体组件选中is Trigger复选框,会发现碰撞体不再组织移动了。触发器用于检测碰撞但不产生碰撞。在2D项目中要使用OnTriggerEnter2D方法。

      • code:

      • private void OnTriggerEnter2D(Collider2D collision)
          {
               Debug.Log($"与{collision}发生碰撞了!");
          }
    • OnColliderEnter(2D) 和OnTriggerEnter(2D):

      • OnCollisionEnter方法必须是在两个碰撞物体都不勾选isTrigger的前提下才能进入,反之只要勾选一个isTrigger那么就能进入OnTriggerEnter方法。

      • OnCollisionEnter和OnTriggerEnter是冲突的不能同时存在的。

      • OnTriggerEnter和OnCollisionEnter的选择。

        • 如果想实现两个刚体物理的实际碰撞效果时候用OnCollisionEnter,Unity引擎会自动处理刚体碰撞的效果。

        • 如果想在两个物体碰撞后自己处理碰撞事件用OnTriggerEnter。

6)Unity中的世界交互:
  • 可收集的对象:
    • 例如玩家通过触发器实现回血或者扣血的操作:

    • //扣血的类

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

      public class collectibleHealth : MonoBehaviour
      {
         public int healther = -1;

         private void OnTriggerEnter2D(Collider2D collision)
        {
             Debug.Log($"与{collision}发生碰撞了!");

             //获取主角游戏对象
             RubyMover RM = collision.GetComponent<RubyMover>();
             if(RM!=null)
            {
                 //调用改变血量的方法时,建议再加一层判断,血满时无法调用这个方法。
                 RM.ChangeHealth(healther);
            Destroy(gameObject);
            }
             
        }  
      }

      //玩家类
      //玩家类中的一些属性(例如血量或者其他的一些私有属性)建议设置为私有,并提供get/set方法。
      public class RubyMover : MonoBehaviour
      {
         public float speed = 0.1f;
         Rigidbody2D rigidbody;
         float x;
         float y;
         int CurHealth;
         int MaxHealth;

         // Start is called before the first frame update
         void Start()
        {
             rigidbody = GetComponent<Rigidbody2D>();
             MaxHealth = CurHealth = 5;
        }
         
         // Update is called once per frame
         void Update()
        {
              x = Input.GetAxis("Horizontal");
              y = Input.GetAxis("Vertical");
        }

         private void FixedUpdate()
        {
             Vector2 position = rigidbody.position;
             position.x += 0.1f * x * speed * Time.deltaTime;
             position.y += 0.1f * y * speed * Time.deltaTime;
             rigidbody.MovePosition(position);
        }

         //有关血量更改的代码
         public void ChangeHealth(int HCer)
        {
             CurHealth = Mathf.Clamp(CurHealth + HCer, 0, MaxHealth);
             Debug.Log("当前生命值:" + CurHealth + "/" + MaxHealth);
        }
      }
  • 设置摄像机跟随Player移动(使用自带脚本的的方式):
7)U2D中的精灵动画:
  • 参考网页教程,百度资源。

8)一些问题及解决方式:
  • 创建的角色在于环境中的一些组件发生碰撞时角色发生旋转、抖动的问题:
    • 旋转:在2D项目中,选中创建的角色,在Inspector面板中找到添加的Rigidbody 2D脚本,在Constrains勾选Freeze Rotation Z。

    • 抖动:引起抖动的原因可能是你在角色移动脚本里写代码是利用的transform来移动角色。此时脚本移动角色的位置会和碰撞体矛盾从而引起抖动。(说白了就是你在脚本中强行将角色移到一个碰撞体的碰撞范围内,这个碰撞体又将角色弹了回来)。解决的方法是:利用刚体的移动代替transfoem的移动方式。代码脚本如下:

    • //原transform移动方式见上


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

      public class RubyMover : MonoBehaviour
      {
         public float speed = 0.1f;
         Rigidbody2D rigidbody;
         float x;
         float y;
         // Start is called before the first frame update
         void Start()
        {
             rigidbody = GetComponent<Rigidbody2D>();
        }
         
         // Update is called once per frame
         void Update()
        {
              x = Input.GetAxis("Horizontal");
              y = Input.GetAxis("Vertical");

             

        }
      //使物理计算保持稳定,定期更新。只要你想直接影响物体组件或刚体,就要使用这个函数。
         private void FixedUpdate()
        {
             Vector2 position = rigidbody.position;
             position.x += 0.1f * x * speed * Time.deltaTime;
             position.y += 0.1f * y * speed * Time.deltaTime;
             rigidbody.MovePosition(position);
        }
      }

Unity-2D的更多相关文章

  1. unity 2d 和 NGUI layer

    http://blog.csdn.net/xtxy/article/details/37876825 在使用unity2d开发游戏的时候,使用了NGUI作为界面,本来二者配合得还挺好,但是一个使用场景 ...

  2. Ubuntu 11.10 安装GMONE3,卸载 UNITY和UNITY 2D

    Ubuntu 11.10安装GNOME3: 1)sudo apt-get install gnome-shell    sudo apt-get install gnome-themes*   (或者 ...

  3. Mastering Unity 2D Game Development

    Mastering Unity 2D Game Development will give your game development skills a boost and help you begi ...

  4. Unity 2D游戏开发教程之精灵的死亡和重生

    Unity 2D游戏开发教程之精灵的死亡和重生 精灵的死亡和重生 目前为止,游戏项目里的精灵只有Idle和Walking这两种状态.也就是说,无论精灵在游戏里做什么,它都不会进入其它的状态,如死亡.于 ...

  5. Unity 2D游戏开发教程之摄像头追踪功能

    Unity 2D游戏开发教程之摄像头追踪功能 上一章,我们创建了一个简单的2D游戏.此游戏中的精灵有3个状态:idle.left和right.这看起来确实很酷!但是仅有的3个状态却限制了精灵的能力,以 ...

  6. Unity 2D游戏开发教程之2D游戏的运行效果

    Unity 2D游戏开发教程之2D游戏的运行效果 2D游戏的运行效果 本章前前后后使用了很多节的篇幅,到底实现了怎样的一个游戏运行效果呢?或者说,游戏中的精灵会不会如我们所想的那样运行呢?关于这些疑问 ...

  7. Unity 2D游戏开发教程之使用脚本实现游戏逻辑

    Unity 2D游戏开发教程之使用脚本实现游戏逻辑 使用脚本实现游戏逻辑 通过上一节的操作,我们不仅创建了精灵的动画,还设置了动画的过渡条件,最终使得精灵得以按照我们的意愿,进入我们所指定的动画状态. ...

  8. Unity 2D游戏开发教程之游戏精灵的开火状态

    Unity 2D游戏开发教程之游戏精灵的开火状态 精灵的开火状态 “开火”就是发射子弹的意思,在战争类型的电影或者电视剧中,主角们就爱这么说!本节打算为精灵添加发射子弹的能力.因为本游戏在后面会引入敌 ...

  9. Unity 2D游戏开发教程之游戏中精灵的跳跃状态

    Unity 2D游戏开发教程之游戏中精灵的跳跃状态 精灵的跳跃状态 为了让游戏中的精灵有更大的活动范围,上一节为游戏场景添加了多个地面,于是精灵可以从高的地面移动到低的地面处,如图2-14所示.但是却 ...

  10. Unity 2D游戏开发教程之为游戏场景添加多个地面

    Unity 2D游戏开发教程之为游戏场景添加多个地面 为游戏场景添加多个地面 显然,只有一个地面的游戏场景太小了,根本不够精灵四处活动的.那么,本节就来介绍一种简单的方法,可以为游戏场景添加多个地面. ...

随机推荐

  1. Solution -「CF 1370F2」The Hidden Pair (Hard Version)

    \(\mathcal{Description}\)   Link (hard) & Link (easy).   这是一道交互题.   给定一棵 \(n\) 个结点的树,其中有两个是特殊结点. ...

  2. Linux性能优化之磁盘I/O性能指标

    讨论指标之前,得先解决两个概念:文件系统和磁盘I/O栈. 文件系统是什么?文件系统是在磁盘的基础上,提供了一个用来管理文件的树状结构.简言之,文件系统是树状结构,一种数据结构~逻辑上的概念.磁盘大家都 ...

  3. git 提交忽略文件

    target/ */target/ **/logs/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .fa ...

  4. SpringCloud微服务实战——搭建企业级开发框架(三十八):搭建ELK日志采集与分析系统

      一套好的日志分析系统可以详细记录系统的运行情况,方便我们定位分析系统性能瓶颈.查找定位系统问题.上一篇说明了日志的多种业务场景以及日志记录的实现方式,那么日志记录下来,相关人员就需要对日志数据进行 ...

  5. 库存数量管理方案一:基于SQL存储过程和MERGE(结合活字格案例)

    库存更新是ERP系统的基本功能,一般包括以下动作:1.以库位编号和商品编号查询库存表,如果查询不到,则添加一行库存信息,如:(出入库)库位编号/(出入库)商品编号/(出入库)+或-数量2.以库位编号和 ...

  6. 在Mac上安装mysql并配置环境(详细篇)

    在Mac上安装mysql并配置环境(详细篇) 1.下载mysql mysql官网 这一步根据自己电脑架构选择,分为arm和x86 下载完成之后打开就可以 接下来运行安装就可以,一直下一步,设置完密码就 ...

  7. 【C# .Net GC】sos.dll 混合模式调试(托管调试+本机)

    当我们想使用本机调试器(如CDB或WinDBG)调试.NET应用程序时,我们必须在本机调试器和托管世界之间使用"桥",因为本机调试器本身并不理解托管代码.它是本机调试器.为了提供这 ...

  8. C# 使用技巧区

    1.事件中的技巧 (1)在事件发送者中,用delegate{}初始化事件.这样就不用每次在使用事件的时候判读事件是否为空了. delegate { }可以赋值给任何类型的委托.这个功能匿名方法特有的, ...

  9. Oracle数据库的下载、安装与卸载

    Oracle数据库下载: 这里以Oracle 11g为例,推荐去Oracle官网下载 Oracle官网下载地址:https://www.oracle.com/database/technologies ...

  10. python面试_总结02_代码题

    - 代码题 1.创建一个函数,接收一个字符串参数,判断其做为Python标识符是否合法. 具体要求: 如果合法则输出 True,否则输出 False. 如果该字符串与Python内置的关键字,或Bif ...