小狐狸横版游戏开发学习笔记(上)
小狐貍橫版游戲開發學習筆記(上)
目錄
小狐貍橫版游戲開發學習筆記(上)
1.關于如何創建Tilemap
2.關于地圖格子之間出現間隙的問題
?3.如何設置自己想要的控制按鍵
4.如何解決玩家移動過程中造成的卡頓問題
5.如何添加動畫
6.動畫轉換(有部分是其它項目中的截圖,放在一起是為了更全面的理解)
7.如何解決,玩家與地圖穿插顯示在頁面最前方的問題
8.如何解決下落轉換為初始狀態太慢的問題
9.關于鏡頭的移動
10.如果不想讓鏡頭超出邊界
1.關于如何創建Tilemap
2.關于地圖格子之間出現間隙的問題
將地圖間隙修改為-0.001
?3.如何設置自己想要的控制按鍵
4.如何解決玩家移動過程中造成的卡頓問題
首先需要添加一個組合碰撞體Composite Collider 2D,添加完之后會自動生成一個剛體組件
將剛體組件中的Body Type屬性由原來的Dynamic改為Static,然后將Geometry Type的屬性改為Polygons(相當于將碰撞體設置為了實心),若設置為outlines,當角色速度過快時,容易發生穿模。
勾選used by composite(復合碰撞體)
?
5.如何添加動畫
首先需要將角色掛接上Animator組件
其次在Assets資源中新建一個Animation文件夾,用來存放Animator Controller
(這里新建了一個Animation Controller,并將其重命名為Player)并將其掛接至Animator上
?
?打開Animation窗口(ctrl+6)先點擊所要掛接對象(這里是Player),再點擊Create,創建動畫
?
選中每幀的動作,將其像素改成相應的大小,再將其選中拖入時間軸
如果速度過快,則將Samples(幀頻)的大小改小
?
?
打開Animator窗口
6.動畫轉換(有部分是其它項目中的截圖,放在一起是為了更全面的理解)
增加一個變量,用于控制狀態轉換
?
取消勾選Has Exit Time,因為在這里我們需要角色立刻退出當前狀態,不需要延時
把Transition Duration改成0,因為我們不需要轉換時間,我們希望它立刻改變狀態
?
?Runright狀態轉換成idle的時候,需要將greater改為less
?
?如果想要建立BlenderTree,則右鍵Create new BlendTree
能夠根據不同的參數來調整同一狀態的的不同方向動畫,下面是添加參數的流程?
?
?
?這樣才能將參數掛上去,如下所示
?
?然后根據代碼,將數值傳入
7.如何解決,玩家與地圖穿插顯示在頁面最前方的問題
由于小狐貍和tilemap(地圖)都在同一個圖層,將order in layer改為負數,代表地圖在小狐貍的后方,這樣就不會出現小狐貍穿過梯子時,不斷閃爍的問題
?
?若想查看任務狀態的轉換,可以開啟Base Layer和Game同步,這樣就可以清晰地看清楚,不同狀態之間的轉換,如果要看動畫狀態的轉換,需要先選中角色
8.如何解決下落轉換為初始狀態太慢的問題
由于發現 通過判斷縱向速度是否為0十分不便,player.velocity.y是浮點數,讓其判斷為0時從falling狀態改為idling狀態,會產生延遲現象,所以我們需要通過設置:判斷當玩家處于下落狀態,并碰到地面時,玩家狀態便會立即轉換成idling,以下是操作步驟:
我們需要利用定義LayerMask,用來獲得地面的信息
Collider2D 用來獲取到小狐貍的碰撞體
?將Tilemap加至ground圖層
?
?將我們創建的用來獲取地面信息的變量,改成Ground圖層,由于Ground圖層表示的是tilemap,因此我們就獲得了地面信息
?將小狐貍的碰撞體掛接到coll上
然后我們通過代碼,小狐貍的碰撞體是否碰到了地面圖層
如果碰到地面圖層,idling狀態為true,falling狀態為false
9.關于鏡頭的移動
為Main Camera添加腳本,讓攝像機的位置隨著角色而移動,所以我們需要讓攝像機獲取小狐貍的位置x與y,z不變為-10;
?若想要在一定的范圍內角色不動,超過一定范圍之后,鏡頭才隨著角色的移動而移動,我們需要下載一個插件camerachine,如下圖所示
?
?
將角色掛接到相機的follow對象,改變body中的Dead Zone Width和Height
能夠控制角色位置移動,但相機不跟隨的范圍,步驟如下:
?
10.如果不想讓鏡頭超出邊界
為新添加的鏡頭增加擴展,CinemachineConfiner,限制鏡頭的位置
?
?此時會有一個Bounding Shape 2D需要掛接collider 2D(表示不能出的范圍區域)
?
由于我們想要的是范圍不出background,所以我們需要為background添加polygon Collider 2D
并點擊Edit Collider來設置范圍,摁住ctrl再點擊點,可以去掉該點
?
?將Background掛接,并將is Trigger勾選,否則小狐貍會因為碰撞體相互碰撞被彈出該范圍
?
下面為部分代碼展示
小狐貍:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class PlayerController : MonoBehaviour {//[SerializeField]Rigidbody2D player; 前面加上SerializeField能夠將該變量顯示出來,但是無法更改Rigidbody2D player;public float speed = 5.0f;public float jumpforce = 3.0f;Animator anim;public LayerMask ground;public Collider2D coll;private int cherry = 0;private int gem = 0;public Text charryNumber;public Text gemNumber;private bool isHurt;//默認是falsepublic AudioSource jump;public AudioSource cherrySound;public AudioSource gemSound;public AudioSource hitSound;float horizontalmove;//只有三種情況會出現:1、-1、0,右為正,左為負,不動為零float facedirection;// Start is called before the first frame updatevoid Start(){player = GetComponent<Rigidbody2D>();anim = GetComponent<Animator>();}// Update is called once per framevoid Update(){if(!isHurt)//當玩家沒有受傷時,才調用Movement,防止角色碰到敵人后不會被彈開{Movement();}Getposition();//每次刷新時都獲取位置Switchanim();charryNumber.text = cherry + "";//將charry的值轉變為字符串型賦給charryNumber的text,同時能夠使用cherry.ToString()gemNumber.text = gem.ToString();//利用了另一種表達,將int類型變為字符串類型}private void FixedUpdate(){}void Getposition()//獲取位置{horizontalmove = Input.GetAxis("Horizontal");//獲取水平移動facedirection = Input.GetAxisRaw("Horizontal");//獲取面朝的方向,左為-1,將該值給到scale的x,即可改變面朝像//if (Input.GetButtonDown("Jump"))//{// player.velocity = new Vector2(player.velocity.x, 5);//}}void Movement(){if (horizontalmove!=0){player.velocity = new Vector2(horizontalmove*speed, player.velocity.y);//player.velocity表示玩家的速度,第一個是水平方向,第二個是豎直方向anim.SetFloat("running",Mathf.Abs(horizontalmove));}if(facedirection!=0){player.transform.localScale = new Vector3(facedirection,1,1);//將該值給到scale的x,即可改變面朝像}//跳躍//coll.IsTouchingLayers(ground)可換成anim.GetBool("idling")|| anim.GetBool("running")if (Input.GetButtonDown("Jump")&& coll.IsTouchingLayers(ground)){player.velocity = new Vector2(player.velocity.x, 8);jump.Play();anim.SetBool("jumping",true);}//Vector2 position = player.position;//position.x = player.position.x + horizontalmove * speed * Time.deltaTime;//player.MovePosition(position);//等于player.position=position;}void Switchanim(){if (player.velocity.y < 0.1f && !coll.IsTouchingLayers(ground)){anim.SetBool("falling", true);}anim.SetBool("idling",false);if (anim.GetBool("jumping")){if( player.velocity.y < 0){anim.SetBool("jumping", false);anim.SetBool("falling", true);}}else if (isHurt)//必須要加在else if (coll.IsTouchingLayers(ground))之前,因為人物一直挨著地面,就不會進行到下一個的if條件判斷{if (Mathf.Abs(player.velocity.x) < 0.1f){isHurt = false;anim.SetBool("hurt", false);anim.SetBool("idling",true);}}else if (coll.IsTouchingLayers(ground)){anim.SetBool("idling", true);anim.SetBool("falling", false);}}private void OnTriggerEnter2D(Collider2D collision){if (collision.tag=="collection"){cherrySound.Play();Destroy(collision.gameObject);cherry += 1;}if (collision.tag == "collection2"){gemSound.Play();Destroy(collision.gameObject);gem += 1;}}private void OnCollisionEnter2D(Collision2D collision)//由于不能將敵人勾選is trigger,如果勾選,敵人將會直接掉出地圖之外,所以這個地方不能使用OnTriggerEnter2D函數{if (collision.gameObject.tag == "Enemies")//OnCollisionEnter2D與OnTriggerEnter2D不同,它需要先取到它本身,再取出tag,所以寫為collision.gameObject.tag{//當小狐貍碰撞到敵人時Enemy enemy = collision.gameObject.GetComponent<Enemy>();if (anim.GetBool("falling"))//同時當小狐貍處于下落狀態時,碰撞敵人后,敵人消失{enemy.Death();player.velocity = new Vector2(player.velocity.x, 7);//敵人消失后,做一個跳躍的動作豐富場景//anim.SetBool("jumping", true);我認為這句話沒什么用,因為在動畫轉換中根本沒有下落轉跳躍的箭頭}//下面是教程中給的方法else if (transform.position.x > collision.gameObject.transform.position.x){hitSound.Play();//當小狐貍不是下落碰撞時,會被彈走player.velocity = new Vector2(5, player.velocity.y);isHurt = true;//由于程序是在不斷刷新的,Movement不斷地在被調用,不摁住鍵盤輸入指令,小狐貍就不會動,也不會被彈開,所以需要用isHurt來控制Movement是否執行(在update與Switchanim中用if語句控制)anim.SetBool("hurt", true);anim.SetFloat("running", 0);}else if (transform.position.x < collision.gameObject.transform.position.x){hitSound.Play();player.velocity = new Vector2(-5, player.velocity.y);isHurt = true;//由于程序是在不斷刷新的,Movement不斷地在被調用,不摁住鍵盤輸入指令,小狐貍就不會動,也不會被彈開,所以需要用isHurt來控制Movement是否執行(在update與Switchanim中用if語句控制)anim.SetBool("hurt", true);anim.SetFloat("running", 0);}//以下是我自己的方法//else//{// hitSound.Play();// player.velocity = new Vector2(-5.0f * facedirection, player.velocity.y);//彈走的方向與小狐貍面朝的方向相反// isHurt = true;// anim.SetBool("hurt", true);// anim.SetFloat("running", 0);//} }} }敵人父類
using System.Collections; using System.Collections.Generic; using UnityEngine;public class Enemy : MonoBehaviour {protected Animator anim;protected AudioSource death;// Start is called before the first frame updateprotected virtual void Start()//virtual代表虛擬的,相當于這個父級是可以被子級重新編寫的{anim = GetComponent<Animator>();death = GetComponent<AudioSource>();}public void Death(){death.Play();anim.SetTrigger("death");}public void Jumpup(){Destroy(gameObject);}// Update is called once per framevoid Update(){} }敵人—青蛙(子類):
using System.Collections; using System.Collections.Generic; using UnityEngine;public class Enemy_Frog : Enemy {private Rigidbody2D fg;//private Animator anim;public Transform left;//獲取左側物體的位置public Transform right;//獲取右側物體的位置private float leftx;//左側物體的x坐標private float rightx;//右側物體的x坐標public float speed,jumpForce;//設置速度(外部可更改)private bool faceleft=true;//用來判斷朝向是否向左private Collider2D coll;public LayerMask ground;// Start is called before the first frame updateprotected override void Start(){base.Start();coll = GetComponent<Collider2D>();//anim = GetComponent<Animator>();fg = GetComponent<Rigidbody2D>();//由于左右兩個物體是敵人的子物體,所以如果敵人移動那么兩個子物體也會跟著一起移動//永遠也到不了左側物體的左邊,敵人會一直向左移動,所以需要利用DetachChildren()方法斷絕父子關系transform.DetachChildren();leftx = left.position.x;//獲取左側物體的位置rightx = right.position.x;//獲取右側物體的位置//斷絕父子關系后子物體會在Hierarchy出現,當敵人多了之后就會有很多子物體出現在Hierarchy中,影響觀感和性能Destroy(left.gameObject);//所以在這里,我們直接將兩個子物體銷毀Destroy(right.gameObject);}// Update is called once per framevoid Update(){Switch();}void Movement(){if (faceleft)//當面朝左側的時候{if (coll.IsTouchingLayers(ground)){anim.SetBool("jumping", true);fg.velocity = new Vector2(-speed, jumpForce);}//向左移動if (transform.position.x < leftx)//當敵人的x坐標小于左側的坐標時,青蛙朝向向右{transform.localScale = new Vector3(-1, 1, 1);fg.velocity = new Vector2(speed, fg.velocity.y);//為了防止青蛙面朝右側,卻還向左跳的bugfaceleft = false;//向左的標志為false;}}else{if (coll.IsTouchingLayers(ground)){anim.SetBool("jumping", true);fg.velocity = new Vector2(speed, jumpForce);}if (transform.position.x > rightx){transform.localScale = new Vector3(1, 1, 1);fg.velocity = new Vector2(-speed, fg.velocity.y);faceleft = true;}}}void Switch(){if (anim.GetBool("jumping")&&fg.velocity.y < 0){anim.SetBool("jumping", false);anim.SetBool("falling", true);//跳躍轉換為下落}if (anim.GetBool("falling") && coll.IsTouchingLayers(ground)){anim.SetBool("falling", false);//下落轉換成idle的條件}}}(想要獲得全部項目資源或代碼請在下方留言或私信)
總結
以上是生活随笔為你收集整理的小狐狸横版游戏开发学习笔记(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 建筑工程图上的尺寸数字
- 下一篇: 功利主义穆勒思维导图_穆勒——《功利主义