概念1:預製體PreFab
將一個GameObject製作成一個元件模板,用於批次套用。
向場景新增一個預製體時,會建立一個它的範例,可在不同場景或同一場景建立多個預製體的範例,當修改預製體的屬性時,這些修改也應用在所有範例上。
概念2:碰撞器Box collider
兩個碰撞的物體身上都要有碰撞器元件,其中至少有一個為剛體Rigidbody(最好是運動的一方)
原理:剛體長時間不運動會休眠以提升程式效能,如果選擇不運動的為剛體,可能互動無效。
其中2D、3D謹防混用,混用則無效
概念3:元件層級Layer
Camera-Sorting Layer-Order In layer
概念4:音訊源Audio Source
屬性 | 說明 |
---|---|
Audio Clip | 設定被播放的音訊檔 |
Mute | 靜音播放 |
Play On Awake | 喚醒時播放 |
指令碼結構:
public class XXX:Monobehaviour{ //繼承Unity的Monobehaviour部分方法
void Start(){ //遊戲執行第一幀執行
}
void Update(){ //遊戲每執行一幀執行一次
}
}
選單頁通過鍵盤【W】、【S】鍵控制指標選擇單/雙人遊戲,點選空格鍵確認選項並開始遊戲。玩家有三點生命值,在每次生成後的三秒內帶有保護盾,敵方攻擊無效。遊戲開始後生成三架敵方坦克,此後每隔四秒隨機生成敵方坦克,當玩家坦克被擊殺三次或最下方巢穴被敵方炸燬後遊戲失敗,失敗後玩家不可控制坦克移動,三秒後跳轉回選單頁。遊戲頁右側圖示和數位顯示被玩家擊殺的坦克數和玩家剩餘生命值。【ESC】退出遊戲。
玩家指令碼:
public class Player : MonoBehaviour
{
public float moveSpeed=3;
private Vector3 bulletEulerAngles;
private float timeVal;//設定攻擊CD
private float defendTimeVal=3;
private bool isDefended=true;
private SpriteRenderer sr;
public Sprite[] tankSprite;//依次為上右下左
public GameObject bulletPrefab;
public GameObject explosionPrefab;
public GameObject defendEffectPrefab;//受保護參照
public AudioSource moveAudio;//音效元件參照,控制音效播放
public AudioClip[] tankAudio;//音效素材,拿到資源,控制渲染器參照
public void Awake()//屬性等在awake中賦值,一開始就拿到
{
sr = GetComponent<SpriteRenderer>();
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//是否處於無敵狀態
if(isDefended)
{
defendEffectPrefab.SetActive(true);
defendTimeVal -= Time.deltaTime;
if(defendTimeVal<=0)
{
isDefended = false;
defendEffectPrefab.SetActive(false);
}
}
}
private void FixedUpdate()//固定物理幀,規定佔用時間固定
{
if(PlayerManager.Instance.isDefeated)
{
return;
}
Move();
if(timeVal>=0.4f)
{
Attack();
}
else
{
timeVal += Time.fixedDeltaTime;
}
}
private void Attack()
{
if(Input.GetKeyDown(KeyCode.Space))
{
//2D遊戲旋轉方向與3D相反
Instantiate(bulletPrefab,transform.position,Quaternion.Euler(transform.eulerAngles+bulletEulerAngles));//最後一個引數:尤拉角轉變成四元數
timeVal = 0;
}
}
//坦克移動
private void Move()
{
float h = Input.GetAxisRaw("Horizontal");//h和v值為1或-1
transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime,Space.World);
//改變轉向:1.更換不同圖片 2.直接改變圖片轉向
if(h<0)
{
sr.sprite = tankSprite[3];
bulletEulerAngles =new Vector3(0,0,90);
}
else if(h>0)
{
sr.sprite = tankSprite[1];
bulletEulerAngles =new Vector3(0,0,-90);
}
if(Mathf.Abs(h)>0.05f)
{
moveAudio.clip = tankAudio[1];
if(!moveAudio.isPlaying)
{
moveAudio.Play();
}
}
if(h!=0)//設定優先順序,橫向優先
{
return;
}
float v = Input.GetAxisRaw("Vertical");
transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime,Space.World);
if(v<0)
{
sr.sprite = tankSprite[2];
bulletEulerAngles =new Vector3(0,0,180);
}
else if(v>0)
{
sr.sprite = tankSprite[0];
bulletEulerAngles =new Vector3(0,0,0);
}
if(Mathf.Abs(v)>0.05f)
{
moveAudio.clip = tankAudio[1];
if(!moveAudio.isPlaying)
{
moveAudio.Play();
}
}else{
moveAudio.clip = tankAudio[0];
if(!moveAudio.isPlaying)
{
moveAudio.Play();
}
}
}
public void Die()
{
if(isDefended)
{
return;
}
PlayerManager.Instance.isDead = true;
//爆炸特效
Instantiate(explosionPrefab,transform.position, transform.rotation);
//坦克死亡
Destroy(gameObject);
}
}
炸彈指令碼
public class Bullet : MonoBehaviour
{
public float moveSpeed=10;
public bool isPlayerBullet;//不設定預設為false
public AudioClip hitAudio;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//Translate的第一個引數是沿著世界座標移動時最後一個引數可寫可不寫,預設世界座標
//沿著自身座標移動時,最後一個引數一定要寫
transform.Translate(transform.up * moveSpeed * Time.deltaTime, Space.World);
}
private void OnTriggerEnter2D(Collider2D collision)
{
switch(collision.tag)
{
case "Tank":
if(!isPlayerBullet)
{
collision.SendMessage("Die");
Destroy(gameObject);
}
break;
case "Heart":
collision.SendMessage("Die");
Destroy(gameObject);
break;
case "Enemy":
if(isPlayerBullet)
{
collision.SendMessage("Die");
Destroy(gameObject);//銷燬自身
}
break;
case "Wall":
if(isPlayerBullet)
{
PlayAudio();
}
Destroy(collision.gameObject);
Destroy(gameObject);//銷燬牆和炮彈本身
break;
case "Barrier":
if(isPlayerBullet)
{
PlayAudio();
}
Destroy(gameObject);
break;
default:
break;
}
}
public void PlayAudio()
{
AudioSource.PlayClipAtPoint(hitAudio,transform.position);
}
}
首頁面選擇單人/雙人遊戲
攻擊敵人
顯示攻擊敵人的數量和剩餘生命值
遊戲失敗
儲存並命名場景-find-Build Settings-Build-選擇打包到的目錄。
踩坑:
UnityError.BuildPlayerWindow+BuildMaethodException:2 errors
解決方法:
選擇打包目錄時建立一個空資料夾存放。
字型顯示模糊