วิธีการทำให้จอขยาย/ย่อให้ตรงกับ Aspect Ratio ที่เราต้องการ by

31
Jan
0

หลังจากเมื่อสองเดือนก่อนได้เขียนบล็อคเรื่อง Anchor แบบที่ทำให้ชิดขอบจอไปแล้ว [ที่นี่ http://blog.levelup.in.th/2014/11/30/ngui-anchor-tutorial/] ตอนนี้ถ้าเราอยากให้ Aspect Ratio มันคงที่ล่ะ? บางส่วนในเกมของเราอยากให้ถูกจำกัดอยู่ในขนาด Aspect Ratio เดิม อาจจะมีเหตุผลทางส่วนต่างๆในจอไม่เหมาะกับการถูกขยายได้ หรือภาพหลังฉากจำกัดไว้ที่ขนาดนี้ การ Lock Aspect Ratio จึงจำเป็น ซึ่งถ้าเราไม่ใส่โค้ดใดๆ ตัวเกมมันก็จะอยู่ตรงกลางจอ ถ้าใช้จอที่ขนาดใหญ่กว่าก็จะมีขอบสีดำที่ไม่มีอะไรทุกด้าน วันนี้เลยจะมาบอกวิธีทำให้ตัวเกมขยายมาชิดขอบจอจนเหลือขอบดำแค่ ซ้ายขวา หรือไม่ก็ บนล่างเท่านั้น ซึ่งมีทางเดียวคือเราต้องปรับ Anchor ในตอน Runtime ครับ

[โค้ดตัวอย่าง]

• ให้เราสร้างสคริปใหม่ขึ้นมาแล้วแปะไว้กับ UIWidget ตัวนอกสุดที่เราจะทำการ Lock Aspect Ratio

• ในสคริปจะมี Class ที่มีไส้ในแบบนี้ครับ

public float fixedAspectRatio; //เป็น Aspect Ratio ที่เราต้องการ ถูกเซ็ทมาจาก Inspector
void Update(){
float aspect = 1f * Screen.width / Screen.height; //Aspect Ratio ปัจจุบันของหน้าจอ
if (aspect > fixedAspectRatio ) //ถ้าเรโชปัจจุบันมากกว่าที่เราต้องการ (3:4 > 2:3) สั่งให้ UIWidget ของเรายึดตามแนวตั้งเป็นหลัก
this.gameObject.GetComponent().keepAspectRatio = UIWidget.AspectRatioSource.BasedOnHeight;
else //หรือถ้าเรโชปัจจุบันมากกว่าที่เราต้องการ (9:16 < 2:3) สั่งให้ UIWidget ของเรายึดตามแนวนอนเป็นหลัก
this.gameObject.GetComponent().keepAspectRatio = UIWidget.AspectRatioSource.BasedOnWidth;
this.gameObject.GetComponent().aspectRatio = fixedAspectRatio; //แล้วก็จัดการใส่ Aspect Ratio ใหม่เข้าไปเลย
}

เท่านี้ก็เรียบร้อยแล้วครับ!!

จอขนาด 2:3 ปกติ

จอขนาด 9:16 (ส่วนสูงเกิน 2:3)

จอขนาด 3:4 (กว้างเกินขนาด 2:3)

Unity Debugging(2) by

31
Jan
0

เคยไหม เวลาที่อยากให้ Object บางตัว โผล่ออกมา หรือหายไป แต่มันดันไม่เป็นไปอย่างที่เราอยากให้เป็น บางทีมันดันมี Object ที่อยากให้หายไปตอนนี้แต่มันดันโผล่มา หรือไม่ยอมหายไป เอ้า ทีนี้จะทำยังไงล่ะ!! วันนี้เลยจะมาบอกวิธีการที่ใช้หาว่า Object ตัวนั้นๆ มันหายไป หรือโผล่มาตอนไหนบ้าง แล้วถูกสั่งให้หายไปหรือ โผล่มาโดย Code บรรทัดไหนเป็นคนสั่ง

1. ก่อนอื่นเลยให้สร้าง Script แล้วใส่ Method ตามนี้

void OnEnable(){
Debug.LogError("OnEnable");
}
void OnDisable(){
Debug.LogError("OnDisable");
}

2. Add Script ที่เราสร้างใหม่นี้ไปใส่กับ Object ที่ต้องการจะดูว่ามันหายหรือโผล่มาตอนไหน
3. คราวนี้เมื่อ Object ตัวนี้ หายไป หรือโผล่มา ก็จะมี ข้อความ OnEnable หรือ OnDisable พ่นออกมา พร้อมกับ Call Stack ด้วย ทำให้เรารู้ได้ทันทีว่า Object นี้หายไปเพราะอะไร นั่นเองงง

สัดส่วนพื้นฐานในการวาดภาพใบหน้าคน by

31
Jan
0

sample10a

สัดส่วนของใบหน้าคนมักแบ่งออกเป็น 3 ส่วนครึ่งในแนวตั้ง โดยมีวงกลมกินพื้นที่ 2 ส่วนครึ่งดังภาพที่ 1

 

 

 

sample10b

เส้นสัดส่วนจะเป็นตัวกำหนดตำแหน่งอวัยวะต่างๆบนใบหน้าคร่าวๆ โดยจากบน ครึ่งส่วนด้านบนสุดจะเป็นส่วนตำแหน่งของเส้นผม
ส่วนถัดมาเป็นส่วนของหน้าผาก โดยมีเส้นที่สองเป็นตำแหน่งของโหนกคิ้ว
ส่วนต่อมาเป็นส่วนของคิ้วถึงปลายจมูกรวมถึงใบหู และส่วนสุดท้ายจะเป็นส่วนของจมูกถึงปลายคาง ดังภาพที่ 2

 

 

sample10c

ภาพที่ 3 หุ่นคนเหลี่ยม หน้าตรง ใช้เพื่อศึกษามิติและโครงสร้างพื้นฐานคร่าวๆของใบหน้า
โดยระยะห่างของดวงตาทั้งสองข้าง และความกว้างของปีกจมูกจะเท่ากับความยาวของดวงตา 1 ข้างพอดี

 

sample10d

การศึกษาสัดส่วนใบหน้าเพื่อความเข้าใจในการวาดใบหน้าคนต่อไป (ภาพที่ 4)

การจัดองค์ประกอบภาพให้ภาพน่าสนใจ ด้วยจุดตัด 9 ช่อง by

31
Jan
0

สวัสดีครับ เคยมั้ย? ตัวละครในงานที่วาดออกมามันยืนไม่ดีตำแหน่งในภาพไม่สวย ไม่ดีเอาซะเลย ถ้าเคยเป็นมาลองใช้เทคนิต “การจัดองค์ประกอบภาพ ด้วยจุดตัด 9 ช่อง ” กัน
ซึงเทคนิตก็ใช้งานง่ายมากๆแถมทำให้งานดูดีขึ้นแน่นอน เป็นไงลองทำตามดูกัน

อย่างแรกวาดตัวละครหรืออะไรขึ้นมาก็ได้ สมมตืรูปนี้เป็นรูปที่วาดลงไปกลางหน้ากระดาษตามปกติ แต่รู้สึกมั้ยว่าค่อนข้างอึดอัดไม่ดีเอาซะเลย ไหนนั้นลองเอาทำจุดตัด 9 ช่องดู
1
แบ่งภาพเป๋นตาราง 9 ช่องแบบนี้ แล้วลองเอามาทำภาพดูสิ (โอ้ชั่งมั่วซะแหลือเกิน นั้นถ้าลองใช้เทคนิตจุดตัด 9 ช่องเพิ่มดูละ ^^)
2

อ่าลองขยับไปทางขวาตามจุดตัด 9 ช่อง ดีขึ้นเยอะเลย
3

ทำภาพเทียบกันหน่อย
5

หวังว่าจะมีประโยชน์กับทุกท่านไม่มากก็น้อยนะครับ ^^

[Unity3D] Asset Bundle คืออะไร? by

31
Jan
1

Screenshot_2015-01-31-13-35-02

ปกติเราเคยเล่นเกม แล้วเห็นเกมอื่นเขาสั่ง Download Content มาเพิ่มตอนเข้าเกมครั้งแรกไหม? แล้วทำไมเขาถึงไม่รวมเข้าไปให้ดาวน์โหลดตั้งแต่อยู่ใน Store เลยล่ะ? ทำไมต้องแยกให้ผู้เล่นรอโหลดสองรอบ? จริงๆ แล้วส่วนที่ Download เพิ่มก็คือ Asset Bundle นี่เองซึ่งเป็น Content เพิ่มเติมของเกมเช่น ตัวละครใหม่ ไอเท็มใหม่ ด่านใหม่ สำหรับสาเหตุที่จำเป็นต้องใช้ asset bundle คือ

  1. Google Play มีการจำกัดขนาดไฟล์ apk ที่จะให้เอาขึ้น Store ได้ 50 MB และส่วนที่เหลือต้องแยก expansion file ส่วน ios จะจำกัดที่ตัว .app ไม่เกิน 60MB ซึ่งจะทำให้ flow การทำงานไม่เหมือน ios และ android ไม่เหมือนกัน การใช้ Asset Bundle จะมาช่วยจัดการความต่างตรงนี้ได้
  2. เมื่อเรา update เกมเพื่อแก้ไข bug แต่ content รูปภาพต่างๆ ยังเหมือนเดิม ผู้เล่นจะต้อง download ใหม่แค่เพียงตัว app ไม่ต้อง Download content ใหม่ทั้งหมด เพียงเพื่อแก้ไขข้อผิดพลาดเล็กๆ น้อยๆ จาก 500 MB(app รวม content model 3 มิติ รูปภาพ) ลดเหลือ 50 MB (ตัว app อย่างเดียว) จะเป็นจุดต่างอย่างมาก
  3. สามารถเพิ่ม content ใหม่ๆ ได้โดยไม่ต้องเอาขึ้น app store/google play store ซึ่งปกติเวลา approve ของ app store จะเฉลี่ยที่ 7 วัน ทำให้ไม่ต้องรอเวลาตรงนี้ถึงจะปล่อย patch update เกมด่านใหม่ๆ ได้ เพิ่มความสะดวกเป็นอย่างมาก

จะเห็นได้ว่ามีประโยชน์มากจริงๆ ดังนั้นเรามาดูกันว่าจะสร้าง Asset Bundle มาใช้งานได้อย่างไร


// C# Example
// Builds an asset bundle from the selected objects in the project view.
// Once compiled go to "Menu" -> "Assets" and select one of the choices
// to build the Asset Bundle
using UnityEngine;
using UnityEditor;
public class ExportAssetBundles {
   [MenuItem("Assets/Build AssetBundle From Selection - Track dependencies")]
   static void ExportResource () {
      // Bring up save panel
      string path = EditorUtility.SaveFilePanel ("Save Resource", "", "New Resource", "unity3d");
      if (path.Length != 0) {
         // Build the resource file from the active selection.
         Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
         BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path,
                      BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, BuildAssetBundleOptions.CollectDependencies , BuildTarget.Android);
         Selection.objects = selection;
      }
   }
   [MenuItem("Assets/Build AssetBundle From Selection - No dependency tracking")]
   static void ExportResourceNoTrack () {
      // Bring up save panel
      string path = EditorUtility.SaveFilePanel ("Save Resource", "", "New Resource", "unity3d");
      if (path.Length != 0) {
         // Build the resource file from the active selection.
         BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, path, BuildAssetBundleOptions.CollectDependencies , BuildTarget.Android);
      }
   }
}

