[UNITY][Particle] Particle ที่เล่น Particle เดิมซ้ำๆ แต่ Random จุดเกิด by tosawat
Jun0
เคยไหม ที่อยากให้ Particle เกิดแบบ Random จุดเกิด แต่มีปริมาณตามที่เรากำหนดไว้ตลอด ยกตัวอย่างเช่น ทำ Particle สำหรับ ท่าโจมตีของ Unit ตัวหนึ่งซึ่งเป็นมือปืน เวลาใช้ท่าไม้ตาย Unit ตัวนี้จะโจมตี 6 ครั้งแบบยิงกราด อะไรประมาณนั้น วันนี้จะมานำเสนอ Code ที่จะทำให้ชีวิตง่ายขึ้นครับ
ขั้นแรก เอา Code ไปก่อนเลยครับ
using UnityEngine;
using System;
using System.Collections;
public class ParticleRandomize : MonoBehaviour
{
[Serializable]
public class Range
{
public float Min;
public float Max;
}
public GameObject Particle;
public int Count;
public float Time;
public Range X;
public Range Y;
public float RandomDistancePercent = 100f;
void Start()
{
float TimePerOnce = Time / Count;
Vector2 Distance = new Vector2(Mathf.Abs(X.Min - X.Max) * RandomDistancePercent / 100 / 2, Mathf.Abs(Y.Min - Y.Max) * RandomDistancePercent / 100 / 2);
Vector2 lastPosition = Vector3.zero;
for (int i = 0; i 100)
{
break;
}
} while ((lastPosition.x + Distance.x > x && x > lastPosition.x - Distance.x) && (lastPosition.y + Distance.y > y && y > lastPosition.y - Distance.y));
lastPosition = new Vector2(x, y);
_particle.transform.parent = transform;
_particle.transform.localPosition = new Vector2(x, y);
});
}
}
}
ต่อมาเราก็ AddComponent ให้ Particle ที่เราอยากให้มันเล่นซ้ำๆนะครับ ตัวอย่าง
จะอธิบาย Config ใน Inspector ทีละตัวนะครับ
Particle: คือ Particle ที่เราอยากให้เล่นซ้ำๆ ครับ ให้ลาก prefab particle มาใส่ในช่องนี้นะครับ
Count: คือจำนวนครั้งที่อยากให้ Particle เล่นครับ
Time: คือระยะเวลาหน่วงระหว่าง Particle ครับ
X.min: คือระยะน้อยที่สุดในแกน x ที่จะ Random จุดเกิด
X.max: คือระยะมากที่สุดในแกน x ที่จะ Random จุดเกิด
Y.min: คือระยะน้อยที่สุดในแกน y ที่จะ Random จุดเกิด
Y.max: คือระยะมากที่สุดในแกน y ที่จะ Random จุดเกิด
Random Distance Percent: คือ ระยะ(เป็นเปอร์เซนของระยะ min, max ที่ตั้งไว้) ที่จะไม่ให้ Particle เกิดใกล้กันครับ
จริงๆแล้ว Script random จุดเกิดของ GameObject ต่างๆนั้นมันไม่ได้ยากอะไรหรอกครับ แต่ข้อดีของ Script นี้ก็คือ สามารถกำหนดได้ว่า ไม่ให้ GameObject ที่ เกิดติดๆกัน อยู่ใกล้กันมากกว่ากี่เปอร์เซนของพื้นที่ ที่เรากำหนดไว้ข้างต้นครับ
[Lua] ฟังก์ชั่นรีเทิร์นหลายค่าและฟังก์ชั่นแบบรับค่าไม่ต้องครบตาม Arguments by Ziah
Mar0
เนื่องจากเพิ่งมาเขียน Lua เดือนนี้ ก็มีโค้ดที่เกี่ยวกับฟังก์ชั่นที่ช่วยให้การทำงานสะดวกสบายขึ้นมานำเสนอฮะ
อันแรก ฟังก์ชั่นในลัวร์รีเทิร์น 2 ค่า อันนี้ไม่แน่ใจว่าภาษาไหนทำได้บ้างแต่จากที่เคยเขียนมาเพิ่งเจอในภาษานี้ครับ อเมซซิ่งมากๆ
local a,b = 1,2
function test2Params(x,y)
return x+1,y+2 --รีเทิร์นสองพารามิเตอร์
end
print('local a,b:'..a..','..b)
a,b = test2Params(a,b)
print('test2Params(a,b):'..a..','..b)
ถัดมาอันนี้เป็นวิธีอ้อม เนื่องจากเราไม่สามารถกำหนด Default Parameter ลงไปในการประกาศฟังก์ชั่นตรงๆ แบบ PHP/AS3 ได้ และยังไม่สามารถ Override ฟังก์ชั่นแบบ C# ได้ แต่สามารถรับไม่ครบมาเช็คค่าด้านในแบบนี้ดื้อๆได้เลยครับ
function testOptionalParams(x,y) -- รับสองตัวแปร
if (y == nil ) then -- ถ้าส่งมาแค่ x (y ไม่ส่งมา) ก็ให้ y เป็นสักค่า
y = 0;
end
return x+y
end
a = testOptionalParams(a)
print('testOptionalParams(a):'..a)
a = testOptionalParams(a,b)
print('testOptionalParams(a,b):'..a)
จากโค้ดทั้งสองชุดด้านบน รันแล้วจะได้ผลลัพธ์ดังนี้ครับ
local a,b:1,2
test2Params(a,b):2,4
testOptionalParams(a):2
testOptionalParams(a,b):6
[Flex] วิธีการทำให้เกมของเราสามารถเปลี่ยนฟอนท์แบบตอน Run Time ได้ by Ziah
Feb0
โดยปกติแล้วในเกมจะใช้ฟอนท์หลักๆ 1 ฟอนท์ แต่ที่นี้ปัญหามันเกิดเมื่อเราทำ Localize ซึ่งฟอนท์ของเรานั้นไม่ได้ครอบคลุมตัวหนังสือของทุกภาษาจึงทำให้ต้องมีการเปลี่ยนฟอนท์ขณะรันไทม์ขึ้นครับ (เพราะต้องรอรับข้อมูลก่อนว่าผู้เล่นเลือกภาษาใดมา)
• ส่วนแรกโดนปกติแล้ว Flex เราจะเตรียม css มาไว้ให้ในไฟล์หลักอยู่แล้ว แต่ถ้ายังไม่มีก็สร้างขึ้นตามนี้ครับ
• จากนั้นก็ใส่ฟอนท์ที่จำเป็นตามปกติ แล้วตามด้วย css class ทิ้งไว้ดังนี้
@namespace mx "library://ns.adobe.com/flex/mx";
@namespace s "library://ns.adobe.com/flex/spark";
@font-face
{
fontFamily: "2005_iannnnnCPU";
src: url("/assets/fonts/2005_iannnnnCPU.ttf");
embedAsCFF: true;
}
@font-face
{
fontFamily: "Tahoma";
fontWeight: bold;
src: url("/assets/fonts/tahomabd.ttf");
embedAsCFF: true;
}
@font-face
{
fontFamily: "Tahoma";
src: url("/assets/fonts/TAHOMA.TTF");
embedAsCFF: true;
}
@font-face
{
fontFamily: "Impact";
src: url("/assets/fonts/impact_0.ttf");
embedAsCFF: true;
}
@font-face
{
fontFamily: "AgencyGP";
src: url("/assets/fonts/dY_AgencyGP.ttf");
embedAsCFF: true;
}
@font-face
{
fontFamily: "-Layiji TaMaiTine1";
src: url("/assets/fonts/layiji_TarMineTine1.ttf");
embedAsCFF: true;
}
@font-face
{
fontFamily: "Arial";
src: url("/assets/fonts/arial.ttf");
embedAsCFF: true;
}
@font-face
{
fontFamily: "Arial";
fontWeight: bold;
src: url("/assets/fonts/arialbd.ttf");
embedAsCFF: true;
}
.langFontStyle{}
.fontSize12{}
.fontSize18{}
.fontSize20{}
.fontSize21{}
.fontSize22{}
.fontSize24{}
.fontSize25{}
.fontSize27{}
.fontSize28{}
.fontSize30{}
.fontSize31{}
.fontSize32{}
.fontSize33{}
.fontSize34{}
.fontSize35{}
.fontSize36{}
.fontSize38{}
.fontSize39{}
.fontSize40{}
.fontSize42{}
.fontSize44{}
.fontSize45{}
.fontSize46{}
.fontSize48{}
.fontSize49{}
.fontSize50{}
.fontSize52{}
.fontSize54{}
.fontSize56{}
.fontSize60{}
.fontSize64{}
.fontSize72{}
.fontSize100{}
.fontSize120{}
.fontSize128{}
ซึ่งที่เขียนเตรียมไว้เยอะๆเพราะเราจะต้องเขียนเผื่อขนาดฟอนท์ที่จะใช้ทั้งหมดในโปรเจ็คนั่นเอง (หรือจะมาเขียนเพิ่มเองทุกครั้งที่มีไซส์ใหม่ก็ได้)
• จากนั้นในไฟล์ Application หลัก โดยปกติจะมี <fx:Style source=”Main.css” /> แต่ถ้ายังไม่มีก็ให้ใส่ก่อน <fx:Script> ครับ
• ทีนี้ก็มาถึงส่วนตั้งค่าละ
if(lang=="en"||lang=="th"){ //ถ้าเป็นภาษาอังกฤษหรือไทย
styleManager.getStyleDeclaration(".langFontStyle").setStyle("fontFamily","2005_iannnnnCPU"); //ใช้ฟอนท์นี้
for(i=0;i<200;i++){
if(styleManager.getStyleDeclaration(".fontSize"+i)!=null)
styleManager.getStyleDeclaration(".fontSize"+i).setStyle("fontSize",i); //รันแก้คลาสชื่อนี้ทั้งหมดให้เป็นขนาดที่ใส่เลขไว้
}
}
else{ //ถ้าเป็นภาษาอื่นๆใช้ฟอนท์นี้และเซ็ทค่าต่างๆ
styleManager.getStyleDeclaration(".langFontStyle").setStyle("fontFamily","Arial");
styleManager.getStyleDeclaration(".langFontStyle").setStyle("fontWeight","bold");
for(i=0;i<200;i++){
if(styleManager.getStyleDeclaration(".fontSize"+i)!=null)
styleManager.getStyleDeclaration(".fontSize"+i).setStyle("fontSize",i/2);
}
}
• จากนั้นในแท็กต่างๆของเราที่ปกติใช้ property fontFamily=”xxx” fontSize=”yyy” ก็มาใช้เป็น styleName=”langFontStyle fontSize44″ เท่านี้แหละครับ
วิธีการทำให้จอขยาย/ย่อให้ตรงกับ Aspect Ratio ที่เราต้องการ by Ziah
Jan0
หลังจากเมื่อสองเดือนก่อนได้เขียนบล็อคเรื่อง 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 ใหม่เข้าไปเลย
}
เท่านี้ก็เรียบร้อยแล้วครับ!!
Unity Debugging(2) by tosawat
Jan0
เคยไหม เวลาที่อยากให้ 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 นี้หายไปเพราะอะไร นั่นเองงง