Unity2D基础


Unity2D基础

组件

场景控制器SceneManagement

using UnityEngine.SceneManagement;
// 加载当前场景(重启)
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
// 加载以一个场景(下一关)
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);

RigidBody 2D

产生刚体,变成物体,可加重力

Box Collider 2D

碰撞体

Circle Collider 2D

圆形的碰撞体

让碰撞体失效

headColl.enabled = false;
headColl.enabled = true;

Tilemap Collider 2D

地形碰撞体

Audio Mixer

混音,控制声音大小

使用

create -> Audio Mixer
windows -> Audio -> Audio Mixer窗口 -> 需要将volume属性改成代码可编辑,右键,Expose …,然后在Exposed Parameters可以看到参数名
选择要更改的Audio Source 有个output属性,设置成Audio Mixer

using UnityEngine.Audio;
// 控制音量的
public AudioMixer audioMixer;
public void setVolume(float value) {
        if (value == -15f) {
            value = -80f;
        }
        audioMixer.SetFloat("MainVolume", value);
    }

光Light

材质

首先需要把场景中的物体,背景这些的材质改成Default-Diffuse反光。然后添加光源就可以让它明亮
也可以自定义材质,把它的Shader改成Sprites/Diffuse,然后拖到物体的材质栏里面

添加光源

右键Light
Directional Light(整体的光源)
Point Light(单点光源)
添加后注意改变光源位置,Y轴,光都是3D的
Intensity,光的强度

Is Trigger

触发器,在碰撞体里面的属性

判断是否碰撞到trigger
private void OnTriggerEnter2D(Collider2D collision) {
		// 碰撞到tag为Collection的物体,销毁这个物体,需要选择tag
        if (collision.tag == "Collection") {
            Destroy(collision.gameObject);
        }
    }

碰撞体碰撞监听

private void OnCollisionEnter2D(Collision2D collision) {
		// 碰撞到某个碰撞体
        if (collision.gameObject.tag == "Enemy") {
            Destroy(collision.gameObject);
            collision.gameObject.tag = "Untagged";
        }
    }

Material材质(碰撞体的属性)

create -> 2D -> Physics Material 2D
拖动到碰撞体的Material

Cinemachine

镜头跟踪,window->package Manager->Unity Registry->Cinemachine下载
create 2D Camera
防止溢出屏幕
Extension->select -> CinemachineConfiner(选择一个collider,确定在哪个范围移动镜头)
这里为背景添加一个PolygonCollider 2D(不规则碰撞体)

图层

Sprite Renderer -> Sorting Layer
新增图层,越下面的层级越高,
相同Sorting Layer下,比较 Order in Layer, 值越大,层级越高

Object

Sprite

精灵,承载实体内容,人物一般用这个,把人物图片拖拽到Sprite里面

LayerMask

属于哪个图层
判断是否碰撞到地面:

将Tilemap Layer设置成Ground
Player定义
// 角色碰撞体
public Collider2D coll;
// 图层
public LayerMask ground;
// 角色是否碰撞到地面
coll.IsTouchingLayers(ground)
(角色Controller里面需要指定定义的对象)
// 或者这样检测是否处于地面
// groundCheck是一个Player的子对象,放到Player的脚下。(断绝与子级关系transform.DetachChildren();)
// 地面检测点
public Transform groundCheck;
// 是否有碰撞器(ground)在坐标圆形周围
isGround = Physics2D.OverlapCircle(groundCheck.position, 0.1f, ground);

Tilemap

瓦片,地图,场景变成一块一块的

windows

Tile Palette

windows -> 2D -> Tile Palette
画地图的,画板,将素材托进去,可以选择单个或者多个,多个需要切图,可以点slice,auto,grid by cell size
首先要新建,create new palette,选择文件夹

动画

Animator

add component -> Animater
新建文件夹Animation->Player->
右键create->animator controller->拖拽到component的->Animator->controller
编辑动画,windows->Animation->Animation
窗口点create
将图片拖拽到时间轴

多个动画切换判断

windows->Animator->
右键make Transition
parameters-> +
属性配置Conditions -> Greater 大于某个数值,就切换动画
其中setting下:Has Exit Time,是否需要退出时间

