Unity以及游戏源码 Unity 绘制背景 设置地图 动画制作 动画重写 game

基本认识

  1. FixedUpdate:每秒50次刷新:50帧,注意条件变量的控制(二段跳)

  2. 单词

    1. gravity:重力

    2. Rigdbody:刚体

    3.  

  1. 组件名在vs中不能更改,且vs要求组件名必须首字母大写;

  2. 视角跟随:在unity中选中GameObject为Sphere

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

    public class CameraControler : MonoBehaviour
    {
       public GameObject Sphere;//在unity中选中GameObject为Sphere
       private Vector3 offset;
       // Start is called before the first frame update
       void Start()
      {
           offset = transform.position - Sphere.transform.position;
      }

       // Update is called once per frame
       void LateUpdate()
      {
           transform.position = Sphere.transform.position + offset;
      }
    }

    分辨率:一个格子100dp=10*10;

    物体碰撞(2d):

    1. 物体设置为Rigidbody、Boxcollider,地面设置为Rigidbody并将bodytype修改为Kinematic、Boxcollider

    2. 碰撞会产生微小形变,可能会穿模,将主角的Rigidbody中的Interpolate改为Interpolate去除碰撞形变

物体运动

https://www.bilibili.com/video/BV14V411r7Tr?p=2视频教学

Kinematic:开启运动学,开启后不再受力的影响,只能通过Transform属性来操作。

  1. 初级运动

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

    public class Character : MonoBehaviour
    {
       public float speed = 3f;
       public Rigidbody2D rig;
       public float jumpForce;
       // Start is called before the first frame update
       void Start()
      {
           rig = GetComponent<Rigidbody2D>();
           jumpForce = 300f;
      }

       // Update is called once per frame
       void Update()
      {
           if (Input.GetKeyDown(KeyCode.K))
          {    //如果按下空格

               rig.AddForce(new Vector2(0, jumpForce));   //给刚体一个向上的力

          }
           float moveX = Input.GetAxisRaw("Horizontal");//控制水平方向A:-1 D:1 0
           //float moveY = Input.GetAxisRaw("Vertical");//控制数值方向S:-1 W:1 0

           Vector2 position = transform.position;
           position.x += moveX * speed * Time.deltaTime;
           transform.position = position;
      }
    }

     

  2. 高级

    1. 改为没有平滑过渡Editor--Project setting--Input--Gravity、Sensetivity修改为1000,与fire1相同

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

      public class Character : MonoBehaviour
      {
         public float WalkSpeed;
         public float AccelerrateTime;
         public float DecelerateTime;

         Rigidbody2D Rig;
         float velocityX;

         private void Awake()
        {
             Rig = GetComponent<Rigidbody2D>();
        }
         private void FixedUpdate()
        {
             if (Input.GetAxisRaw("Horizontal") < 0)
            {
                 Rig.velocity = new Vector2(Mathf.SmoothDamp(Rig.velocity.x, WalkSpeed * Time.deltaTime * 60, ref velocityX, AccelerrateTime), Rig.velocity.y);
            }
             else if (Input.GetAxisRaw("Horizontal") > 0)
            {
                 Rig.velocity = new Vector2(Mathf.SmoothDamp(Rig.velocity.x, WalkSpeed * Time.deltaTime * 60*(-1), ref velocityX, AccelerrateTime), Rig.velocity.y);
                 //使用加速时间控制启动、停止快慢
            }
             else if (Input.GetAxisRaw("Horizontal") == 0)
            {
                 Rig.velocity = new Vector2(Mathf.SmoothDamp(Rig.velocity.x, 0, ref velocityX, AccelerrateTime), Rig.velocity.y);
            }
        }
      }

使用

在Edit->project setting -> input 处可以对按键细节进行设置: Unity以及游戏源码
Unity
绘制背景
设置地图
动画制作
动画重写
game 扩展size ,即可添加按键配置。 Name:名称,调用或在外部设置的时候需要使用该名 Negative Button :缺省值为-1的按键 Positive Button :缺省值为1的按键 Alt Negative Button :备用的缺省值为-1的按键 Alt Positive Button :备用的缺省值为1的按键 Dead: 输入阈值, 触摸或者摇杆大于这个值才会触发输入 Gravity:表示松开按键时,从端点1或-1返回缺省值0时的速度 Sensitivity:按下按键时,从缺省值0到1或-1时的速度 Snap: 当触发反向操作时,当前值是否立即归零 Invet:是否取反值 Type:预设输入设备类型,可选键盘与鼠标按键、手柄、鼠标移动 Axis:装置选择,例如一个手柄有两个十字键两个摇杆,那么可以在这里设置当前设定作用于哪个装置 Joy Num: 手柄编号。指定连接的哪个设备 需要说明的是,在输入管理器中设置的输入基本上都是返回-1 - 1 区间的值。这比返回true false要好很多,因为优化输入体验的时候,比如我们希望根据按压力度来调整跳跃距离,又或者我们希望根据摇杆的摇摆程度来控制车辆的方向盘,都比较合适

函数说明

Rig.velocity:刚体的速度:矢量,

参数说明

Parameters,它就是使用Animator来切换动作的灵魂。可以把它理解为实现动作的条件,通过改变它来判断满足什么条件执行什么动作。点击右边的+号,可以看到有4个类型:Float,Int,Bool,Trigger。

