ต้นไม้พฤติกรรมสำหรับโครงการ Unity3D เขียนด้วยวิธีการที่ขับเคลื่อนด้วยรหัสเพื่อเพิ่มความสามารถในการบำรุงรักษาในโครงการขนาดใหญ่ด้วยรูปแบบการสร้าง แรงบันดาลใจจากต้นไม้พฤติกรรมที่คล่องแคล่ว
คุณสมบัติ
สนับสนุน
เข้าร่วมชุมชน Discord หากคุณมีคำถามหรือต้องการความช่วยเหลือ
ดูคุณสมบัติที่จะเกิดขึ้นและความคืบหน้าการพัฒนาบนกระดาน Trello
เมื่อสร้างต้นไม้คุณจะต้องเก็บไว้ในตัวแปรเพื่อแคชข้อมูลที่จำเป็นทั้งหมดอย่างถูกต้อง
using UnityEngine ;
using CleverCrow . Fluid . BTs . Tasks ;
using CleverCrow . Fluid . BTs . Trees ;
public class MyCustomAi : MonoBehaviour {
[ SerializeField ]
private BehaviorTree _tree ;
private void Awake ( ) {
_tree = new BehaviorTreeBuilder ( gameObject )
. Sequence ( )
. Condition ( " Custom Condition " , ( ) => {
return true ;
} )
. Do ( " Custom Action " , ( ) => {
return TaskStatus . Success ;
} )
. End ( )
. Build ( ) ;
}
private void Update ( ) {
// Update our tree every frame
_tree . Tick ( ) ;
}
}
ขึ้นอยู่กับสิ่งที่คุณกลับมาสำหรับสถานะงานที่แตกต่างกันจะเกิดขึ้น
tree.Tick()
จะรีสตาร์ทต้นไม้หากไม่มีโหนดอื่นให้รันtree.Tick()
เรียกว่า การอ้างอิงตัวชี้ถูกติดตามโดยต้นไม้และสามารถล้างได้ก็ต่อเมื่อเรียกว่า tree.Reset()
ตราบใดที่ตัวแปรจัดเก็บต้นไม้ของคุณถูกตั้งค่าเป็น public
หรือมีแอตทริบิวต์ SerializeField
คุณจะสามารถพิมพ์การสร้างภาพต้นไม้ของคุณในขณะที่เกมกำลังทำงานในตัวแก้ไข โปรดทราบว่าคุณไม่สามารถดูต้นไม้ได้ในขณะที่เกมไม่ทำงาน เนื่องจากต้นไม้จะต้องถูกสร้างขึ้นเพื่อให้เห็นภาพ
คุณสามารถเพิ่มรหัสใหม่ให้กับต้นไม้พฤติกรรมของคุณได้อย่างปลอดภัยด้วยหลายบรรทัด ช่วยให้คุณสามารถปรับแต่ง BTS ในขณะที่รองรับการอัพเกรดเวอร์ชันในอนาคต
using UnityEngine ;
using CleverCrow . Fluid . BTs . Tasks ;
using CleverCrow . Fluid . BTs . Tasks . Actions ;
using CleverCrow . Fluid . BTs . Trees ;
public class CustomAction : ActionBase {
protected override TaskStatus OnUpdate ( ) {
Debug . Log ( Owner . name ) ;
return TaskStatus . Success ;
}
}
public static class BehaviorTreeBuilderExtensions {
public static BehaviorTreeBuilder CustomAction ( this BehaviorTreeBuilder builder , string name = " My Action " ) {
return builder . AddNode ( new CustomAction { Name = name } ) ;
}
}
public class ExampleUsage : MonoBehaviour {
public void Awake ( ) {
var bt = new BehaviorTreeBuilder ( gameObject )
. Sequence ( )
. CustomAction ( )
. End ( ) ;
}
}
แผนผังพฤติกรรมของไหลถูกใช้ผ่านตัวจัดการแพ็คเกจของ Unity ในการใช้งานคุณจะต้องเพิ่มบรรทัดต่อไปนี้ลงในไฟล์ Packages/manifest.json
ไฟล์ของคุณ หลังจากนั้นคุณจะสามารถควบคุมทรีพฤติกรรมของเหลวของฟลุดได้ที่คุณใช้จากหน้าต่างแพ็คเกจตัวจัดการใน Unity สิ่งนี้จะต้องทำเพื่อให้ตัวแก้ไข Unity ของคุณสามารถเชื่อมต่อกับรีจิสทรีแพ็คเกจของ NPM ได้
{
"scopedRegistries" : [
{
"name" : " NPM " ,
"url" : " https://registry.npmjs.org " ,
"scopes" : [
" com.fluid "
]
}
],
"dependencies" : {
"com.fluid.behavior-tree" : " 2.2.0 "
}
}
คลังเก็บของรุ่นเฉพาะและบันทึกย่อที่มีอยู่ในหน้าเผยแพร่
คุณอาจต้องการดูโครงการตัวอย่างการจับธงสำหรับตัวอย่างการทำงานว่าแผนผังพฤติกรรมของเหลวสามารถใช้ในโครงการของคุณได้อย่างไร มันแสดงให้เห็นถึงการใช้งานตามเวลาจริงกับหน่วยที่พยายามจับธงในขณะที่คว้าพลังอัพเพื่อลองและได้รับตำแหน่งสูงกว่า
คุณอาจต้องการดูโครงการตัวอย่างการจับธงสำหรับตัวอย่างการทำงานว่าแผนผังพฤติกรรมของเหลวสามารถใช้ในโครงการของคุณได้อย่างไร มันแสดงให้เห็นถึงการใช้งานตามเวลาจริงกับหน่วยที่พยายามจับธงในขณะที่คว้าพลังอัพเพื่อลองและได้รับตำแหน่งสูงกว่า
แผนผังพฤติกรรมของเหลวมาพร้อมกับห้องสมุดที่แข็งแกร่งของการกระทำก่อนทำเงื่อนไขคอมโพสิตและโหนดอื่น ๆ เพื่อช่วยเร่งกระบวนการพัฒนาของคุณ
คุณสามารถสร้างการกระทำทั่วไปได้ทันที หากคุณพบว่าตัวเองใช้การกระทำแบบเดียวกันกับคุณอีกครั้งคุณอาจต้องการดูส่วนเกี่ยวกับการเขียนการกระทำที่กำหนดเองของคุณเอง
. Sequence ( )
. Do ( " Custom Action " , ( ) => {
return TaskStatus . Success ;
} )
. End ( )
ข้ามจำนวนของเห็บบนต้นไม้พฤติกรรม
. Sequence ( )
// Wait for 1 tick on the tree before continuing
. Wait ( 1 )
. Do ( MyAction )
. End ( )
รอจนกว่าจำนวนวินาทีที่ผ่านไปจะหมดอายุใน deltaTime
. Sequence ( )
. WaitTime ( 2.5f )
. Do ( MyAction )
. End ( )
คุณสามารถสร้างเงื่อนไขทั่วไปได้ทันที หากคุณพบว่าตัวเองใช้การกระทำแบบเดียวกันกับตัวเองอีกครั้งคุณอาจต้องการดูส่วนเกี่ยวกับการเขียนเงื่อนไขที่กำหนดเองของคุณเอง
. Sequence ( )
. Condition ( " Custom Condtion " , ( ) => {
return true ;
} )
. Do ( MyAction )
. End ( )
ประเมินโหนดแบบสุ่มว่าเป็นจริงหรือเท็จตามโอกาสที่ผ่านมา
. Sequence ( )
// 50% chance this will return success
. RandomChance ( 1 , 2 )
. Do ( MyAction )
. End ( )
รันโหนดเด็กแต่ละโหนดตามลำดับและคาดว่าสถานะ ความสำเร็จ จะทำเครื่องหมายโหนดถัดไป หาก ความล้มเหลว ถูกส่งคืนลำดับจะหยุดเรียกใช้โหนดลูกและส่งคืน ความล้มเหลว ไปยังผู้ปกครอง
หมายเหตุ เป็นสิ่งสำคัญที่ทุกคอมโพสิตจะตามด้วยคำสั่ง .End()
สิ่งนี้ทำให้แน่ใจว่าโหนดของคุณซ้อนกันอย่างถูกต้องเมื่อสร้างต้นไม้
. Sequence ( )
. Do ( ( ) => { return TaskStatus . Success ; } )
. Do ( ( ) => { return TaskStatus . Success ; } )
// All tasks after this will not run and the sequence will exit
. Do ( ( ) => { return TaskStatus . Failure ; } )
. Do ( ( ) => { return TaskStatus . Success ; } )
. End ( )
รันโหนดเด็กแต่ละโหนดจนกว่า ความสำเร็จ จะถูกส่งคืน
. Selector ( )
// Runs but fails
. Do ( ( ) => { return TaskStatus . Failure ; } )
// Will stop here since the node returns success
. Do ( ( ) => { return TaskStatus . Success ; } )
// Does not run
. Do ( ( ) => { return TaskStatus . Success ; } )
. End ( )
สุ่มเลือกโหนดเด็กที่มีอัลกอริทึมการสับเปลี่ยน ดูจนกว่า Success
จะถูกส่งคืนหรือทุกโหนดล้มเหลว สับทุกครั้งที่ต้นไม้เริ่มต้นใช้งานในตอนแรก
. SelectorRandom ( )
. Do ( ( ) => { return TaskStatus . Failure ; } )
. Do ( ( ) => { return TaskStatus . Success ; } )
. Do ( ( ) => { return TaskStatus . Failure ; } )
. End ( )
รันโหนดเด็กทั้งหมดในเวลาเดียวกันจนกว่าพวกเขาจะกลับมาประสบ ความสำเร็จ ออกและหยุดโหนดที่ทำงานทั้งหมดหากมีการส่งคืน ความล้มเหลว
. Parallel ( )
// Both of these tasks will run every frame
. Do ( ( ) => { return TaskStatus . Continue ; } )
. Do ( ( ) => { return TaskStatus . Continue ; } )
. End ( )
นักตกแต่งเป็นองค์ประกอบหลักที่ห่อโหนดใด ๆ เพื่อเปลี่ยนค่าส่งคืน (หรือดำเนินการตรรกะพิเศษ) พวกเขามีพลังอย่างมากและเป็นคำชมที่ยอดเยี่ยมเกี่ยวกับการกระทำเงื่อนไขและคอมโพสิต
คุณสามารถห่อโหนดใดก็ได้ด้วยรหัสมัณฑนากรที่กำหนดเองของคุณเอง สิ่งนี้ช่วยให้คุณสามารถปรับแต่งฟังก์ชันการใช้งานได้อีกครั้ง
หมายเหตุ : คุณต้องโทร Update()
บนโหนดลูกหรือจะไม่ยิง นอกจากนี้ยังต้องตามคำสั่งของมัณฑนากรทุกคนตามด้วยคำสั่ง .End()
มิฉะนั้นต้นไม้จะสร้างไม่ถูกต้อง
. Sequence ( )
. Decorator ( " Return Success " , child => {
child . Update ( ) ;
return TaskStatus . Success ;
} )
. Do ( ( ) => { return TaskStatus . Failure ; } )
. End ( )
. Do ( ( ) => { return TaskStatus . Success ; } )
. End ( )
ย้อนกลับสถานะที่ส่งคืนของโหนดเด็กหากเป็น TaskStatus.Success
หรือ TaskStatus.Failure
ไม่เปลี่ยน TaskStatus.Continue
. Sequence ( )
. Inverter ( )
. Do ( ( ) => { return TaskStatus . Success ; } )
. End ( )
. End ( )
ส่งคืน TaskStatus.Success
ถ้าเด็กส่งคืน TaskStatus.Failure
ไม่เปลี่ยน TaskStatus.Continue
. Sequence ( )
. ReturnSuccess ( )
. Do ( ( ) => { return TaskStatus . Failure ; } )
. End ( )
. End ( )
ส่งคืน TaskStatus.Failure
ถ้าเด็กส่งคืน TaskStatus.Success
ไม่เปลี่ยน TaskStatus.Continue
. Sequence ( )
. ReturnFailure ( )
. Do ( ( ) => { return TaskStatus . Success ; } )
. End ( )
. End ( )
ส่งคืน TaskStatus.Continue
โดยไม่คำนึงถึงสถานะที่เด็กกลับมา มัณฑนากรนี้ (และงานที่สืบเชื้อสายมาทั้งหมด) สามารถถูกขัดจังหวะได้โดยการโทรหา BehaviorTree.Reset()
. Sequence ( )
. RepeatForever ( )
. Do ( ( ) => { return TaskStatus . Success ; } )
. End ( )
. End ( )
ส่งคืน TaskStatus.Failure
ถ้าเด็กส่งคืน TaskStatus.Failure
มิฉะนั้นจะส่งคืน TaskStatus.Continue
. Sequence ( )
. RepeatUntilFailure ( )
. Do ( ( ) => { return TaskStatus . Success ; } )
. End ( )
. End ( )
ส่งคืน TaskStatus.Success
ถ้าเด็กส่งคืน TaskStatus.Success
มิฉะนั้นจะส่งคืน TaskStatus.Continue
. Sequence ( )
. RepeatUntilSuccess ( )
. Do ( ( ) => { return TaskStatus . Success ; } )
. End ( )
. End ( )
ต้นไม้สามารถรวมกับรหัสได้เพียงไม่กี่บรรทัด สิ่งนี้ช่วยให้คุณสร้างต้นไม้พฤติกรรมที่ฉีดได้ซึ่งรวมโหนดที่แตกต่างกันสำหรับฟังก์ชั่นที่ซับซ้อนเช่นการค้นหาหรือโจมตี
ได้รับการเตือนว่าต้นไม้ที่มีการประกบต้องการต้นไม้ที่สร้างขึ้นใหม่สำหรับการฉีดเนื่องจากโหนดจะถูกคัดลอกลึกลงไปใน .Build()
using CleverCrow . Fluid . BTs . Trees ;
using CleverCrow . Fluid . BTs . Tasks ;
using UnityEngine ;
public class MyCustomAi : MonoBehaviour {
private BehaviorTree _tree ;
private void Awake ( ) {
var injectTree = new BehaviorTreeBuilder ( gameObject )
. Sequence ( )
. Do ( " Custom Action " , ( ) => {
return TaskStatus . Success ;
} )
. End ( ) ;
_tree = new BehaviorTreeBuilder ( gameObject )
. Sequence ( )
. Splice ( injectTree . Build ( ) )
. Do ( " Custom Action " , ( ) => {
return TaskStatus . Success ;
} )
. End ( )
. Build ( ) ;
}
private void Update ( ) {
// Update our tree every frame
_tree . Tick ( ) ;
}
}
สิ่งที่ทำให้ต้นไม้พฤติกรรมของเหลวมีประสิทธิภาพมากคือความสามารถในการเขียนโหนดของคุณเองและเพิ่มลงในตัวสร้างโดยไม่ต้องแก้ไขแหล่งใด ๆ คุณสามารถสร้างแพ็คเกจ Unity ที่เพิ่มฟังก์ชั่นตัวสร้างใหม่ ตัวอย่างเช่นเราสามารถเขียนวิธีการสร้างต้นไม้ใหม่เช่นนี้ซึ่งตั้งค่าเป้าหมายของระบบ AI ของคุณด้วยรหัสเพียงไม่กี่บรรทัด
var tree = new BehaviorTreeBuilder ( gameObject )
. Sequence ( )
. AgentDestination ( " Find Enemy " , target )
. Do ( ( ) => {
// Activate chase enemy code
return TaskStatus . Success ;
} )
. End ( )
. Build ( ) ;
ควรใช้เวลาประมาณ 3 นาทีในการสร้างการกระทำที่กำหนดเองครั้งแรกของคุณและนำไปใช้ ก่อนสร้างการกระทำใหม่
using CleverCrow . Fluid . BTs . Tasks ;
using CleverCrow . Fluid . BTs . Tasks . Actions ;
using UnityEngine ;
using UnityEngine . AI ;
public class AgentDestination : ActionBase {
private NavMeshAgent _agent ;
public Transform target ;
protected override void OnInit ( ) {
_agent = Owner . GetComponent < NavMeshAgent > ( ) ;
}
protected override TaskStatus OnUpdate ( ) {
_agent . SetDestination ( target . position ) ;
return TaskStatus . Success ;
}
}
ต่อไปเราจำเป็นต้องขยายสคริปต์ BehaviorTreeBuilder
ด้วยการดำเนินการตัวแทนใหม่ของเรา สำหรับข้อมูลเพิ่มเติมเกี่ยวกับส่วนขยายคลาส C# ดูเอกสารอย่างเป็นทางการ
using CleverCrow . Fluid . BTs . Trees ;
public static class BehaviorTreeBuilderExtensions {
public static BehaviorTreeBuilder AgentDestination ( this BehaviorTreeBuilder builder , string name , Transform target ) {
return builder . AddNode ( new AgentDestination {
Name = name ,
target = target ,
} ) ;
}
}
และคุณทำเสร็จแล้ว! ตอนนี้คุณได้สร้างการกระทำที่กำหนดเองและการสร้างต้นไม้พฤติกรรมที่ขยายได้ซึ่งได้รับการพิสูจน์ในอนาคตสำหรับเวอร์ชันใหม่ ตัวอย่างต่อไปนี้จะเหมือนกันมากขึ้น แต่แต่ละประเภทครอบคลุมโหนดที่แตกต่างกัน
คุณสามารถสร้างการกระทำที่กำหนดเองของคุณเองด้วยเทมเพลตต่อไปนี้ สิ่งนี้มีประโยชน์สำหรับการรวมรหัสที่คุณใช้อยู่ตลอดเวลา
using UnityEngine ;
using CleverCrow . Fluid . BTs . Tasks ;
using CleverCrow . Fluid . BTs . Tasks . Actions ;
public class CustomAction : ActionBase {
// Triggers only the first time this node is run (great for caching data)
protected override void OnInit ( ) {
}
// Triggers every time this node starts running. Does not trigger if TaskStatus.Continue was last returned by this node
protected override void OnStart ( ) {
}
// Triggers every time `Tick()` is called on the tree and this node is run
protected override TaskStatus OnUpdate ( ) {
// Points to the GameObject of whoever owns the behavior tree
Debug . Log ( Owner . name ) ;
return TaskStatus . Success ;
}
// Triggers whenever this node exits after running
protected override void OnExit ( ) {
}
}
เพิ่มโหนดใหม่ของคุณไปยังส่วนขยาย
using CleverCrow . Fluid . BTs . Trees ;
public static class BehaviorTreeBuilderExtensions {
public static BehaviorTreeBuilder CustomAction ( this BehaviorTreeBuilder builder , string name = " My Action " ) {
return builder . AddNode ( new CustomAction {
Name = name ,
} ) ;
}
}
เงื่อนไขที่กำหนดเองสามารถเพิ่มได้ด้วยเทมเพลตตัวอย่างต่อไปนี้ คุณจะต้องใช้สิ่งเหล่านี้เพื่อตรวจสอบเช่นสายตาหาก AI สามารถย้ายไปยังตำแหน่งและงานอื่น ๆ ที่ต้องตรวจสอบที่ซับซ้อน
using UnityEngine ;
using CleverCrow . Fluid . BTs . Tasks ;
public class CustomCondition : ConditionBase {
// Triggers only the first time this node is run (great for caching data)
protected override void OnInit ( ) {
}
// Triggers every time this node starts running. Does not trigger if TaskStatus.Continue was last returned by this node
protected override void OnStart ( ) {
}
// Triggers every time `Tick()` is called on the tree and this node is run
protected override bool OnUpdate ( ) {
// Points to the GameObject of whoever owns the behavior tree
Debug . Log ( Owner . name ) ;
return true ;
}
// Triggers whenever this node exits after running
protected override void OnExit ( ) {
}
}
เพิ่มเงื่อนไขใหม่ให้กับตัวสร้างต้นไม้พฤติกรรมของคุณด้วยตัวอย่างต่อไปนี้
using CleverCrow . Fluid . BTs . Trees ;
public static class BehaviorTreeBuilderExtensions {
public static BehaviorTreeBuilder CustomCondition ( this BehaviorTreeBuilder builder , string name = " My Condition " ) {
return builder . AddNode ( new CustomCondition {
Name = name ,
} ) ;
}
}
ต้นไม้พฤติกรรมของเหลวไม่ได้ จำกัด อยู่เพียงแค่การกระทำและเงื่อนไขที่กำหนดเอง คุณสามารถสร้างประเภทคอมโพสิตใหม่ด้วย API ที่ค่อนข้างง่าย นี่คือตัวอย่างของลำดับพื้นฐาน
using CleverCrow . Fluid . BTs . TaskParents . Composites ;
using CleverCrow . Fluid . BTs . Tasks ;
public class CustomSequence : CompositeBase {
protected override TaskStatus OnUpdate ( ) {
for ( var i = ChildIndex ; i < Children . Count ; i ++ ) {
var child = Children [ ChildIndex ] ;
var status = child . Update ( ) ;
if ( status != TaskStatus . Success ) {
return status ;
}
ChildIndex ++ ;
}
return TaskStatus . Success ;
}
}
การเพิ่มคอมโพสิตแบบกำหนดเองลงในแผนผังพฤติกรรมของคุณนั้นง่ายพอ ๆ กับการเพิ่มการกระทำ ใช้รหัสหนึ่งบรรทัด
using CleverCrow . Fluid . BTs . Trees ;
public static class BehaviorTreeBuilderExtensions {
public static BehaviorTreeBuilder CustomSequence ( this BehaviorTreeBuilder builder , string name = " My Sequence " ) {
return builder . ParentTask < CustomSequence > ( name ) ;
}
}
นักตกแต่งยังสามารถเขียนแบบกำหนดเองเพื่อลดรหัสซ้ำ ๆ
using CleverCrow . Fluid . BTs . Decorators ;
using CleverCrow . Fluid . BTs . Tasks ;
public class CustomInverter : DecoratorBase {
protected override TaskStatus OnUpdate ( ) {
if ( Child == null ) {
return TaskStatus . Success ;
}
var childStatus = Child . Update ( ) ;
var status = childStatus ;
switch ( childStatus ) {
case TaskStatus . Success :
status = TaskStatus . Failure ;
break ;
case TaskStatus . Failure :
status = TaskStatus . Success ;
break ;
}
return status ;
}
}
การใช้งานตกแต่งมีความคล้ายคลึงกับคอมโพสิต หากคุณต้องการตั้งค่าอาร์กิวเมนต์ในคอมโพสิตคุณจะต้องมีการยกเค้าที่ Method BehaviorTreeBuilder.AddNodeWithPointer()
using CleverCrow . Fluid . BTs . Trees ;
public static class BehaviorTreeBuilderExtensions {
public static BehaviorTreeBuilder CustomInverter ( this BehaviorTreeBuilder builder , string name = " My Inverter " ) {
// See BehaviorTreeBuilder.AddNodeWithPointer() if you need to set custom composite data from arguments
return builder . ParentTask < CustomInverter > ( name ) ;
}
}
หากคุณใช้ตัวจัดรูปแบบอัตโนมัติมันอาจจะจัดการการจัดรูปแบบรหัสของคุณด้วยไวยากรณ์ของตัวสร้าง เพื่อหลีกเลี่ยงสิ่งนี้คุณสามารถปิดการจัดรูปแบบได้เช่นเดียวกับ Jetbrains Rider หากคุณต้องการ IDE ที่เฉพาะเจาะจงมันไม่ควรยากที่จะ Google การจัดรูปแบบที่เฉพาะเจาะจงในการปิดการใช้งานความคิดเห็นที่คุณต้องการ
// @formatter:off
_tree = new BehaviorTreeBuilder ( gameObject )
. Sequence ( )
. Condition ( " Custom Condition " , ( ) => {
return true ;
} )
. Do ( " Custom Action " , ( ) => {
return TaskStatus . Success ;
} )
. End ( )
. Build ( ) ;
// @formatter:on
ในการเข้าถึงการสร้าง develop
ทุกคืนที่เป็นมิตรกับแพ็คเกจที่เป็นมิตรคุณจะต้องแก้ไข Packages/manifest.json
ของคุณด้วยตนเอง json
{
"dependencies" : {
"com.fluid.behavior-tree" : " https://github.com/ashblue/fluid-behavior-tree.git#nightly "
}
}
โปรดทราบว่าในการสร้างใหม่ทุกคืนคุณต้องลบบรรทัดนี้และข้อมูลล็อคที่เกี่ยวข้องใด ๆ ในรายการให้สร้างความสามัคคีใหม่จากนั้นเพิ่มกลับ ในฐานะที่เป็นเอกภาพล็อคแฮชสำหรับ GIT เป็นแพ็คเกจ
หากคุณต้องการเรียกใช้เพื่อเรียกใช้สภาพแวดล้อมการพัฒนาคุณจะต้องติดตั้ง node.js จากนั้นเรียกใช้สิ่งต่อไปนี้จากรูทหนึ่งครั้ง
npm install
หากคุณต้องการสร้างบิลด์ Run npm run build
จากรูทและมันจะเติมโฟลเดอร์ dist
การกระทำทั้งหมดควรทำโดยใช้ commitizen (ซึ่งติดตั้งโดยอัตโนมัติเมื่อเรียกใช้ npm install
) commits จะถูกรวบรวมโดยอัตโนมัติเป็นหมายเลขเวอร์ชันในการเปิดตัวดังนั้นนี่จึงสำคัญมาก PRS ที่ไม่มีการกระทำตามความมุ่งมั่นจะถูกปฏิเสธ
เพื่อทำประเภทการกระทำต่อไปนี้เป็นเทอร์มินัลจากรูท
npm run commit
โปรดดูเอกสารแนวทางการสนับสนุนสำหรับข้อมูลเพิ่มเติม
ขอบคุณไปที่คนที่ยอดเยี่ยมเหล่านี้ (คีย์อีโมจิ):
สีน้ำเงิน | Jesse Talavera-Greenberg | PureSaltProductions - | Martin Duvergey - | การโทร - | Piotr Jastrzebski | sounghoo |
tnthomas - | ตัวเอง | angstr0m - | อิซซี่ - | Jeremyvansnick |
โครงการนี้เป็นไปตามข้อกำหนดทั้งหมดของผู้เข้าร่วม การมีส่วนร่วมทุกชนิดยินดีต้อนรับ!
ขอบคุณไปที่คนที่ยอดเยี่ยมเหล่านี้ (คีย์อีโมจิ):
โครงการนี้เป็นไปตามข้อกำหนดทั้งหมดของผู้เข้าร่วม การมีส่วนร่วมทุกชนิดยินดีต้อนรับ!