[UNITY] [Editor] เทคนิคการเขียน Editor ภาค 1 by

30
Jun
0

หลังจากใช้ UNITY กันมาซักพักแล้ว วันนี้เรามาเรียนรู้เรื่องที่ทำให้ชีวิต ง๊ายง่าย กันมากขึ้นดีกว่า
นั่นก็คือ การเขียน Editor นั่นเอง แต่เราไม่ได้จะมาเรียนการเขียน Editor กากๆ พื้นๆนะ
เราจะมาเรียนเรื่องที่มันลึกขึ้นอีกนิด เทพขึ้นอีกหน่อย ให้ชีวิต ดี๊ดี ขึ้นอีกเยอะๆกันดีกว่า

เรื่องแรกเลยก็คือ เรื่องของเส้นคั่น ในตัวเลือกต่างๆของ Editor เคยสงสัยกันไหมว่า เอะทำยังไง
ให้มันมีเส้นคั่นโผล่ออกมา แล้วมีหลายเส้นได้ไหม แล้วมีกฏการเขียนยังไงให้มันมีเส้นคั่นขึ้นมา คืออย่างงี้ครับ
คำตอบก็คือ คำสั่ง MenuItem() เนี่ยมันมี พารามิเตอร์ ที่ชื่อว่า priority อยู่ครับ และมันก็มีกฏเล็กๆน้อย
สำหรับ พารามิเตอร์ ตัวนี้นั่นก็คือ มันจะเรียงลำดับ Item ใน Menu จาก priority น้อยไปหามาก
และแบ่งกลุ่มให้หากมี Item ที่มี priority เดียวกัน และจะสร้างเส้นคั่นให้ ทุกๆ 50 priority ครับ
อ่านแล้ว งงๆ กันใช่ไหมครับ มาดูตัวอย่างกันดีกว่า

[MenuItem("Test/Menu1", false, 1)]
static void Menu1(){}
[MenuItem("Test/Menu2", false, 1)]
static void Menu2(){}
[MenuItem("Test/Menu3", false, 51)]
static void Menu3(){}

จะได้ผลลัพท์ดังรูป

1

และหากเราเพิ่ม code นี้ลงไปท้าย code เดิม

[MenuItem("Test/Menu4", false, 101)]
static void Menu4() { }

จะได้ผลลัพท์ดังรูป

2

เป็นยังไงบ้างครับสำหรับ trick เล็กๆน้อยๆ ของการเขียน Editor ไว้คราวหน้าจะมี trick อื่นๆมาฝากอีกครับ

มาใส่แสง lens flare เท่ๆในงานกัน by

30
Jun
0

1. เริ่มต้นเปิดรูปขึ้นมาก่อน
01

2. สร้างเลเยอร์ใหม่แล้วเทสีดำลงไป~ ใช้ถังสีปุ่มG
02

3. จากนั้นไปที่ Fiter >> Render >> Lens flare…
03

4. จะมีหน้าต่าง Lens flares ขึ้นมา ส่วนนี้สามารถปรับความสว่าง(1) หรือจุดตั้งแสงไฟได้ โดยลากไปทางทิศที่เราต้องการ
04

5. แล้วก็เลือกเลเยอร์ปรับเป็นโหมด Screen ตอนนี้เราก็ได้แสงแล้ว /ส่วนนี้อาจต้องขยับแสงไปในจุดที่ต้องการเพิ่มด้วย
05

6.เสร็จแล้วลองเปลี่ยนสีโดยไป Image >> Adjustments >> Hue / Saturation หรือ Ctlr+U
ค่า Hue เลือนเพื่อเลือกสี / ค่า Saturation เลือนเพื่อเข้มสุดกับอ่อนสุด
06

7.จากนั้นก็อบเลเยอร์แสงขึ้นมาอีก กดCtlr+J และกด Ctlr+t เพื่อบีบและยืดออกด้านข้าง
07

เป็นอันเสร็จ เท่านี้เราก็ได้แสงเท่ๆเหมือนในหนังแล้ว
08