绘制背景

  1. 创建tilemap

  2. 设置sortinglayer:通过Edit/Project Settings/Tags & Layers打开Sorting Layers创建*排列层*并调整它们的位置

  3. 放入背景,设置每个tilemap单元格的像素(设置tilemap的scale大小,自己调试)

    第一次人物做的太小,导致画地图时地图方块无法占满单个格子

  4. 调试物块大小:将物块放入tilepalete,在inspector界面中调整图片像素

设置地图

  1. 在对应的tilemap里边添加碰撞器,刚体

  2. 单独的每一块碰撞器,发现角色卡在某个位置不能移动,解决方法:将每个碰撞器合并成整体的复合碰撞器

    1. Tilemap Collidor 2d中选择used by Composite

    2. 添加Composite Collidor 2d

  3. 调整TileMap碰撞点

    在进行爬坡测试的时候,出现了一个问题就是斜坡的瓦片碰撞点不能和瓦片重合,且凹凸不平,运行体验不佳。

    不是正方形的瓦片的话,TileMap的碰撞点自动设置可能很奇怪,直接TileMap设置碰撞器的话,可能会有凹凸不平的情况,且凹凸不平的形状不能和瓦片完全重合。

    出现这个问题可能需要回到一开始编辑图片,在Sprite Editor里面,左边的红框选择第三个Custom Physics Shape,然后点击需要修改碰撞点的方形块,然后点击Generate就可以修改碰撞点。

  4. 物体勾选IsTriger:物体可以被穿过但仍视为有效碰撞,用于制作陷阱或者拾取道具

动画制作

  1. 创建空动画

  2. 将动画拉入主角,自动生成动画控制器

  3. 点击Animator,右键创建blendtree

  4. 点击blendtree,再双击,添加之前创建的空动画

  5. 选择主角,在animation处添加图片,生成动画

动画重写

  1. 已有Enermy1动画效果,在AnimationControllers文件夹内空白处右键,依次选择Create->Animator Override Controller,创建了一个动画重写控制器,我们命名为Enemy2

  2. 可以看到这个重写控制器右侧Inspector窗口内有个Controller选项,可以选择继承哪个动画控制器。在这里,我们可以把Enemy1直接拖入到输入框,或者点击输入框右侧的小圆圈选择Enemy1。

  3. 继承Enemy1的动画控制器后,还需要把美术资源也替换掉。Enemy1Attack改写成Enemy2Attack,Enemy1Idle改写成Enemy2Idle,这样重写控制器就配置好了。

  4. 这时候,怪物2的Animator组件使用的控制器还是Enemy1。选择Enemy2游戏对象,在Animator组件的Controller选项点击右侧小圆圈,在弹出的窗口中选择Enemy2即可。

  5. 这时候运行游戏,可以看到怪物2的动画正常。

  6. 通过这样重写控制器,以后在怪物1的动画控制器添加逻辑的时候,怪物2自动继承,不需要再额外给怪物2添加一样的逻辑。我们这个项目才2个小怪,如果怪物类型或者动画类型再多一点,重写控制器就非常有必要。而且修改起来也只需要改一个地方即可,非常方便。其实个人觉得和Prefab预制件有点相似。

链接:https://www.jianshu.com/p/5622f6db56b7

game

实现高度手感跳跃

public float LowJumpMultiplier;
   bool IsJumping;

   //触地判定
   public Vector2 PointOffset;
   public Vector2 Size;
   public LayerMask GroundLayerMask;
   Rigidbody2D Rig;
   float velocityX;
   bool GravatySwitch = true;
   bool IsOnGround;//判定是否在地面

   private void Awake()
  {
       Rig = GetComponent<Rigidbody2D>();
  }
   private void FixedUpdate()
  {
       IsOnGround = OnGround();
       //左右移动
       if (Input.GetAxisRaw("Horizontal") < 0)
      {
           Rig.velocity = new Vector2(Mathf.SmoothDamp(Rig.velocity.x, WalkSpeed * Time.deltaTime * 60*(-1), ref velocityX, AccelerrateTime), Rig.velocity.y);
      }
       else if (Input.GetAxisRaw("Horizontal") > 0)
      {
           Rig.velocity = new Vector2(Mathf.SmoothDamp(Rig.velocity.x, WalkSpeed * Time.deltaTime * 60, ref velocityX, AccelerrateTime), Rig.velocity.y);
      }
       else if (Input.GetAxisRaw("Horizontal") == 0)
      {
           Rig.velocity = new Vector2(Mathf.SmoothDamp(Rig.velocity.x, 0, ref velocityX, AccelerrateTime), Rig.velocity.y);
      }
       if (Input.GetAxisRaw("Jump") == 1&&!IsJumping)
      {
           Rig.velocity = new Vector2(Rig.velocity.x, JumpingSpeed);//x轴不变,y轴给个初速度
           IsJumping = true;//正在空中
      }
       if (IsOnGround && Input.GetAxisRaw("Jump") == 0)//在地面并且松开跳跃键
      {
           IsJumping = false;
      }
       //Physics2D.gravity.y是一个负值
       if (Rig.velocity.y < 0)//下坠时
      {
           //下落的更快
           Rig.velocity += Vector2.up * Physics2D.gravity.y * (FallMultiplier - 1) * Time.fixedDeltaTime;
      }
       else if(Rig.velocity.y>0&&Input.GetAxisRaw("Jump")!=