Unity學(xué)習(xí)筆記10二維游戲開發(fā)
概念
1,結(jié)合到場景中的二維圖片或者動畫
2,游戲角色,鼠標(biāo)指針,屏幕字符或者其他移動物體
3,最初表示硬件方式的圖片混合技術(shù)
精靈的存儲方式

上圖是一個打包的精靈資源,包含很多子圖片,游戲引擎可以對這些子圖片進行切塊,并且顯示,來達(dá)到模擬二維
動畫的目的,這個就是精靈的存儲方式。
布告板Billboard
1,是在三維環(huán)境中使用的精靈
2,所在平面總是垂直于攝像機的視線,保證永遠(yuǎn)看到的都是正面
3,縮放圖片的大小來模擬透視,可以旋轉(zhuǎn),和其他物體重疊或者被遮擋
4,可以代替幾何加貼圖的建模方式來極大提升引擎的效率
布告板應(yīng)用范圍
1,粒子系統(tǒng)(比如火,煙霧等),粒子系統(tǒng)中的每個粒子都是由布告板來構(gòu)成的
2,三維物體(一般是一些小物體,小植物,草叢等)
3,角色的某些HUD(比如游戲中出現(xiàn)的"1-Up"/升級等效果,在頭頂上出現(xiàn)的)
4,早期三維游戲的可拾取物體
簡單實踐
創(chuàng)建二維工程
可以顯示在二維場景中的物體,每一個都是Sprite。
將精靈圖片拖拽到場景中,系統(tǒng)會自動添加Sprite ? Renderer組件,這個組件可以自動的渲染精靈圖。
多張圖片混合成的大圖片可以調(diào)整一下Sprite為Multiple,點擊Sprite ?Editor可以對其進行編輯。
編輯界面的左上角的Slice可以切割圖片,有三種類型,自動,按尺寸,按數(shù)量進行切割。切割后Apply
在二維場景中有層級的概念,在Sprite的屬性里的Additional ?Settings中有兩個參數(shù),Sorting Layer指的是所在層
級,Order in Layer 指的是Sprite在這個層級當(dāng)中的順序,數(shù)值大的在前面。
精靈的Pixels ?Per Unit 指的是每一個Unity單位包含多少個像素,修改該數(shù)值可以調(diào)整圖片的大小。
Filter ?Mode(濾波模式):像素游戲不進行濾波,使用Point。
新建一個動畫,作為角色靜止時的動畫,可以將切割后圖片直接拖拽進去,會自動生成動畫。
建立兩個腳本Bullet(子彈腳本)和Spawner(子彈控制腳本)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//子彈行為腳本
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(Collider2D))]
//要求掛接這個腳本的物體包含這兩個屬性
public class NewBehaviourScript : MonoBehaviour
{
? ?public float speed = 2f;//移動速度
? ?private Rigidbody2D body;
? ?// Start is called before the first frame update
? ?void Start()
? ?{
? ? ? ?body = GetComponent<Rigidbody2D>();
? ?}
? ?// Update is called once per frame
? ?void Update()
? ?{
? ? ? ?body.MovePosition(transform.position + speed * transform.right * Time.deltaTime);//right是向前的方向
? ? ? ?//物體的移動,使用MovePosition向著某一個移動
? ?}
? ?private void OnCollisionEnter2D(Collision2D collision)//當(dāng)與其他碰撞體發(fā)生碰撞的時候會調(diào)用該函數(shù)
? ?{
? ? ? ?if(collision.gameObject.tag=="enemy")//如果打到的物體帶有敵人tag
? ? ? ?{
? ? ? ? ? ?GameObject.Destroy(collision.gameObject);//銷毀敵人
? ? ? ? ? ?GameObject.Destroy(gameObject);//銷毀子彈
? ? ? ?}
? ?}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//控制發(fā)射子彈的腳本
public class Spawner : MonoBehaviour
{
? ?//此腳本是讓玩家自動發(fā)射子彈
? ?public float timeInterval = 3f;//每隔3秒發(fā)射子彈
? ?float timer = 0f;//計時器,凍結(jié)時間
? ?public GameObject bullet;//子彈預(yù)制件
? ?// Start is called before the first frame update
? ?void Start()
? ?{
? ? ? ?
? ?}
? ?// Update is called once per frame
? ?void Update()
? ?{
? ? ? ?if(timer>timeInterval)
? ? ? ?{
? ? ? ? ? ?Instantiate(bullet,transform);
? ? ? ? ? ?timer = 0;//重置計時器的凍結(jié)時間
? ? ? ?}
? ? ? ?timer += Time.deltaTime;//每次疊加計時器的時間
? ?}
}
在玩家角色上新建一個空物體,用來發(fā)射子彈,將Spawner腳本掛接上去,制作子彈預(yù)制件,將Bullet腳本掛接上
去。與上面的玩家動畫類似,制作敵人待機動畫。為敵人添加Box Collider 2D碰撞體,并且修改tag。
精靈類型的材質(zhì)默認(rèn)情況是一個Sprite類型的材質(zhì),不受光照的影響。
但也可以令其受光照的影響,新建一個材質(zhì),修改Shader類型為Sprite/Diffuse(漫反射光照),拖拽到某個物體
上,該物體會變暗,因為該物體需要受光照的影響,沒有光照時,就會比較暗。可以建立光源照亮。
一般需要光照信息是在制作美術(shù)資源時就提前畫好的。
瓦片地圖Tilemap
作用:用于構(gòu)造2D關(guān)卡,將瓦片tile按照特定方式排列起來,模擬頂視角,斜視角。
等距透視視圖
2,攝像機處于游戲場景的斜上方并向下轉(zhuǎn)動一定角度來觀察游戲場景
3,游戲中的瓦片都斜向排列
關(guān)系

精靈是原料,
簡單實踐
創(chuàng)建瓦片地圖:GameObject----2D-----Tilemap
在windows窗口中,有一個2D----Tile ?Palette(調(diào)色板)。調(diào)出來后,在左上角可以創(chuàng)建新的調(diào)色板,并且需要
選擇保存的位置,在窗口的上面Active ?Tilemap可以選擇對哪張地圖進行編輯。
將選中的精靈資源拖拽進去,需要為這些調(diào)色板里的資源選擇保存的位置。
選中調(diào)色板里的精靈,可以直接用筆刷的方式在地圖里進行編輯,當(dāng)圖片的大小與地圖的格子不符時,可以選中
Grid修改Cell size 的值。然后進行繪制即可。
可以創(chuàng)建多個Tilemap來進行繪制,關(guān)閉其中一個不影響其他的??梢詫崿F(xiàn)多子地圖類型的地圖系統(tǒng)。
Tilemap也需要碰撞檢測,可以為選中的tilemap添加Tilemap ?Collider 2D組件,添加該組件后,系統(tǒng)自動為該地
圖里的每一個格子加上一個碰撞體,但效率太低,可以添加Composite ?Collider 2D組件(系統(tǒng)會自動同時添加
Rigidbody 2D組件,需要將其Body Type修改為Static類型,地圖一般為靜態(tài)),然后將Tilemap ?Collider 2D中的
Used ?By ?Composite勾選上,這時Tilemap的碰撞體就變成一個整體了。
進行測試:可以為敵人添加一個剛體組件,使其受重力影響,然后運行游戲,可以發(fā)現(xiàn)敵人落在了地圖上。
二維角色
實現(xiàn)
1,和三維角色類似,都可以使用骨架,動畫等;
2,使用精靈圖片來實現(xiàn)
3,精靈保存所有可能的動作序列幀
4,綁定物理體
簡單實踐
使用自帶的Robot資源,然后新建四個動畫,,,
動畫狀態(tài)機中的Any State表示:特殊的狀態(tài)單元,表示任意動畫狀態(tài)(就比如跳躍,在站立,走路,跑步狀態(tài)下都可以進行)

Parameters:參數(shù) ? ? ? ?Greater:大于 ? ? ? ? less:少于
新建兩個參數(shù),一是float類型的speed,用來控制角色的移動速度(以速度的值來控制角色在站立,跑步,走路狀
態(tài)的轉(zhuǎn)換),一個是bool類型的ground,用來表示角色是否在地面上,如果不是在地面上,就開始播放jump動
畫。
然后將Any state轉(zhuǎn)換到j(luò)ump動畫的線上添加ground條件

jump動畫到idle動畫添加

idle狀態(tài)到walk狀態(tài)

walk到run狀態(tài),speed大于0.1,,,其他狀態(tài)的轉(zhuǎn)換同理可知。運行游戲,修改speed和ground來測試狀態(tài)機
force:力
新建一個角色控制腳本,拖拽給場景中的Robot
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Robot : MonoBehaviour
{
? ?public float m_Maxspeed = 10f;//最大速度
? ?public float m_jumpForce = 400f;
? ?public LayerMask m_WhatIsGround;//地面的Layer類型
? ?public Transform m_GroundCheck;//在角色的腳底掛接一個空物體來檢查地面
? ?const float k_GroundedRadius = 0.5f;//檢查地面時做一個冗余,半徑是0.5
? ?public bool m_Grounded;//表示是否在地面上
? ?private Animator m_Anim;//用來得到當(dāng)前角色的Animator組件
? ?private Rigidbody2D m_Rigidbody2D;
? ?public bool m_FacingRight = true;//用來表示角色是否朝向右邊
? ?public bool m_Jump;//是否處于跳躍狀態(tài)
? ?// Start is called before the first frame update
? ?private void Awake()
? ?{
? ? ? ?m_GroundCheck = transform.Find("GroundCheck");//找到名為GroundCheck的物體
? ? ? ?m_Anim = GetComponent<Animator>();
? ? ? ?m_Rigidbody2D = GetComponent<Rigidbody2D>();//得到角色身上的對應(yīng)組件
? ?}
? ?void Start()
? ?{
? ? ? ?
? ?}
? ?// Update is called once per frame
? ?void Update()
? ?{
? ? ? ?
? ?}
? ?private void FixedUpdate()
? ?{
? ? ? ?m_Grounded = false;//默認(rèn)情況不在地面上
? ? ? ?//OverlapCircleAll檢查一下以一個點做一個圓,在這個圓內(nèi)是否有其他物體(碰撞體)的存在,如果有,將其他物體的colliders返回
? ? ? ?//有三個參數(shù),第一個是中心點的位置,第二個是半徑,第三個是Layer,可以將特定的Layer納入檢查范圍,不一定檢查所有的物體
? ? ? ?Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position,k_GroundedRadius,m_WhatIsGround);
? ? ? ?for(int i=0;i<colliders.Length;++i)
? ? ? ?{
? ? ? ? ? ?if(colliders[i].gameObject!=gameObject)//如果不是當(dāng)前物體的話,就表示碰撞到地面了
? ? ? ? ? ?{
? ? ? ? ? ? ? ?m_Grounded = true;
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?m_Anim.SetBool("ground", m_Grounded);//使用SetBool來修改ground的值為第二個參數(shù)
? ? ? ?//下面代碼控制角色的運動行為
? ? ? ?float h = Input.GetAxis("Horizontal");//看玩家是否按下了左右鍵 Horizontal:水平的
? ? ? ?if(!m_Jump)
? ? ? ?{
? ? ? ? ? ?m_Jump = Input.GetKeyDown(KeyCode.Space);//如果不是處于跳躍狀態(tài),檢測玩家是否按下了空格鍵
? ? ? ?}
? ? ? ?Move(h, m_Jump);
? ? ? ?m_Jump = false;
? ?}
? ?public void Move(float move,bool jump)//控制角色移動
? ?{
? ? ? ?if(m_Grounded)//如果在地面上
? ? ? ?{
? ? ? ? ? ?m_Anim.SetFloat("speed",Mathf.Abs(move));//Mathf.Abs()絕對值
? ? ? ? ? ?m_Rigidbody2D.velocity = new Vector2(move*m_Maxspeed,m_Rigidbody2D.velocity.y);//velocity表示的是速度
? ? ? ? ? ?if(move>0&&!m_FacingRight)//如果角色向右移動,但是角色沒有朝向右邊,則需要反轉(zhuǎn)一下方向
? ? ? ? ? ?{
? ? ? ? ? ? ? ?Flip();
? ? ? ? ? ?}
? ? ? ? ? ?else if(move < 0 && m_FacingRight)//與上面相反的
? ? ? ? ? ?{
? ? ? ? ? ? ? ?Flip();
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?//如果不在地面上,處理關(guān)于跳躍的操作
? ? ? ?if (m_Grounded && jump && m_Anim.GetBool("ground"))
? ? ? ?{
? ? ? ? ? ?//角色在地面上,并且玩家按下了跳躍鍵,并且動畫機里的ground也是在地面
? ? ? ? ? ?//GetBool得到“”里的參數(shù)
? ? ? ? ? ?m_Grounded = false;
? ? ? ? ? ?m_Anim.SetBool("ground",false);
? ? ? ? ? ?m_Rigidbody2D.AddForce(new Vector2(0, m_jumpForce));//給角色一個向上的力
? ? ? ?}
? ?}
? ?void Flip()
? ?{
? ? ? ?m_FacingRight = !m_FacingRight;//朝向求反
? ? ? ?//反轉(zhuǎn)操作
? ? ? ?Vector3 theScale = transform.localScale;
? ? ? ?theScale.x *= -1;
? ? ? ?transform.localScale = theScale;
? ?}
}
將參數(shù)What Is ground 修改為Everything(所有物體都檢測)
然后給Robot添加一個空物體GroundCheck,并且需要將這個空物體放到地面的位置。(用來完成地面檢測)。
然后拖拽到腳本中。
給Robot添加Rigidbody 2D和Capsule Collider 2D,然后點擊Capsule Collider 2D中的edit collider,修改一下
Robot的碰撞檢測范圍,使其貼合游戲角色。
勾選Robot的Freeze Roation ,鎖定Z方向的旋轉(zhuǎn)自由度,使其不受摩擦力的影響

在將所有動畫狀態(tài)轉(zhuǎn)換之間的Has Exit Time勾掉,這樣動作的轉(zhuǎn)換不會有延遲,轉(zhuǎn)換立即發(fā)生,而不是等上一個
動畫播放完成之后在轉(zhuǎn)換。
重新繪制一下Tilemap

并為其添加Platform ?Effector 2D組件(平臺效果),需要將里面的Use One Way(單向平臺),需要和
Composite Collider 2D組件配合使用,需要將Used By Effector勾選上。運行游戲,測試是否可以跳躍到平臺
上。
二維角色骨架系統(tǒng)
二維動畫有兩種形式,關(guān)鍵幀動畫和骨骼動畫,關(guān)鍵幀是通過保存一系列圖片來生成動畫(問題是保存的數(shù)據(jù)量很大,且角色很難和場景中的其他物體發(fā)生有效的交互。)

與三維骨骼動畫類似
簡單實踐
骨骼動畫是主流的動畫控制方法。
需先在包管理器中安裝2D Animation組件。
選中一個Sprite,點擊Sprite ?Editor進行編輯

進入后選擇骨骼編輯

點擊Create ?bone 創(chuàng)建骨骼,在圖片上進行繪制骨骼,在preview pose狀態(tài)下,點擊Visibility可以看到已經(jīng)創(chuàng)建的骨骼層次。

Auto Geometry-->Generate ?for ?Selected自動生成網(wǎng)格,網(wǎng)格依附于骨骼而運動,并且網(wǎng)格相對于骨骼具有權(quán),在Weight中,

Auto Weigth可以自動生成權(quán)重。
完成后放到場景中,為其添加Sprite ?Skin 組件,點擊Create Bones,unity會自動的將建好的骨骼綁定到角色
上。創(chuàng)建新的動畫,點擊錄制按鈕,建兩個關(guān)鍵幀,在關(guān)鍵幀處運動骨骼后保存,運行游戲即可看到關(guān)鍵幀的效
果。