การหลีกเลี่ยงการใช้ List แบบ Public ที่ต้องการกำหนดค่าในโค๊ด by

30
Jun
0

เป็นปัญหาที่พบล่าสุด โดยปกติแล้วถ้าเรามีตัวแปร Global ที่อยากให้ไฟล์อื่นเรียกใช้โดยที่ไม่ต้องการแก้ไขใน Inspector ของ Unity เราก็จะสร้างตัวแปร Public ไว้ให้ไฟล์อื่นๆเรียกใช้ โดยเราจะสั่ง  [HideInInspector] ไว้เพื่อไม่ให้มันโชว์ใน Inspector

แต่ทีนี้ตัวแปร List ที่เราสร้างไว้ เรายังสามารถแก้ไขในโค๊ดยังไงก็ได้ แต่ว่าถ้าเมื่อไหร่ตัว GameObject ของเราเข้าไปอยู่ใน Scene ที่ทำการ Save แล้ว ค่านั้นจะถูกแช่ไว้โดย Unity ทำให้ไม่ว่าเราจะแก้ไขในโค๊ดเท่าไรมันจะไม่เปลี่ยนตาม

List ตัวอย่างที่ถูกแก้ไขมาแล้ว

List ไม่โชว์จากคำสั่ง [HideInInspector]

ข้อมูลเมื่อรันจริง จะได้ค่าที่ถูกแช่ไว้โดย Unity ตอนที่เรา Save Scene

วิธีแก้ปัญหาก็มีได้ 2 วิธี
1. สร้างตัวแปรมาไว้ก่อนแล้ว Init ค่าตอน Awake() หรือ Start()
2. วิธีที่ควรจะเป็นคือ ใช้ตัวแปรเป็น  private
ex.
private List TestPublicList = new List()

แล้วถ้าต้องการให้ไฟล์อื่นมาเรียกใช้ก็สร้าง function public มาดึงข้อมูลตัวนี้อีกทีเท่านั้นเอง

ข้อมูลตอนรันหลังจากแก้เป็น private แล้ว

[Unity3D] เพิ่ม Game Center ลงเกมของเรา by

30
Jun
0

วิธี setup Game Center และใส่ Archivement ลงใน Game Center ตามนี้เลยครับ

Setup ที่ iTune Connect

1. เข้าไปที่ iTune Connect

2. เลือก app ของเรา (ถ้ายังไม่ใส่ app ลง iTune Connect จะทำ Game Center ไม่ได้เลย)

gamecenter1

3. กดเมนู Features ตามด้วย Game Center ดังรูปด้านบน

gamecenter2

4. กด Add Achievement ตามรูป (ถ้าอยากใส่ Leaderboard ด้วยก็ต้องใส่ข้อมูล Leaderboard ด้วยตรงนี้)

5. มีข้อมูลต้องกรอกดังนี้

  • Achievement Reference Name – ชื่อที่เอาไว้ดูในเว็บ iTune Connect เท่านั้น ไม่มีการเชื่อมต่อกับส่วนอื่น
  • Achievement ID – ชื่อที่ใช้อ้างอืงกับเกมของเรา เวลาเราสั่ง Achievement ไหนเสร็จก็จะต้องอ้าง string ตัวนี้ ใช้ได้เฉพาะตัวอักษรอังกฤษ, ตัวเลข, -, _ ห้ามมีตัวอักษรอื่นนอกเหนือจากนี้รวมถึง spacebar
  • Point Value – ถ้าทำสำเร็จจะได้กี่แต้ม ตรงนี้ต้องระวังหน่อยใส่ได้สูงสุด 100 และรวมทุก Achievement ห้ามเกิน 1000 คะแนนตรงนี้จริงๆ เกมเราไม่ได้เอาไปใช้อะไรหรอก แต่สำหรับผู้เล่น มันจะมีคะแนนที่สะสมมาจากเกมอื่นที่ไม่ใช่ของเรามารวมด้วย และจัดอันดับของทั้ง Game Center รวมกันหลายๆ เกมอีกที ในส่วนนี้สมมติตั้งว่าได้ 10 คะแนน แต่คนเล่น progress ไป 50% แล้ว แต่ยังไม่สำเร็จก็จะยังไม่ได้แต้ม (ไม่ใช่ว่าได้ 5 แต้มไปก่อนแล้ว) ต้องทำ progress ครบ 100 ถึงจะได้ 10 คะแนน
  • Hidden – แสดงให้ผู้เล่นรู้ไหมว่ามี Achievement นี้อยู่
  • Achievable More Than Once – ทำซ้ำได้มากกว่า 1 ครั้งไหม

