THE REPUBLIQUE REMASTERED ใน Unity 5 โปรเจคสำหรับศึกษาที่น่าสนใจสุด ๆ

Asset Store ของ Unity ถือเป็นแหล่งขุมทรัพย์ของนักพัฒนาอย่างเราเลยก็ว่าได้ เพราะไม่เพียงมีโมเดลให้เราโหลดใช้งานเพียงอย่างเดียว แต่เรายังสามารถหาโปรเจคต่าง ๆ ในนั้น ไว้ดูเป็นตัวอย่างได้อีกด้วย วันนี้ผู้เขียนจึงขอยกโปรเจคโปรเจคหนึ่ง มาให้ดูกัน !!!

image00

ในโปรเจคนี้เราสามารถนำฉากต่าง ๆ มาเช็คและทดลองดูได้ไม่ยาก พร้อมกับมีหลายฉากที่น่าสนใจอีกด้วย ซึ่งในแต่ละฉากเราก็จะได้เห็นการใช้งานของ Reflection Probes, Enlighten, Animation รูปแบบใหม่ และระบบ Audio พร้อมกับอื่น ๆ อีกมากมาย

image04

ENLIGHTEN 

  • Republique’s Atrium คือฉากแรกที่เราจะนำมาศึกษากันนะครับ โดยส่วนใหญ่แล้วการสร้างฉาก ฉากหนึ่งจะเกิดจากการนำแนวคิดต่าง ๆ ที่มีนำมาทดลองโดยระบบใหม่ ๆ เพื่อจะนำมันมาศึกษาวิธีการใช้งานจริง ๆ ของมัน ซึ่ง The Atrium is Episode 1 จึงถือเป็นผลงานชิ้นดี ที่แสดงให้เห็นคุณภาพสูงสุดของระบบใน Unity 5 ทั้งนี้ในระบบใหม่ที่น่าสนใจคือ Enlighten ที่ถูกปรับปรุงใหม่ โดยเฉพาะ แสงที่ถูกสร้างจากด้านบนของซีน

image07

  •  Emissive materials ถือเป็นสิ่งใหม่ล่าสุดของ Unity 5 ที่เราจะเห็นได้ว่ามันจะไปเพิ่ม Emission intensity  ของ Fluorescent Light material ซึ่งจะทำให้ฉากเราสดใสมากขึ้นจากแสง bounce

image06

  •  เรายังสามารถเห็นได้จากตัวอย่างของ material ได้ว่า emission value นั้นถือเป็นระบบใหม่ และมันยังง่ายสำหรับการทำอนิเมท โดยการเพิ่ม Animation track เข้าไปควบคุมท่าก็เสร็จเรียบร้อยแล้ว

image10

image09

  •  ทั้งนี้เราจะเห็นได้ว่า การเพิ่ม Indirect Intensity ใน lighting tab นั้น ฉากที่เป็นแบบไดนามิกจะถูกแก้ไข และกลายเป็น brighter

image05-800x421

  •  Reflection probes สามารถช่วยให้ metals ตอบสนองได้มากขึ้น เช่น real-world counterparts ที่จะเห็นถึงการสะท้อนของสภาพแวดล้อมสิ่งต่าง ๆ หากเราเช็ค  Box projections ได้อย่างถูกต้อง เราจะเห็น reflect ของสิ่งแวดล้อมรอบตัวเป็นรูปทรงสี่เหลี่ยม

image12

  •  ส่วนภาพข้างล่างจะเห็นได้ว่า ถ้าหากเราใช้เสา และเซ็ต surface ของ material  เป็น metal จากนั้นเพิ่ม reflectivity เราจะได้การสะท้อนที่ถูกต้อง
  •  ในกรณีเดียวกัน หากเราลด smoothness จากการสะท้อนจะกลายเป็นขรุขระ หรือพร่ามัว

 UNITY 5 AUDIO

  •  Unity 5  Audio Mixer ช่วยให้เราสามารถจัดหมวดหมู่เสียง และระบุ buses ออกไป ให้มีความยืดหยุ่นมากขึ้น โดยการนำเสียงไป routed  และ mixed รวมไปถึงการนำ effects  มาใช้งาน ซึ่งใน  ‘Ambience’ จะแบ่งออกเป็น 2 แบบ คือ 2D และ 3D โดยปกติแล้ว  3D ambient audio จะถูก routed ไปยังกลุ่ม 3D ย่อย ๆ เพื่อให้เสียงที่เกี่ยวข้องใน 3D bus fire ออกมาเหมาะสม ภายในแต่ละกลุ่ม volume และ pitch สามารถปรับแต่งได้ ซึ่ง audio filters สามารถนำไปใช้ และปรับแต่งได้ โดยเราสามารถ solo individual  หรือ mute  individual หรือกลุ่มทั้งหมดในตอน Run อยู่ก็ได้ โดยเราแค่กดที่ ‘Edit ใน Play Mode’ ทางด้านขวาบน corner ของ Audio Mixer ในขณะที่โปรเจคกำลังทำงานอยู่ ตัวอย่างเช่นเราเพิ่ม ‘SFX Reverb’ ไปที่กลุ่ม Footsteps เพื่อให้เราสามารถปรับแต่ง และเล่นวนในขณะที่โปรเจคกำลังทำงานอยู่นั่นเอง
  •  เมื่อเราพอใจกับวิธีการ mix  เราสามารถเซฟมันเก็บไว้ได้นะครับ โดยการเซฟ Snapshot ของเราใน Audio Mixer settings ซึ่งนี่จะทำให้เราสร้างเสียงที่มีเอกลักษณ์ และเหมาะสมได้มากที่สุด