动画中调用函数

Add event -> 然后拖动点击这个event。右边设置Function,即调用的方法

UI

Canvas

首先要新建Canvas,然后在里面新建组件(Text,Button…)
F快捷键定位到Canvas
代码获取

using UnityEngine.UI;

// UI
public Text scoreText;
scoreText.text = cherryScore.ToString();

Dialog

同样在Canvas里面新建一个Panel
然后在Panel里面新建Text之类的
选择位置

渐入动画

这种动画可以录制,同样新建Animation,点击红点录制,调每一帧的属性,整体会有一个动画效果。

C#

base.start()调用基类的start

获取其它对象

// 获取敌人
Enemy enemy = collision.gameObject.GetComponent<Enemy>();

相关方法

// 延迟2秒执行restartGame函数
Invoke("restartGame", 2f);
// 调用公共方法
FindObjectOfType<Enemy>().JumpOn();
// 目录找到object
GameObject.Find("Canvas/MainMenu/UI").SetActive(true);
// 时间流逝速度的缩放比例(暂停游戏)
Time.timeScale = 0f;

镜头偏移

生成一个脚本Parallax

public class Parallax : MonoBehaviour
{
    // 相机
    public Transform Cam;
    // 背景偏移量
    public float moveRateBG;
    private float startPointX;
    private float startPointY;
    // 是否锁定y轴跟随偏移
    public bool lockY;
    void Start()
    {
        // 开始获取坐标
        startPointX = transform.position.x;
    }

    // Update is called once per frame
    void Update()
    {
        if (lockY) {
            transform.position = new Vector2(startPointX + Cam.position.x * moveRateBG, transform.position.y);
        } else {
            transform.position = new Vector2(startPointX + Cam.position.x * moveRateBG, startPointY + Cam.position.y * moveRateBG);
        }
    }
}

拖动到偏移物体,编写镜头,这里镜头要给MainCamera,选择是否锁定Y轴偏移

Audio

  1. 给对象添加Audio Source组件
  2. 把mp3音乐文件拖动到组件中的AudioClip
  3. 脚本调用
    // 跳跃音源
    public AudioSource jumpAudioSource;
    jumpAudioSource.Play();
    // 然后把Audio Source 拖动到脚本的public里面

    关闭所有音乐

    GetComponent<AudioSource>().enabled = false;

打包

失败

  1. BuildMethodException
    UnityEditor.BuildPlayerWindow+BuildMethodException
    代码中引用了“UnityEditor”,无法进行打包编译
    处理方式:
    1. 将带有“UnityEditor”的C#丢进Editor文件夹里面,如果没有Editor文件夹就新建一个
    2. 将带有“UnityEditor”的代码注释掉试试。

安卓

  1. 卡在Building Gradle project
    处理:
    删掉.gradle/daemon文件夹(C:\Users\用户\.gradle\daemon)

常见问题

Input.GetButtonDown没有正确响应

Update跟FixedUpdate的刷新频率不一样,FixedUpdate还没有取到GetButtonDown的值,就被Update先给重置了
相关帖子 https://blog.csdn.net/candycat1992/article/details/22927713

Update是真正和我们机器相关,帧率受不同机器性能影响的函数,而FixedUpdate则是一个Unity自行封装定义的函数,它的默认值一般是0.02m,也就是50fps,我们可以通过Edit -> Project Setting -> Physics来改变调用间隔时间。
因此,Update和FixedUpdate其实是完全独立的两个函数。当Update执行了一次时,FixedUpdate可能已经执行了两次、三次甚至一次都没有执行过。

不要在FixedUpdate里面直接监听Input输入
可以这样写:

// 是否按下跳跃键
public bool jumpAction = false;
// Update每一帧都会调用,因此可以保证所有的输入都可以被响应
   void Update() {
       // 角色跳跃
       if (Input.GetButtonDown("Jump")) {
           jumpAction = true;
       }
   }
void FixedUpdate() {
    // 跳跃
    if (jumpAction) {
        rb.velocity = new Vector2(rb.velocity.x, jumpforce * Time.deltaTime);
        jumpAction = false;
    }
}

  目录