6. ข้อมูลส่วน Add Language มีดังนี้

  • Language – ภาษา
  • Title – หัวข้อที่จะแสดงเวลาผู้เล่นทำสำเร็จครบ 100% แล้วมี status แสดงว่าสำเร็จแล้ว (Hero, Great Warrior ชื่ออะไรที่อยากให้คนเล่นเห็นก็ว่าไป)
  • Pre-earned Description – ก่อนจะได้ Achievement ให้แสดงข้อความข้างใต้ Title อย่างไร อาจใส่เป็นคำใบ้ว่าต้องทำอย่างไรถึงจะได้ Achievement นี้ก็ได้
  • Earned Description – หลังได้ Achievement ให้แสดงข้อความข้างใต้ Title ว่าอย่างไร
  • Image – รูปที่แสดง ขนาด 512×512 px หรือ 1024×1024 px โดยจะถูกตัดขอบเป็นวงกลมให้เสมอ

7. หลังกด Save แล้วก็ Add Achievement อื่นๆ วนซ้ำไปเรื่อยๆ จนกว่าจะครบตามต้องการ

8. เข้าเมนู App Store

gamecenter3

9. กดเพิ่ม version เกมอันใหม่แล้วเลือก Enable Game Center ตามรูปซะ และ Select All Achievement หรือ Leaderboard ที่สร้างมาให้ครบเพื่อรับการ Review

10. Submit App ตัวใหม่ที่ implement Game Center แล้วเรียบร้อยขึ้น Store

Unity Coding

สำหรับด้าน Coding ของ Unity ไม่จำเป็นต้องติดตั้ง Library ใดๆ เพิ่ม สามารถใช้งานได้เลยโดยมีเพียงเล็กน้อยดังนี้

using UnityEngine;
using UnityEngine.SocialPlatforms;
public class GameCenter : MonoBehaviour {
public static GameCenter instance;
public bool IsLogin = false;
void Awake() {
instance = this;
}
// Use this for initialization
void Start () {
// Authenticate and register a ProcessAuthentication callback
// This call needs to be made before we can proceed to other calls in the Social API
#if UNITY_IOS
GameCenterPlatform.ShowDefaultAchievementCompletionBanner(true);
Social.localUser.Authenticate(ProcessAuthentication);
#endif
}
// This function gets called when Authenticate completes
// Note that if the operation is successful, Social.localUser will contain data from the server.
void ProcessAuthentication(bool success)
{
if (success)
{
IsLogin = true;
}
}
}

Copy ไปสร้างไฟล์ใหม่ชื่อ Game Center แล้วลาก Script ไปแปะที่ Scene แรกสุดได้เลย ในส่วนนี้คือคำสั่ง Login user เข้า Game Center สำหรับคำสั่งที่จะส่ง progress ไปยัง Game Center ใช้แค่ดังนี้

Social.ReportProgress(achievementId, 100f, delegate(bool result) {
if (result)
Debug.Log("Successfully reported achievement progress");
});

ง่ายดายมากๆ เพียงส่ง string ตัวแปร achievementId ไปให้ตรงกับที่สร้างไว้บน iTune Connect และ parameter ตัวที่สองคือ progress ซึ่งจะมีได้ตั้งแต่ 0-100 เท่านั้น (ไม่ว่า Point Value จะเป็นเท่าไรก็ตาม) ถ้าทำสำเร็จจะมี popup เลื่อนมาแสดงว่าสำเร็จแล้ว