MECANIM

  • เมื่อเราพร้อมที่จะเล่นเกมแล้ว เราสามารถกดเล่นได้ โดยเราสามารถควบคุมการเคลื่อนที่ต่าง ๆ ของกล้องได้จากปุ่ม WASD หากเรากดคลิกซ้ายยังสามารถคลื่อนที่ Hope ไปยังรอบ ๆ สิ่งแวดล้อมได้ ซึ่งในนี้ได้มีการรวมการอนิเมทต่าง ๆ ไว้แล้ว แต่เนื่องจากมีการเปิดเผย API ของ Mecanim เราจึงสามารถสร้างเครื่องมือในการสร้าง และแก้ไข Mecanim asset ได้
  •  ในโปรเจคมีปุ่มสร้างใหม่ที่ใช้สำหรับ Animator โดยเราเรียกใช้ได้ผ่านการคลิกที่ Hope  ส่วนข้างล่างนี้เป็นสคริปต์ในการสร้าง similar Animator ในโฟลเดอร์โปรเจค

[MenuItem ("Hope/Create Controller")]

 

static void CreateController () {

 

<i>

 

var controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath ("Assets/HopeScriptCtrl.controller");

 

<i>

 

controller.AddParameter("Walk", AnimatorControllerParameterType.Bool);

 

controller.AddParameter("TurnLeft", AnimatorControllerParameterType.Bool);

 

controller.AddParameter("TurnRight", AnimatorControllerParameterType.Bool);

 

controller.AddParameter("HalfTurn", AnimatorControllerParameterType.Bool);

 

<i>

 

var rootStateMachine = controller.layers[0].stateMachine;

 

var stateMachineStand = rootStateMachine.AddStateMachine("Stand");

 

<i>

 

var stateIdle = stateMachineStand.AddState("Idle");

 

var stateTurnLeft = stateMachineStand.AddState("TurnLeft");

 

var stateTurnRight = stateMachineStand.AddState("TurnRight");

 

var stateHalfTurn = stateMachineStand.AddState("HalfTurn");

 

var stateWalk = stateMachineStand.AddState("Walk");

 

stateIdle.motion = AssetDatabase.LoadAssetAtPath("Assets/Animations/Hope Animations/StandingIdleLooking.fbx", typeof(AnimationClip)) as Motion;

 

stateTurnLeft.motion = AssetDatabase.LoadAssetAtPath("Assets/Animations/Hope Animations/MoveStand90_L.fbx", typeof(AnimationClip)) as Motion;

 

stateTurnRight.motion = AssetDatabase.LoadAssetAtPath("Assets/Animations/Hope Animations/MoveStand90_R.fbx", typeof(AnimationClip)) as Motion;

 

stateHalfTurn.motion = AssetDatabase.LoadAssetAtPath("Assets/Animations/Hope Animations/MoveStand180.fbx", typeof(AnimationClip)) as Motion;

 

stateWalk.motion = AssetDatabase.LoadAssetAtPath("Assets/Animations/Hope Animations/MoveWalk_F.fbx", typeof(AnimationClip)) as Motion;

 

<i>

 

var idle2TurnLeft = stateIdle.AddTransition (stateTurnLeft);

 

var turnLeft2Idle = stateTurnLeft.AddTransition (stateIdle);

 

idle2TurnLeft.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "TurnLeft");

 

idle2TurnLeft.duration = 0.025f;

 

turnLeft2Idle.hasExitTime = true;

 

turnLeft2Idle.exitTime = 0.85f;

 

turnLeft2Idle.duration = 0.15f;

 

var idle2TurnRight = stateIdle.AddTransition (stateTurnRight);

 

var turnRight2Idle = stateTurnRight.AddTransition (stateIdle);

 

idle2TurnRight.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "TurnRight");

 

idle2TurnRight.duration = 0.025f;

 

turnRight2Idle.hasExitTime = true;

 

turnRight2Idle.exitTime = 0.85f;

 

turnRight2Idle.duration = 0.15f;

 

var idle2HalfTurn = stateIdle.AddTransition (stateHalfTurn);

 

var halfTurn2Idle = stateHalfTurn.AddTransition (stateIdle);

 

idle2HalfTurn.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "HalfTurn");

 

idle2HalfTurn.duration = 0.025f;

 

halfTurn2Idle.hasExitTime = true;

 

halfTurn2Idle.exitTime = 0.85f;

 

halfTurn2Idle.duration = 0.15f;

 

var idle2Walk = stateIdle.AddTransition (stateWalk);

 

var walk2Idle = stateWalk.AddTransition (stateIdle);

 

idle2Walk.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "Walk");

 

idle2Walk.duration = 0.025f;

 

walk2Idle.AddCondition(UnityEditor.Animations.AnimatorConditionMode.IfNot, 0, "Walk");

 

walk2Idle.duration = 0.25f;

 

}

และนี่คือทั้งหมดแล้วสำหรับการนำโปรเจคนี้มาศึกษาดูระบบต่าง ๆ ผู้เขียนคิดว่าเพื่อน ๆ หลายคนคงได้ประโยชน์ แรงบันดาลใจ และความรู้ไปไม่มากก็น้อยนะครับ (^^)


ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *