Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Unity遊戲程式設計(15) 實作Space shooter遊戲

1,444 views

Published on

官網Space shooter遊戲step by step教學

Published in: Software
  • Be the first to comment

  • Be the first to like this

Unity遊戲程式設計(15) 實作Space shooter遊戲

  1. 1. 電子工程系 Unity遊戲程式設計(15) Space shooter遊戲 吳錫修 June 12, 2017
  2. 2. shapethefuture Space Shooter tutorial套件 2 Wu, ShyiShiou Dept. of E.E., NKUT
  3. 3. shapethefuture  https://unity3d.com/learn/tutorials/projects/space-shooter-tutorial 線上教學影片 3 Wu, ShyiShiou Dept. of E.E., NKUT
  4. 4. shapethefuture  新增3D專案  選單命令File> New Project…  專案名稱Space shooter  儲存預設場景  Main.unity  滙入Space Shooter tutorial.unitypackage  選單命令Assets> Import Package> Custom Package… 專案設定 1/2 4 Wu, ShyiShiou Dept. of E.E., NKUT
  5. 5. shapethefuture  設定場景大小  選單命令File> Build Settings…  點擊Player Settings  取消勾選Default Is Full Screen*  Default Screen Width: 600  Default Screen Height: 900 專案設定 2/2 5 Wu, ShyiShiou Dept. of E.E., NKUT
  6. 6. shapethefuture  拖曳Models/vehicle_playerShip到Hiearchy面板  重新命名:Player  重置Transform參數值  設定Player戰機為剛體物件  選單命令Component> Physics> Rigidbody  取消勾選Use Gravity以符合外太空無重力環境 建立玩家戰機物件 1/2 6 Wu, ShyiShiou Dept. of E.E., NKUT
  7. 7. shapethefuture  在Player戰機上加上網格碰撞器  選單命令Component> Physics> Mesh Collider  勾選Convex  勾選Is Trigger  簡化網格,拖曳Models/player_ship_collider到Mesh欄  設定Player戰機引擎噴射效果  拖曳PrefabsVFXEnginesengines_player預製物件做為Player子物件 建立玩家戰機物件 2/2 7 Wu, ShyiShiou Dept. of E.E., NKUT
  8. 8. shapethefuture  重置Main Camera之Transform參數值  使Main Camera朝下  Rotation (X, Y, Z) = (90, 0, 0)  使Main Camera移動Player戰機到上方  Position (X, Y, Z) = (0, 10, 0)  將Main Camera投影方式設定為正交投影  Projection = Orthographic  Size = 10  調整Player戰機在畫面初始顯示位置  Main Camera Position (X, Y, Z) = (0, 10, 5) 攝影機設定 1/2 8 Wu, ShyiShiou Dept. of E.E., NKUT
  9. 9. shapethefuture  設定Main Camera鏡頭底色  Clear Flags = Solid Color  Background = black 攝影機設定 2/2 9 Wu, ShyiShiou Dept. of E.E., NKUT
  10. 10. shapethefuture  刪除Directional Light  取消環境光  選單命令Window> Lighting> Settings開啟Lighting面板  Skybox Material = none  Ambient Color = black 光照設定 1/3 10 Wu, ShyiShiou Dept. of E.E., NKUT
  11. 11. shapethefuture  建立主光源  選單命令GameObject> Light> Directional Light,更名為Main Light  重置Position  調整光線角度,Rotation (X, Y, Z) = (20, -115, 0)  建立補光  選單命令Edit> Duplicate (Ctrl-D)複製⼀份Main Light,更名為Fill Light  重置Rotation  調整補光強度,Intensity = 0.5  調整補光角度,Rotation (X, Y, Z) = (5, 125, 0)  調整補光顏色,Color (R, G, B) = (128, 192, 192) 光照設定 2/3 11 Wu, ShyiShiou Dept. of E.E., NKUT
  12. 12. shapethefuture  建立邊緣反射光  複製Fill Light,更名為Rim Light  重置Transform  調整邊緣反射光顏色,Color = white  調整邊緣反射光角度,Rotation (X, Y, Z) = (-15, 65, 0)  調整邊緣反射光強度,Intensity = 0.25  管理光源物件  選單命令GameObject> Create Empty,更名為Lighting  重置Transform  Position (X, Y, Z) = (0, 100, 0)  將Main Light、Fill Light及Rim Light拖曳到Lighting下做為子物件 光照設定 3/3 12 Wu, ShyiShiou Dept. of E.E., NKUT
  13. 13. shapethefuture  選單命令GameObject> 3D Object> Quad,新增Quad做為背景 物件,更名為Background  重置Transform屬性值  使Background物件面向Main Camera  Rotation (X, Y, Z) = (90, 0, 0)  調整Background物件大小,使其可以填滿整個遊戲畫面  Scale (X, Y, Z) = (15, 30, 0)  設定背景材質  拖曳Materialstile_nebula_green_diff到Background上 設定遊戲背景 1/2 13 Wu, ShyiShiou Dept. of E.E., NKUT
  14. 14. shapethefuture  移除Mesh Collider  將材質Shader欄變更為Unlit/Texture  調整Background物件位置到Player戰機下方  Position (X, Y, Z) = (0, -10, 0) 設定遊戲背景 2/2 14 Wu, ShyiShiou Dept. of E.E., NKUT
  15. 15. shapethefuture  在Player物件加上PlayerController程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { void FixedUpdate () { Rigidbody rigidBody = GetComponent<Rigidbody> (); float moveHorizontal = Input.GetAxis ("Horizontal"); float moveVertical = Input.GetAxis ("Vertical"); Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical); rigidBody.velocity = movement; } } 玩家戰機移動控制 1/5 15 Wu, ShyiShiou Dept. of E.E., NKUT
  16. 16. shapethefuture  執行測試,可使用方向鍵移動Player戰機,但是…  移動速度很慢  在PlayerController程式腳本加入速度參數 public class PlayerController : MonoBehaviour { public float speed; void FixedUpdate () { Rigidbody rigidBody = GetComponent<Rigidbody> (); float moveHorizontal = Input.GetAxis ("Horizontal"); float moveVertical = Input.GetAxis ("Vertical"); Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical); rigidBody.velocity = movement * speed; } } 玩家戰機移動控制 2/5 16 Wu, ShyiShiou Dept. of E.E., NKUT
  17. 17. shapethefuture  將PlayerController之Speed欄設定為10  執行測試,Player戰機移動速度變快了,但是…  Player戰機會跑出螢幕  修改PlayerController程式腳本,限制Player戰機移動範圍 using System.Collections; using System.Collections.Generic; using UnityEngine; [System.Serializable] public class Player_Boundary { public float xMin, xMax, zMin, zMax; } 玩家戰機移動控制 3/5 17 Wu, ShyiShiou Dept. of E.E., NKUT
  18. 18. shapethefuture public class PlayerController : MonoBehaviour { public float speed; public float tilt; public Player_Boundary boundary; void FixedUpdate () { Rigidbody rigidBody = GetComponent<Rigidbody> (); float moveHorizontal = Input.GetAxis ("Horizontal"); float moveVertical = Input.GetAxis ("Vertical"); Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical); rigidBody.velocity = movement * speed; rigidBody.position = new Vector3 ( Mathf.Clamp (rigidBody.position.x, boundary.xMin, boundary.xMax), 0.0f, Mathf.Clamp (rigidBody.position.z, boundary.zMin, boundary.zMax)); rigidBody.rotation = Quaternion.Euler ( 0.0f, 0.0f, rigidBody.velocity.x * -tilt); } } 玩家戰機移動控制 4/5 18 Wu, ShyiShiou Dept. of E.E., NKUT
  19. 19. shapethefuture  設定Player戰機之Boundry值  調整Player戰機Position之X值,測試最左及最右位置值  調整Player戰機Position之Z值,測試上方及下方位置值  執行測試,Player戰機不會跑出場景範圍了 玩家戰機移動控制 5/5 19 Wu, ShyiShiou Dept. of E.E., NKUT
  20. 20. shapethefuture  選單命令GameObject> Create Empty,更名為Bolt  重置Transform屬性值  選單命令GameObject> 3D Object> Quad,更名為VFX  重置Transform屬性值  使VFX面向Main Camera  Rotation (X, Y, Z) = (90, 0, 0)  移除Mesh Collider元件  拖曳VFX到Bolt下做為子物件 建立玩家戰機子彈 1/4 20 Wu, ShyiShiou Dept. of E.E., NKUT
  21. 21. shapethefuture  選單命令Assets> Create>Material新增材質球,更名為 fx_bolt_orange  Shader = Particles/Additive  Particle Texture = fx_lazer_orange_dff  拖曳fx_bolt_orange材質到VFX物件上  Bolt物件加上Rigidbody元件  取消勾選Use Gravity  Bolt物件加上Capsule Collider元件  Direction = Z-Axis  Radius = 0.03,Height = 0.5  勾選Is Trigger 建立玩家戰機子彈 2/4 21 Wu, ShyiShiou Dept. of E.E., NKUT
  22. 22. shapethefuture  Bolt物件加上Mover程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class Mover : MonoBehaviour { public float speed; // Use this for initialization void Start () { GetComponent<Rigidbody>().velocity = transform.forward * speed; } } 建立玩家戰機子彈 3/4 22 Wu, ShyiShiou Dept. of E.E., NKUT
  23. 23. shapethefuture  將Bolt物件拖到Prefabs資料夾做為預製物件  Speed = 20  刪除場景中的Bolt物件  執行測試,將Bolt預製物件拖曳到Hierarchy面板,檢視Game視窗, 子彈是否向前飛去 建立玩家戰機子彈 4/4 23 Wu, ShyiShiou Dept. of E.E., NKUT
  24. 24. shapethefuture  選單命令GameObject> Create Empty,更名為Shot Spawn  重置Transform  拖曳Shot Spawn成為Player子物件  調整Shot Spawn位置到戰機之前端,Position (X, Y, Z) = (0, 0, 1) 玩家戰機子彈發射控制 1/3 24 Wu, ShyiShiou Dept. of E.E., NKUT
  25. 25. shapethefuture  編輯Player物件之PlayerController程式腳本 public class PlayerController : MonoBehaviour { public float speed; public float tilt; public Player_Boundary boundary; public GameObject shot; public Transform shotSpawn; public float fireRate; private float nextFire; void Update () { if (Input.GetButton("Fire1") && Time.time > nextFire) { nextFire = Time.time + fireRate; Instantiate(shot, shotSpawn.position, shotSpawn.rotation); } } … } 玩家戰機子彈發射控制 2/3 25 Wu, ShyiShiou Dept. of E.E., NKUT
  26. 26. shapethefuture  拖曳Bolt預製物件到Player Controller之Shot欄  拖曳Shot Spawn物件到Player Controller之Shot Spawn欄  將Player Controller之Fire Rate欄值設為0.25  執行測試,按下滑鼠左鍵可發射子彈,但是…  檢視Hierarchy面板,子彈物件會不斷生成,但不會自動銷毀 玩家戰機子彈發射控制 3/3 26 Wu, ShyiShiou Dept. of E.E., NKUT
  27. 27. shapethefuture  選單命令GameObject> 3D Object> Cube,更名為Boundary  重置Transform屬性值  勾選Box Collider之Is Trigger  使Boundary物件置中顯示  Position (X, Y, Z) = (0, 0, 5) 參照Main Camera之Z座標設定  使Boundary物件涵蓋整個遊戲場景  Scale (X, Y, Z) = (15, 1, 20)  移除Mesh Renderer元件  移除Mesh Filter元件 設定玩家戰機子彈邊界 1/2 27 Wu, ShyiShiou Dept. of E.E., NKUT
  28. 28. shapethefuture  Boundary物件加上DestroyByBoundry程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class DestroyByBoundary : MonoBehaviour { void OnTriggerExit(Collider other) { Destroy(other.gameObject); } }  測試程式,檢視Hirarchy面板,子彈物件碰到Bundary後會自動銷 毀 設定玩家戰機子彈邊界 2/2 28 Wu, ShyiShiou Dept. of E.E., NKUT
  29. 29. shapethefuture  選單命令GameObject> Create Empty,更名為Asteroid  Position (X, Y, Z) = (0, 0, 8)  拖曳Models/prop_asteroid_01到Asteroid物件上  重置prop_asteroid_01物件Transform設定  在Asteroid物件加上Rigidbody元件  取消勾選Use Gravity  在Asteroid物件加上Capsule Collider元件  調整Radius及Height使其符合物件大小  Direction = Z-Axis  Radius = 0.486  Height = 1.524 建立隕石 1/4 29 Wu, ShyiShiou Dept. of E.E., NKUT
  30. 30. shapethefuture  Asteroid物件加上RandomRotator程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class RandomRotator : MonoBehaviour { public float tumble; void Start () { GetComponent<Rigidbody>().angularVelocity = Random.insideUnitSphere*tumble; } }  Asteroid物件之Tumble設定為5  執行測試,隕石會自主轉動,但是...  子彈會直接穿過隕石 建立隕石 2/4 30 Wu, ShyiShiou Dept. of E.E., NKUT
  31. 31. shapethefuture  Asteroid物件加上DestroyByContact程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class DestroyByContact : MonoBehaviour { void OnTriggerEnter(Collider other) { if (other.tag == "Boundary") { return; } Destroy(other.gameObject); Destroy(gameObject); } } 建立隕石 3/4 31 Wu, ShyiShiou Dept. of E.E., NKUT
  32. 32. shapethefuture  將Boundary物件之Tag設定為Boundary  執行測試  子彈碰到隕石時,子彈與隕石都會自動銷毀 建立隕石 4/4 32 Wu, ShyiShiou Dept. of E.E., NKUT
  33. 33. shapethefuture  編輯DestroyByContact程式腳本 public class DestroyByContact : MonoBehaviour { public GameObject explosion; void OnTriggerEnter(Collider other) { if (other.tag == "Boundary") { return; } Instantiate(explosion, transform.position, transform.rotation); Destroy(other.gameObject); Destroy(gameObject); } }  將PrefabsVFXExplosionsexplosion_asteroid預製物件拖曳到 explosion欄 爆破效果 1/4 33 Wu, ShyiShiou Dept. of E.E., NKUT
  34. 34. shapethefuture  執行測試,子彈碰到隕石時隕石會爆破,但是...  戰機撞到隕石時,隕石會爆破但戰機直接銷毀  將Player物件之Tag設定為Player  編輯DestroyByContact程式腳本 public class DestroyByContact : MonoBehaviour { public GameObject explosion; public GameObject playerExplosion; 爆破效果 2/4 34 Wu, ShyiShiou Dept. of E.E., NKUT
  35. 35. shapethefuture void OnTriggerEnter(Collider other) { ... Instantiate(explosion, transform.position, transform.rotation); if (other.tag == "Player") { Instantiate(playerExplosion, other.transform.position, other.transform.rotation); } Destroy(other.gameObject); Destroy(gameObject); } }  將PrefabsVFXExplosionsexplosion_player預製物件拖曳到 playerExplosion欄 爆破效果 3/4 35 Wu, ShyiShiou Dept. of E.E., NKUT
  36. 36. shapethefuture  執行測試,戰機撞到隕石時,隕石與戰機都會爆破  Asteroid物件加上Mover程式腳本  設定Speed為-5  執行測試,隕石會自動向下墜落  將Asteroid物件拖曳到Prefabs資料夾做成預製物件  刪除場景上的Asteroid物件 爆破效果 4/4 36 Wu, ShyiShiou Dept. of E.E., NKUT
  37. 37. shapethefuture  選單命令GameObject> Create Empty,更名為Game Controller  重置Transform  設定Tag為GameController 遊戲控制 1/3 37 Wu, ShyiShiou Dept. of E.E., NKUT
  38. 38. shapethefuture  Game Controller物件加上GameController程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameController : MonoBehaviour { public GameObject hazard; public Vector3 spawnValues; void Start () { SpawnWaves (); } void SpawnWaves () { Vector3 spawnPosition = new Vector3 ( Random.Range (-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z); Quaternion spawnRotation = Quaternion.identity; Instantiate (hazard, spawnPosition, spawnRotation); } } 遊戲控制 2/3 38 Wu, ShyiShiou Dept. of E.E., NKUT
  39. 39. shapethefuture  拖曳Asteroid預製物件到Hazard欄  設定SpawnValues(X, Y, Z) = (6, 0, 16)  執行測試,每次執行隕石會由不同位置墜落 遊戲控制 3/3 39 Wu, ShyiShiou Dept. of E.E., NKUT
  40. 40. shapethefuture  編輯GameController程式腳本 public class GameController : MonoBehaviour { public GameObject hazard; public Vector3 spawnValues; public int hazardCount; public float spawnWait; public float startWait; public float waveWait; void Start () { StartCoroutine (SpawnWaves ()); } 設定隕石群 1/4 40 Wu, ShyiShiou Dept. of E.E., NKUT
  41. 41. shapethefuture IEnumerator SpawnWaves () { yield return new WaitForSeconds (startWait); while (true) { for (int i = 0; i < hazardCount; i++) { Vector3 spawnPosition = new Vector3 ( Random.Range (-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z); Quaternion spawnRotation = Quaternion.identity; Instantiate (hazard, spawnPosition, spawnRotation); yield return new WaitForSeconds (spawnWait); } yield return new WaitForSeconds (waveWait); } } } 設定隕石群 2/4 41 Wu, ShyiShiou Dept. of E.E., NKUT
  42. 42. shapethefuture  執行測試,隕石會定時自動生成,但是...  擊破隕石時生成的爆破效果物件不會自動銷毀  建立DestroyByTime程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class DestroyByTime : MonoBehaviour { public float lifetime; void Start () { Destroy (gameObject, lifetime); } } 設定隕石群 3/4 42 Wu, ShyiShiou Dept. of E.E., NKUT
  43. 43. shapethefuture  在explosion_asteroid預製物件及explosion_player預製物件加入 DestroyByTime程式腳本  Lifetime設定為2  執行測試,隕石會定時自動生成,爆破特效物件也會在2秒後自動銷 毀 設定隕石群 4/4 43 Wu, ShyiShiou Dept. of E.E., NKUT
  44. 44. shapethefuture  在explosion_asteroid預製物件加上Audio Source元件  拖曳Audioexplosion_asteroid到explosion_asteroid預製物件之 AudioClip欄  勾選Play On Awake  在explosion_player預製物件加上Audio Source元件  拖曳Audioexplosion_player到explosion_player預製物件之 AudioClip欄  勾選Play On Awake  在Player物件加上Audio Source元件  拖曳Audioweapon_player到Player物件之AudioClip欄  取消勾選Play On Awake  Volume設為0.5 加入音效 1/2 44 Wu, ShyiShiou Dept. of E.E., NKUT
  45. 45. shapethefuture  編輯Player物件之Player Controller程式腳本 void Update () { if (Input.GetButton("Fire1") && Time.time > nextFire) { nextFire = Time.time + fireRate; Instantiate(shot, shotSpawn.position, shotSpawn.rotation); GetComponent<AudioSource>().Play(); } } 加入音效 2/2 45 Wu, ShyiShiou Dept. of E.E., NKUT
  46. 46. shapethefuture  在GameController物件加上Audio Source元件  拖曳Audiomusic_background到GameController物件之AudioClip欄  勾選Play On Awake  勾選Loop  Volume設為0.5 加入背景音樂 46 Wu, ShyiShiou Dept. of E.E., NKUT
  47. 47. shapethefuture  選單命令GameObject> Create Empty,更名為Score Text  重置Transform  Position (X, Y, Z) = (0, 1, 0)  加入GUI Text元件  Pixel Offset (X, Y) = (10, -10)  編輯GameController程式腳本 public class GameController : MonoBehaviour { ... public float waveWait; public GUIText scoreText; private int score; 計算及顯示分數 1/4 47 Wu, ShyiShiou Dept. of E.E., NKUT
  48. 48. shapethefuture void Start () { score = 0; UpdateScore (); StartCoroutine (SpawnWaves ()); } public void AddScore (int newScoreValue) { score += newScoreValue; UpdateScore (); } void UpdateScore () { scoreText.text = "Score: " + score; } ... } 計算及顯示分數 2/4 48 Wu, ShyiShiou Dept. of E.E., NKUT
  49. 49. shapethefuture  編輯DestroyByContact程式腳本 public class DestroyByContact : MonoBehaviour { public GameObject explosion; public GameObject playerExplosion; public int scoreValue; private GameObject gameController; void Start () { gameController = GameObject.Find ("Game Controller"); } void OnTriggerEnter(Collider other) { ... Destroy(other.gameObject); Destroy(gameObject); gameController.GetComponent<GameController> ().AddScore (scoreValue); } } 計算及顯示分數 3/4 49 Wu, ShyiShiou Dept. of E.E., NKUT
  50. 50. shapethefuture  將Asteroid預製物件之Score Value設定為10  拖曳Score Text物件到Game Controller物件之Score Text欄  執行測試,每擊破⼀個隕石增加10分 計算及顯示分數 4/4 50 Wu, ShyiShiou Dept. of E.E., NKUT
  51. 51. shapethefuture  選單命令GameObject> Create Empty,更名為Display Text  重置Transform  選單命令GameObject> Create Empty,更名為Restart Text  重置Transform  Position (X, Y, Z) = (1, 1, 0)  加入GUI Text元件  Anchor = Upper right  Alignment = Right  Pixel Offset (X, Y) = (-10, -10) 結束遊戲作業 1/7 51 Wu, ShyiShiou Dept. of E.E., NKUT
  52. 52. shapethefuture  選單命令GameObject> Create Empty,更名為Gameover Text  重置Transform  Position (X, Y, Z) = (0.5, 0.6, 0)  加入GUI Text元件  Anchor = Middle center  Alignment = Center  Pixel Offset (X, Y) = (0, 0)  將Score Text物件、Restart Text物件及Gameover Text物件拖曳到 Display Text下成為子物件 結束遊戲作業 2/7 52 Wu, ShyiShiou Dept. of E.E., NKUT
  53. 53. shapethefuture  編輯GameController程式腳本 using UnityEngine.SceneManagement; public class GameController : MonoBehaviour { ... private int score; public GUIText scoreText; public GUIText restartText; public GUIText gameOverText; private bool gameOver; private bool restart; void Start () { gameOver = false; restart = false; restartText.text = ""; gameOverText.text = ""; score = 0; ... } 結束遊戲作業 3/7 53 Wu, ShyiShiou Dept. of E.E., NKUT
  54. 54. shapethefuture IEnumerator SpawnWaves () { ... yield return new WaitForSeconds (waveWait); if (gameOver) { restartText.text = "Press 'R' for Restart"; restart = true; break; } } } void UpdateScore () { scoreText.text = "Score: " + score; } 結束遊戲作業 4/7 54 Wu, ShyiShiou Dept. of E.E., NKUT
  55. 55. shapethefuture void Update () { if (restart) { if (Input.GetKeyDown (KeyCode.R)) { SceneManager.LoadScene ("Main"); } } } public void GameOver () { gameOverText.text = "Game Over!"; gameOver = true; } } 結束遊戲作業 5/7 55 Wu, ShyiShiou Dept. of E.E., NKUT
  56. 56. shapethefuture  編輯DestroyByContact程式腳本 public class DestroyByContact : MonoBehaviour { ... void OnTriggerEnter(Collider other) { ... if (other.tag == "Player") { Instantiate(playerExplosion, other.transform.position, other.transform.rotation); gameController.GetComponent<GameController> ().GameOver(); } ... } } 結束遊戲作業 6/7 56 Wu, ShyiShiou Dept. of E.E., NKUT
  57. 57. shapethefuture  拖曳Restart Text物件到Game Controller物件之Restart Text欄  拖曳Gameover Text物件到Game Controller物件之Game Over Text欄  執行測試,玩家戰機會顯示Game over!,等下⼀波隕石群時顯示 Press 'R' for Restart,按下R鍵即可重玩 結束遊戲作業 7/7 57 Wu, ShyiShiou Dept. of E.E., NKUT

×