ในส่วนของการแสดง Game Center Interface ภายในเกมของเราทำได้โดยสั่ง

Social.ShowAchievementsUI() หรือ Social.ShowLeaderboardUI() ตามแต่ต้องการว่าจะแสดงอะไร

หากต้องการ Reset Achievement ที่ทำไปแล้วทั้งหมดทำได้โดยสั่งดังนี้

GameCenterPlatform.ResetAllAchievements( (resetResult) => {
Debug.Log( (resetResult) ? "Reset done." : "Reset failed." );
});

การทดสอบ

IMG_0152

สำหรับ iOS ตั้งแต่เวอร์ชั่น 9 เป็นต้นไป ไม่ต้องทำอะไรก็สามารถทดสอบได้เลย แต่หากเป็น iOS เวอร์ชั่นตำกว่า 9 จะต้องเข้าหน้า Setting -> Game Center เพื่อปรับ Sandbox ให้เป็น Enable ก่อนดังภาพ และต้อง Sign Out account game center เพื่อใช้งาน Account Sandbox ตอนเข้าเกม (ถ้ายังไม่มีต้องสร้างที่ iTune Connect เข้าเมนู Users and Roles -> Sandbox Testers) เมื่อเตรียมการเรียบร้อยก็เข้าเกมเราไปทดสอบ ลองดูเลย ถ้าเจอ popup Welcome to Game Center โผล่มาก็แสดงว่าสำเร็จ ถ้าไม่มีก็ต้องตรวจสอบขั้นตอนใหม่ว่ามีอะไรผิดพลาดบ้าง ขอให้โชคดีครับทุกท่าน :)

วิธีสร้างบัญชีไฟล์โดยเรียงตามวันที่ by

30
Jun
0

วิธีนี้จะเป็นการสร้างประยุกต์ใช้ function ภายใน file helper ของ codeigniter ซึ่งรุ่นใหม่ๆ ผมไม่แน่ใจว่ามีวิธีสำเร็จรูปไว้แล้วหรือยัง
ที่แน่ๆ รุ่นที่กำลังใช้งานอยู่มันยังไม่มีรูปแบบสำเร็จรูป เลยต้องสร้าง function สำหรับใช้งานเอง เนื่องจาก function เตรียมไว้ใช้กับการเรียงไฟล์ที่อัพโหลดขึ้นมาบน server เรื่องเวลาที่ซ้ำกันจริงตัดออกไปนะครับ
function file_list_by_date(&$a_ret, $path, $reverse = TRUE) {
$buffer = array();
foreach (get_filenames($path) as $each) {
$buffer[get_file_info("{$path}{$each}", 'date')['date']] = $each;
}
$a_key = array_keys($buffer);
if ($reverse) {
rsort($a_key);
} else {
sort($a_key);
}
foreach ($a_key as $each) {
$a_ret[] = $buffer[$each];
}
}

อธิบายทีละบรรทัดได้ดังนี้

  1. บรรทัดแรกประกาศตัวแปล array ไว้รอรับ
  2. ใช้ foreach เพื่อวนรายชื่อไฟล์ใส่ตัวแปร
  3. นำวันที่ ในที่นี้จะเป็น timestamp มาเป็น key ของ array
  4. ใช้ function array_keys เพื่อนำ key ทั้งหมดมาใส่ไว้ในตัวแปร
  5. เลือกการ sort โดย sort ปกติ จะน้อยไปหามาก ส่วน rsort จะเป็นมากไปหาน้อย
  6. ถ้าสังเกตจากการประกาศ function $a_ret เราส่งเข้ามาเป็น pointer สำหรับ push ข้อมูลเข้าไปต่อท้ายได้เลย
  7. ทำการ push ข้อมูลตามลำดับด้วย key ที่ผ่านการจัดเรียงมาแล้ว
กู้เงิน | เศรษฐกิจพอเพียง | สินเชื่อบุคคล | สมัครบัตรกดเงินสด | สินเชื่อ | เงินกู้ด่วน | ยืมเงินทรูมูฟ | เงินด่วนนอกระบบ