ให้เรา Copy Code ข้างบนไปเซพไฟล์ใหม่ชื่อ AssetBundleCreator.cs (หรือชื่ออื่นก็ได้) แล้วสร้าง Folder ใหม่ใน Folder Assets ใน project ของเราชื่อว่า Editor นำไฟล์ AssetBundleCreator.cs ไปใส่ด้านใน จากนั้น ให้คลิกเลือก Resource รูปภาพที่จะนำมาสร้างใน tab project ด้านล่าง ต่อด้วยคลิกที่เมนู Asset จะเห็นดังภาพ

AssetBundleMenuOptions

1. Build AssetBundle From Selection – Track dependencies คือสร้าง asset bundle โดยพ่วงเอาทุกอย่างที่เลือกแถมมาด้วย เช่นเลือกรูปภาพ 1 รูปแล้วเลือกเมนูนี้จะได้ Texture2D และ Sprite มาทั้งคู่ใน bundle (แน่นอนว่าขนาดไฟล์ที่ได้จะใหญ่กว่า)
2. Build AssetBundle From Selection – No dependency tracking คือสร้าง asset bundle โดยสร้างแค่เฉพาะของที่ใส่ลงไปใน bundle เช่นเลือกรูปภาพ 1 รูปแล้วเลือกเมนูนี้จะได้ Texture2D อย่างเดียวมาใน bundle

สิ่งที่ต้องระวังในการใช้งาน asset bundle คือตอนสร้างเราจะต้องเลือกสร้างบน platform ใด platform หนึ่งเช่น สั่งสร้าง asset bundle for android ก็จะใช้ได้กับ android เท่านั้น ใช้กับ ios ไม่ได้ ดังนั้นหากต้องการ update content เกมทั้งสอง os จะต้องสร้าง bundle มา 2 ไฟล์แยกกัน โดยแก้ไขส่วนของ BuildTarget.Android เป็น BuildTarget.iPhone ตามแต่ os

สำหรับวิธีเรียกไปใช้งานก็ตาม code ด้านล่าง

using UnityEngine;
using System.Collections;
public class BundleLoader : MonoBehaviour{
    public string url;
    public int version;
    public IEnumerator LoadBundle(){
        using(WWW www = WWW.LoadFromCacheOrDownload(url, version){
            yield return www;
            AssetBundle assetBundle = www.assetBundle;
            GameObject gameObject = assetBundle.mainAsset as GameObject;
            Instantiate(gameObject );
            assetBundle.Unload(false);
        }
    }
    void Start(){
        StartCoroutine(LoadBundle());
    }
}

ขอให้สนุกกับการทำเกมนะครับ :)

กู้เงิน | เศรษฐกิจพอเพียง | สินเชื่อบุคคล | สมัครบัตรกดเงินสด | สินเชื่อ | เงินกู้ด่วน | ยืมเงินทรูมูฟ | เงินด่วนนอกระบบ