ኣብዚ ጽሑፍ፡ ንነፍሲ ወከፍ ስጉምቲ ምውቃርን ምምሕያሽን መቆጻጸሪታት ብዕምቆት ብምምርማር፡ ኣብ ዩኒቲ ን2D ፕላትፎርመር ዝኸውን ናይ ገጸ ባህርያት ተቖጻጻሪ ምምዕባል ቀጺልና ኣለና።
ኣብ ዝሓለፈ ጽሑፍ “ ከመይ ጌርና 2D Character Controller ኣብ ሓድነት ንፈጥር፡ 1ይ ክፋል ”፡ ከመይ ጌርካ መሰረት ናይቲ ገጸ ባህሪ ትፈጥር፡ ኣካላዊ ባህርያቱን መሰረታዊ ምንቅስቓሱን ሓዊስካ ብዝርዝር ተዛሪብና ኔርና። ሕጂ፡ ናብ ዝያዳ ምዕቡል መዳያት፡ ከም ኣተሓሕዛ እታዎታትን ዳይናሚክ ካሜራ ምክትታልን ክንሰግር ግዜኡ እዩ።
ኣብዚ ጽሑፍ፡ ኣብ ምድላው ሓድሽ ስርዓተ ምእታው ዩኒቲ፡ ነቲ ገጸ ባህሪ ንምቁጽጻር ንጡፍ ተግባራት ምፍጣር፡ ምዝላል ምኽኣልን ንትእዛዛት ተጻወትቲ ግቡእ ምላሽ ምርግጋጽን ዕምቆት ክንርኢ ኢና።
ኩሉ እቲ ኣብዚ ጽሑፍ ተገሊጹ ዘሎ ለውጥታት ባዕልኻ ከተተግብሮ እንተደሊኻ፡ ነቲ መሰረት ናይዚ ጽሑፍ ዝሓዘ “ ኣካል ገጸ ባህርያት ” ዝብል ጨንፈር መኽዘን ከተውርድ ትኽእል ኢኻ። ከም ኣማራጺ ድማ፡ ነቲ “ Character Controller ” ዝብል ጨንፈር ምስቲ ናይ መወዳእታ ውጽኢት ከተውርድዎ ትኽእሉ ኢኹም።
ቅድሚ ንባህርያትና ንምቁጽጻር ኮድ ምጽሓፍ ምጅማርና፡ ኣብቲ ፕሮጀክት ዘሎ ስርዓተ ምእታው ክንውቅሮ ኣለና። ንናይ ፕላትፎርመርና፡ ቅድሚ ገለ ዓመታት ዝተኣታተወ ሓድሽ ናይ ዩኒቲ ኢንፑት ሲስተም መሪጽና ኣለና፡ እዚ ድማ ካብቲ ባህላዊ ስርዓት ብዘለዎ ብልጫታት ኣገዳሲ ኮይኑ ይቕጽል ኣሎ።
ስርዓት እታው ዝያዳ ሞዱላርን ተዓጻጻፍን ኣገባብ ኣተሓሕዛ እታዎታት የቕርብ፣ እዚ ድማ ንዝተፈላለዩ መሳርሒታት ብቐሊሉ ቁጽጽር ከቕውሙን ብዘይ ተወሳኺ ናይ ኣተገባብራ ልዕሊ ዋጋ ዝያዳ ዝተሓላለኹ ናይ ምእታው ስናርዮታት ክድግፉን የኽእሎም።
መጀመርታ Input System package ንጽዓኖ። ካብቲ ቀንዲ ዝርዝር መስኮት → ኣመሓዳሪ ዕሹግ ብምምራጽ ኣመሓዳሪ ፓኬጅ ክፈቶ። ኣብቲ Unity Registry ዝብል ክፍሊ "Input System" ዝብል ፓኬጅ ረኺብና "Install" ዝብል ጠውቕ።
ቀጺልና ብመንገዲ Edit → Project Settings ዝብል ዝርዝር ናብቲ ናይ ፕሮጀክት ቅጥዕታት ንኺድ። ነቲ Player ዝብል ትብ ምረጽ፡ ነቲ Active Input Handling ዝብል ክፍሊ ረኺብካ፡ ናብ "Input System Package (New) ኣቐምጦ።
ነዞም ስጉምትታት ምስ ወዳእካ፡ ዩኒቲ ዳግማይ ክትጅምር ክሕብረካ እዩ። ዳግማይ ምስ ተጀመረ ኩሉ ንካፕቴንና መቆጻጸሪታት ንምውቃር ድሉው ክኸውን እዩ።
ኣብቲ ናይ ቅጥዕታት ኣቃፊራ፡ ብመንገዲ እቲ ቀንዲ ዝርዝር ፡ ንብረት → ምፍጣር → ተግባራት ምእታው፡ ተግባራት ምእታው ፍጠር። ነቲ ፋይል "Controls" ኢልካ ስመዮ።
ዩኒቲ ኢንፑት ሲስተም ሓያልን ተዓጻጻፍን ናይ ምእታው ምሕደራ መሳርሒ ኮይኑ፡ ዲቨሎፐራት ንገጸ ባህርያትን ናይ ጸወታ ባእታታትን መቆጻጸሪታት ክውቅሩ ዘኽእሎም እዩ። ዝተፈላለዩ ናይ ምእታው መሳርሒታት ይድግፍ። እቶም እትፈጥሮም Input Actions ማእከላይ ምሕደራ እታዎት ይህቡ፣ ንኣወዳድባ የቃልሉን ነቲ መተሓላለፊ ዝያዳ ንጹር ይገብሮን።
ንኣርትዖት ንምኽፋት ነቲ Controls ፋይል ድርብ ጠውቕ፣ "Character" ዝብል ስም ዘለዎ Action Map ንመቆጻጸሪ ፊደላት ወስኸሉ።
ካርታ ተግባር ኣብ ሓድነት ኣብቲ ጸወታ ፍሉይ ዕማማት ንምፍጻም ምስ ዝተፈላለዩ ተቖጻጸርትን መፍትሕን ክተሓሓዝ ዝኽእል እኩብ ተግባራት እዩ። ንመቆጻጸሪታት ንምውዳብ ውጽኢታዊ መንገዲ ኮይኑ፡ ዲቨሎፐራት ኮድ ዳግማይ ከይጸሓፉ እታዎታት ክምድቡን ከስተኻኽሉን የኽእሎም። ንዝያዳ ዝርዝር ሓበሬታ፡ ኣብ ወግዓዊ ሰነድ ስርዓተ ምእታው ተወከስ ።
እቲ ቀዳማይ ተግባር "ምንቅስቓስ" ክበሃል እዩ። እዚ ተግባር እዚ ኣንፈት ምንቅስቓስ ናይቲ ገጸ ባህሪ ክገልጽ እዩ። ንኣርባዕተ ኣንፈት ምንቅስቓስ ንምኽኣል ንዓይነት ተግባር ናብ "ዋጋ" ንዓይነት ቁጽጽር ድማ ናብ "ቬክተር2" ኣቐምጦ።
Add Up/Down/Right/Left Composite ብምምራጽን ነቶም ፍሉጣት ናይ WASD መፍትሕታት ናብ በብኣንፈቶም ብምምዳብን ነዚ ተግባር መእሰሪታት ምምዳብ።
ንብረት ምዕቃብ ብምጥዋቕ ቅጥዕታትካ ምዕቃብ ኣይትረስዕ። እዚ ኣወዳድባ እዚ ን"Move" ዝብል ተግባር ዝኸውን መእሰሪታት ዳግማይ ክትምድብ ከም እትኽእል የረጋግጽ፣ ንኣብነት ናብ መፍትሕ ፍላጻታት ወይ ውን ዋላ ናብ ጆይስቲክ ጌምፓድ።
ቀጺልና ሓድሽ ተግባር ወስኸሉ — "ዘለል"። ዓይነት ተግባር ከም "መጠወቒ" ጌርካ ምሓዝ፣ ግን ሓድሽ Interaction — "Press" ወስኸሉ፣ ከምኡውን Trigger Behavior ናብ "Press And Release" ኣቐምጦ፣ ምኽንያቱ ንኽልቲኡ ምጽቃጥን ምፍታሕን መጠወቒ ክንሕዝ ስለዘድልየና።
እዚ ድማ ነቲ ናይ ገጸ ባህርያት ምቁጽጻር ስልቲ ይውድኦ። እቲ ዝቕጽል ስጉምቲ ነዞም ተግባራት ንምሕላው ሓደ ክፍሊ ምጽሓፍ እዩ።
ንመቆጻጸሪ ገጸ ባህርያት ዝፈጠርናዮ Input Actions ምስቲ CharacterBody
ክፍሊ ከነተሓሕዞ ግዜኡ በጺሑ ኣሎ፣ እዚ ድማ እቲ ገጸ ባህሪ ብመሰረት ትእዛዛት ምቁጽጻርና ብንጥፈት ኣብ ልዕሊ እቲ ትርኢት ንኽንቀሳቐስ የኽእሎ።
ነዚ ንምግባር ድማ ንመቆጻጸሪ ምንቅስቓስ ሓላፍነት ዝስከም ስክሪፕት ፈጢርና ንንጹርነት CharacterController
ኢልና ክንሰምዮ ኢና። ኣብዚ ስክሪፕት መጀመርታ ገለ መሰረታዊ ዓውድታት ክንገልጽ ኢና። ነቲ CharacterBody
ዝበሃል ክፍሊ መወከሲ ክንውስኸሉ ኢና _characterBody
፡ እዚ ድማ ብቐጥታ ብስክሪፕት ክቆጻጸር እዩ።
ብተወሳኺ ንፍጥነት ምንቅስቓስ ናይቲ ገጸ ባህሪ ( _speed
)ን ቁመት ዝላ ( _jumpHeight
)ን መለክዒታት ከነቐምጥ ኢና። ብተወሳኺ ዕላማ ናይቲ _stopJumpFactor
ዝብል ዓውዲ ክንገልጽ ኢና።
ኣብ ብዙሓት 2D ፕላትፎርመርስ ቁመት ዝላ ክቆጻጸር ከም ዝኽእል ኣስተብሂልኩም ትኾኑ። እቲ ናይ ዘላሊ መጠወቒ ብዝነውሐ መጠን ብዝተሓዝ መጠን እቲ ገጸ ባህሪ ዝለዓለ ይዘልል። ብመሰረቱ ኣብ መጀመርታ እቲ ዝላ ናይ መጀመርታ ንላዕሊ ዝወስድ ፍጥነት ይትግበር፣ እዚ ፍጥነት ድማ እቲ መጠወቒ ምስ ዝፍታሕ ይንኪ። _stopJumpFactor
ነቲ ናይ ምዝላል መጠወቒ ምስ ፈታሕካ እቲ ንላዕሊ ዝወስድ ፍጥነት ክንደይ ከም ዝንኪ ይውስን።
ኣብነት ናይቲ ክንጽሕፎ ዝግበኣና ኮድ እንሆ፤
// CharacterController.cs public class CharacterController : MonoBehaviour { [SerializeField] private CharacterBody _characterBody; [Min(0)] [SerializeField] private float _speed = 5; [Min(0)] [SerializeField] private float _jumpHeight = 2.5f; [Min(1)] [SerializeField] private float _stopJumpFactor = 2.5f; }
ቀጺልና ነቲ ገጸ ባህሪ ንጸጋምን የማንን ናይ ምንቅስቓስ ክእለት ክንተግብር ኢና። እቲ ገጸ ባህሪ ነቲ ናይ ምንቅስቓስ መጠወቒ ክትሕዞ ከለኻ፡ ዕንቅፋታት ብዘየገድስ፡ ነቲ ዝተወሰነ ፍጥነት ምንቅስቓስ ክሕሉ ኣለዎ። ነዚ ንምዕዋት፡ ኣብቲ ስክሪፕት ሓደ ተለዋዋጢ ክንውስኽ ኢና፡ ነቲ ሕጂ ዘሎ ፍጥነት ምንቅስቓስ ኣብ ልዕሊ እቲ ገጽ (ወይ ድማ እቲ ገጸ ባህሪ ኣብ ኣየር ክህሉ ከሎ ብቐሊሉ ብኣግማድ) ክንዕቅቦ ኢና፤
// CharacterController.cs private float _locomotionVelocity;
ኣብቲ CharacterBody
ክፍሊ ነዚ ፍጥነት ንምቕማጥ ዝሕግዝ ሜላ ከነተኣታቱ ኢና፤
// CharacterBody.cs public void SetLocomotionVelocity(float locomotionVelocity) { Velocity = new Vector2(locomotionVelocity, _velocity.y); }
ጸወታና ቁልቁል ዝኣፉ ገጽ ስለዘይብሉ እዚ ኣገባብ እዚ ኣዝዩ ቀሊል እዩ። ኣብ ዝያዳ ዝተሓላለኸ ተርእዮታት፡ ንኹነታት ኣካላትን ቁልቁለት ገጽን ምሕሳብ ምተገደድና። ንሕጂ ግን ነቲ ቀጥታዊ ባእታ ናይቲ ፍጥነት ጥራይ ኢና ንዕቅቦ፡ ነቲ ልኡል x
ኮርዲኔት ጥራይ እናቐየርና።
ቀጺልና ነዚ ዋጋ ኣብ Update
method ኣብ ነፍሲ ወከፍ ፍሬም ክንሰርዖ ኢና፤
// CharacterController.cs private void Update() { _characterBody.SetLocomotionVelocity(_locomotionVelocity); }
ካብ Move
Input Action ዝመጽእ ምልክታት ንምሕላው ዝሕግዝ ሜላ ክንገልጽ ኢና፤
// CharacterController.cs public void OnMove(InputAction.CallbackContext context) { var value = context.ReadValue<Vector2>(); _locomotionVelocity = value.x * _speed; }
እቲ Move
ዝብል ተግባር ከም Vector2
ስለዝግለጽ፡ እቲ ዓውደ-ጽሑፍ ከከም ኣየኖት መፍትሕታት ከምዝተጸቕጡ ወይ ከምዝተለቐቑ ናይ ቬክተር ዋጋ ክህብ እዩ። ንኣብነት፡ መፍትሕ D
ምጽቃጥ፡ እቲ ሜላ OnMove
ነቲ ቬክተር (1, 0) ክቕበል እዩ። ንኽልቲኦም D
ን W
ን ብሓንሳብ ምጽቃጥ (1, 1) ይኸውን። ኩሎም መፍትሕታት ምፍታሕ OnMove
ብዋጋ (0, 0) ክጅምር እዩ።
ንመፍትሕ A
፡ እቲ ቬክተር (-1, 0) ክኸውን እዩ። ኣብ ኣገባብ OnMove
ነቲ ልኡል ባእታ ናይቲ ዝተቐበለ ቬክተር ወሲድና በቲ ዝተወሰነ ፍጥነት ምንቅስቓስ _speed
ንባዝሖ።
መጀመርታ ነቲ CharacterBody
ዝበሃል ክፍሊ ምዝላል ንምሕላው ክንምህሮ ኣለና። ነዚ ንምግባር ድማ ነቲ ዝላ ሓላፍነት ዝስከም ሜላ ክንውስኽ ኢና፤
// CharacterBody.cs public void Jump(float jumpSpeed) { Velocity = new Vector2(_velocity.x, jumpSpeed); State = CharacterState.Airborne; }
ኣብ ጉዳይና እዚ ኣገባብ ቀጥታዊ እዩ: ነቲ ቀጥታዊ ፍጥነት የቐምጦ እሞ ብኡንብኡ ንኹነታት ናይቲ ገጸ ባህሪ ናብ Airborne
ይቕይሮ።
ቀጺልና፡ እቲ ገጸ ባህሪ ክዘልል ዘለዎ ፍጥነት ክንውስን ኣለና። ድሮ ቁመት ዝላ ገሊጽናዮ ኣለና፡ ስሕበት ድማ ብቐጻሊ ኣብ ኣካላት ከም ዝሰርሕ ንፈልጥ ኢና። ካብዚ ብምብጋስ እቲ ናይ መጀመርታ ፍጥነት ዝላ ነዚ ቀመር ተጠቒምካ ክሕሰብ ይከኣል፤
ኣብዚ h ቁመት ዝላ ኮይኑ ፡ g ድማ ምቅልጣፍ ስሕበት እዩ። ኣብቲ CharacterBody
ዝበሃል ክፍሊ ዝርከብ ናይ ስሕበት መባዛሒ እውን ክንሕተተሉ ኢና። ንመጀመርታ ፍጥነት ዝላ ንምግላጽ ሓድሽ ሜዳ ክንውስኽን ከምዚ ዝስዕብ ክንሕስቦን ኢና፤
// CharacterController.cs private float _jumpSpeed; private void Awake() { _jumpSpeed = Mathf.Sqrt(2 * Physics2D.gravity.magnitude * _characterBody.GravityFactor * _jumpHeight); }
እቲ ገጸ ባህሪ ኣብዚ እዋን እዚ ይዘልል ድዩ ኣይዘልልን ንምክትታል ካልእ ዓውዲ ከድልየና እዩ፣ ስለዚ ኣብቲ ዝግባእ ግዜ ፍጥነት ዝላ ክንድርቶ ንኽእል።
ብተወሳኺ እቲ ተጻዋታይ ክሳብ ዝዓልብ ነቲ ናይ ምዝላል መጠወቒ እንተሓዚሉ ነዛ ባንዴራ ባዕልና ዳግማይ ክንሰርሓ ይግባእ ። እዚ ኣብቲ Update
ዝብል ኣገባብ ክግበር እዩ፤
// CharacterController.cs private bool _isJumping; private void Update() { if (_characterBody.State == CharacterState.Grounded) { _isJumping = false; } //... }
ሕጂ፡ ነቲ Jump
ተግባር ንምሕላው ዝሕግዝ ሜላ ንጽሓፍ፤
// CharacterController.cs public void OnJump(InputAction.CallbackContext context) { if (context.started) { Jump(); } else if (context.canceled) { StopJumping(); } }
እቲ Jump
ዝብል ተግባር መጠወቒ ስለዝኾነ፡ እቲ መጠወቒ ምጽቃጥ ጀሚሩ ( context.started
) ወይ ተዛዚሙ ( context.canceled
) ካብቲ ዓውዲ ክንውስን ንኽእል። ካብዚ ብምብጋስ ወይ ነቲ ዝላ ነበግሶ ወይ ድማ ነቋርጾ።
ነቲ ዝላ ንምፍጻም ዝሕግዝ ሜላ ኣብዚ ኣሎ፤
// CharacterController.cs private void Jump() { if (_characterBody.State == CharacterState.Grounded) { _isJumping = true; _characterBody.Jump(_jumpSpeed); } }
ቅድሚ ምዝላልና፡ እቲ ገጸ ባህሪ ኣብ መሬት እንተሃልዩ ንምርግጋጽ። ከምኡ እንተኾይኑ ድማ _isJumping
ዝብል ባንዴራ ኣቐሚጥና ነቲ ኣካል ብ_ _jumpSpeed
ከም ዝዘልል ንገብሮ።
ሕጂ፡ ነቲ ደው ምባል ዝዘልል ባህሪ ነተግብሮ፤
// CharacterController.cs private void StopJumping() { var velocity = _characterBody.Velocity; if (_isJumping && velocity.y > 0) { _isJumping = false; _characterBody.Velocity = new Vector2( velocity.x, velocity.y / _stopJumpFactor); } }
ነቲ ዝላ ደው ንብሎ _isJumping
ዝብል ባንዴራ ንጡፍ ምስ ዝኸውን ጥራይ እዩ። ካልእ ኣገዳሲ ኩነታት ድማ እቲ ገጸ ባህሪ ንላዕሊ ዝኸይድ ክኸውን ኣለዎ። እዚ ድማ ንታሕቲ እናተጓዓዝካ እቲ ናይ ዝላ መጠወቒ እንተተለቒቑ ፍጥነት ውድቀት ከይድርት ይከላኸል። ኩሎም ኩነታት እንተተማሊኦም፡ ነቲ _isJumping
ባንዴራ ዳግማይ ንሰርዖን ነቲ ቀጥታዊ ፍጥነት ብ ረቛሒ _stopJumpFactor
ንጉድሎን።
ሕጂ ኩሎም ኣካላት ድሉዋት ምስ ዝኾኑ PlayerInput
ን CharacterController
ዝበሃሉ ኣካላት ኣብቲ ኣብቲ scene ዘሎ Captain object ንውስኾ። ነቲ ን3D ፊደላት ንምቁጽጻር ዝተዳለወ ስታንዳርድ ኣሃዱ ኣሃዱ ዘይኮነስ ነቲ ዝፈጠርናዮ CharacterController
component ምምራጽካ ኣረጋግጽ።
ን CharacterController
፡ ነቲ ዝጸንሐ CharacterBody
ክፍሊ ካብቲ ፊደል ምደቦ። ን PlayerInput
፡ ነቲ ኣቐዲሙ ዝተፈጥረ Controls ኣብቲ Actions
ዝብል ዓውዲ ኣቐምጦ።
ቀጺልና ነቲ PlayerInput ዝበሃል ክፍሊ ካብ CharacterController ዝምጥን ሜላታት ንኽጽውዕ ንውቅሮ። ኣብቲ ኣርታዒ ንዘሎ ክፍልታት ፍጻመታትን ገጸ ባህርያትን ኣስፍሕ፣ ነቶም ተዛመድቲ ሜላታት ድማ ምስ ተግባራት ምንቅስቓስን ምዝላልን ኣተሓሕዞም።
ሕጂ፡ ኩሉ ነቲ ጸወታ ንምክያድን ኩሎም እቶም ዝተዋቕሩ ኣካላት ብኸመይ ብሓባር ከም ዝሰርሑ ንምፍታንን ድሉው ኮይኑ ኣሎ።
ሕጂ፡ ካሜራ ነቲ ገጸ ባህሪ ኣብ ዝኸድዎ ቦታ ክትስዕቦ ክንገብሮ ኣለና። ሓድነት ንኣመራርሓ ካሜራ ሓያል መሳርሒ ይህብ — ሲነማሽን ።
ሲነማሽን ኣብ ዩኒቲ ንምቁጽጻር ካሜራ ዝኸውን ሰውራዊ መፍትሒ ኮይኑ፡ ንደቨሎፐራት ምስ ድሌታት ጸወታ ዝሰማማዕ ዳይናሚክ፡ ጽቡቕ ዝተቓነየ ስርዓታት ካሜራ ንምፍጣር ሰፊሕ ዓቕሚ የቕርብ። እዚ መሳርሒ እዚ፡ ከም ምክትታል ገጸ ባህርያት፡ ኣውቶማቲክ ምትዕርራይ ፎኮስን ካልእ ብዙሕን ዝኣመሰሉ ዝተሓላለኹ ሜላታት ካሜራ ንምትግባር ቀሊል ይገብሮ፡ ኣብ ነፍሲ ወከፍ ትርኢት ህይወትን ሃብትን ይውስኽ።
መጀመርታ ኣብቲ scene ዘሎ Main Camera object ንረክብ እሞ CinemachineBrain
component ንውስኸሉ።
ቀጺልና ኣብቲ ትርኢት CaptainCamera ዝበሃል ሓድሽ ነገር ንፍጠር። እዚኣ ልክዕ ከም ፕሮፌሽናል ካሜራማን ንካፕቴን እትስዕብ ካሜራ ክትከውን እያ። ኣብኡ CinemachineVirtualCamera
ዝብል ክፍሊ ወስኸሉ። ነቲ Follow ዝብል ዓውዲ ናብ ካፕቴን ኣቐምጦ፣ Framing Transposer for the Body field ምረጽ፣ ነቲ Lens Ortho Size ዝብል መለክዒ ድማ ናብ 4 ኣቐምጦ።
ብተወሳኺ፡ ናይ ካሜራ ኦፍሴት ብተዛማዲ ምስቲ ገጸ ባህሪ ንምግላጽ ካልእ ክፍሊ ከድልየና እዩ — CinemachineCameraOffset
። ዋጋ Y ናብ 1.5 ዋጋ Z ድማ ናብ -15 ኣቐምጦ።
ሕጂ፡ ካሜራ ከመይ ጌራ ንባህርያትና ከም እትኽተል ንፈትን።
ምሉእ ብምሉእ ጽቡቕ ውጽኢት ዝረኸበ ይመስለኒ። ካሜራ ሓሓሊፋ ቁሩብ ከም እትሽርሽር ኣስተብሂለ። ነዚ ንምእራም ድማ ነቲ Blend Update Method ዝብል ዓውዲ ናይቲ Main Camera object ናብ FixedUpdate ኣቐሚጠዮ።
እስከ ነቲ ዝተመሓየሸ መካኒክስ ንፈትኖ። ክትጎዪን ብቐጻሊ ክትዘልልን ፈትን። ምኩራት ተጻወትቲ፡ እቲ ዝላታት ኩሉ ግዜ ከምዘይምዝገብ ከስተብህሉ ይኽእሉ። ኣብ መብዛሕትኡ ጸወታታት እዚ ጉዳይ ኣይኮነን።
ንመጠወቒ ዝላ ዳግማይ ንምጽቃጥ ልክዕ ናይ ምዕላብ ግዜ ምግማት ኣጸጋሚ ኮይኑ ተረኺቡ። ተጻወትቲ ቅድሚ ምዕላቦም ቁሩብ ዝላ ክጸቕጡ ብምፍቃድን እቲ ገጸ ባህሪ ምስ ዓለቡ ብቕጽበት ክዘልል ብምግባርን ነቲ ጸወታ ዝያዳ ይቕረ ዝብሎ ክንገብሮ ኣለና። እዚ ባህሪ እዚ ምስቲ ተጻወትቲ ዝለመድዎ ይሰማማዕ።
ነዚ ንምትግባር ድማ ሓድሽ ተለዋዋጢ _jumpActionTime
ከነተኣታቱ ኢና፡ እዚ ድማ ነቲ ዕድል እንተተፈጢሩ ገና ዝላ ክጅምር ዝኽእል መስኮት ግዜ ዝውክል እዩ።
// CharacterController.cs [Min(0)] [SerializeField] private float _jumpActionTime = 0.1f;
_jumpActionEndTime
ዝብል ዓውዲ ወሲኸ ኣለኹ፣ እዚ ድማ መወዳእታ ናይቲ ናይ ምዝላል ተግባር መስኮት ዝሕብር እዩ። ብኻልእ ኣዘራርባ ክሳብ _jumpActionEndTime
ዝበጽሕ እቲ ገጸ ባህሪ ዕድል እንተተፈጢሩ ክዘልል እዩ። ከምኡ ውን Jump
action handler update ንገብሮ።
// CharacterController.cs private float _jumpActionEndTime; public void OnJump(InputAction.CallbackContext context) { if (context.started) { if (_characterBody.State == CharacterState.Grounded) { Jump(); } else { _jumpActionEndTime = Time.unscaledTime + _jumpActionTime; } } else if (context.canceled) { StopJumping(); } }
እቲ ናይ ዘላሊ መጠወቒ ምስ ዝጽቀጥ፡ እቲ ገጸ ባህሪ ኣብ መሬት እንተሃልዩ፡ ብኡንብኡ ይዘልሉ። እንተዘይኮይኑ፡ እቲ ዝላ ገና ክፍጸም ዝኽእል ናይ ግዜ መስኮት ንዕቅቦ።
ካብቲ Jump
ሜላ ባዕሉ ነቲ Grounded
state check ነወግዶ።
// CharacterController.cs private void Jump() { _isJumping = true; _characterBody.Jump(_jumpSpeed); }
ነቲ ደው ምባል ዝዘልል ኣገባብ እውን ክንመዓራረዮ ኢና። እቲ መጠወቒ ቅድሚ ምዕላብ እንተተለቒቑ፡ ዝኾነ ዝላ ክኽሰት የብሉን፡ ስለዚ _jumpActionEndTime
ዳግማይ ንሰርዖ።
// CharacterController.cs private void StopJumping() { _jumpActionEndTime = 0; //... }
መዓስ እቲ ገጸ ባህሪ ከም ዝዓለበ ፈቲሽና ዝላ ከነበግስ ይግባእ? እቲ CharacterBody
ኩነታት ኣብ FixedUpdate
ይስርሕ፣ መስርሕ ተግባር ድማ ድሒሩ ይፍጸም። Update
ይኹን FixedUpdate
ብዘየገድስ፡ ኣብ መንጎ ምዕላብን ምዝላልን ናይ ሓደ ፍሬም ምድንጓይ ከጋጥም ይኽእል እዩ፡ እዚ ድማ ርኡይ እዩ።
ንመዓልቦ ብቕጽበት መልሲ ንምሃብ ኣብ CharacterBody
StateChanged
event ክንውስኽ ኢና። እቲ ቀዳማይ ስነ-ሞጎት እቲ ዝሓለፈ ኩነታት ክኸውን እዩ፣ እቲ ካልኣይ ድማ እቲ ናይ ሕጂ ኩነታት ክኸውን እዩ።
// CharacterBody.cs public event Action<CharacterState, CharacterState> StateChanged;
ነቲ ናይ ግዝኣት ለውጢ ክስተት ንምብጋስ ነቲ ናይ ግዝኣት ምሕደራ ከነስተኻኽሎ ኢና እሞ FixedUpdate
ዳግማይ ክንጽሕፎ ኢና።
// CharacterBody.cs [field: SerializeField] private CharacterState _state; public CharacterState State { get => _state; private set { if (_state != value) { var previousState = _state; _state = value; StateChanged?.Invoke(previousState, value); } } }
ብተወሳኺ ኣብ FixedUpdate
surfaceHit
ከመይ ከም ዝሕዞ ኣጽሪየዮ ኣለኹ።
// CharacterBody.cs private void FixedUpdate() { //... if (_velocity.y <= 0 && slideResults.surfaceHit) { var surfaceHit = slideResults.surfaceHit; Velocity = ClipVector(_velocity, surfaceHit.normal); if (surfaceHit.normal.y >= _minGroundVertical) { State = CharacterState.Grounded; return; } } State = CharacterState.Airborne; }
ኣብ CharacterController
፡ ኣብቲ StateChanged
ክስተት ሳብስክራይብ ክንገብር ኢና፡ ሓደ ሃንድለር ድማ ክንውስኽ ኢና።
// CharacterController.cs private void OnEnable() { _characterBody.StateChanged += OnStateChanged; } private void OnDisable() { _characterBody.StateChanged -= OnStateChanged; } private void OnStateChanged(CharacterState previousState, CharacterState state) { if (state == CharacterState.Grounded) { OnGrounded(); } }
ነቲ Grounded
state check ካብ Update
ኣውጺእና ናብ OnGrounded
ከነሰጋግሮ ኢና።
// CharacterController.cs private void Update() { _characterBody.SetLocomotionVelocity(_locomotionVelocity); } private void OnGrounded() { _isJumping = false; }
ሕጂ፡ ዝላ ክጅምር ኣለዎ ድዩ ኣይግባእን ንምርግጋጽ፡ ነቲ ኮድ ወስኸሉ።
// CharacterController.cs private void OnGrounded() { _isJumping = false; if (_jumpActionEndTime > Time.unscaledTime) { _jumpActionEndTime = 0; Jump(); } }
_jumpActionEndTime
ካብቲ ሕጂ ዘሎ ሰዓት ዝዓቢ እንተኾይኑ፡ እቲ ናይ ምዝላል መጠወቒ ኣብ ቀረባ እዋን ተጸቒጡ ማለት እዩ፡ ስለዚ _jumpActionEndTime
ዳግማይ ንሰርዖ እሞ ነቲ ዝላ ንፍጽሞ።
ሕጂ፡ ምስቲ ገጸ ባህሪ ብቐጻሊ ክትዘልል ፈትን። እቲ ናይ ዘላሊ መጠወቒ ዝያዳ ምላሽ ዝህብ ኮይኑ ከም ዝስምዓካ ከተስተብህል ኢኻ፡ ምቁጽጻር ድማ ነቲ ገጸ ባህሪ ዝያዳ ስሉጥ ከም ዝኸውን። ይኹን እምበር፡ ኣብ ዝተወሰኑ ኩነታት፡ ከም ኣብዚ ኣብ ታሕቲ ዘሎ ስእሊ ዝርአ ኩርናዕ፡ እቲ Grounded
state ቁሩብ ምድንጓይ ከም ዘጋጥሞ ተዓዚበ፡ እዚ ድማ ነቲ ናይ ዘላሊ ሰንሰለት የቋርጾ።
ነዚ ንምፍታሕ ኣብቲ CharacterBody
component ዘሎ Surface Anchor
field ኣብ ክንዲ 0.01 ናብ 0.05 ኣቐሚጠዮ። እዚ ዋጋ እዚ እቲ ኣካል ናብ Grounded
ኩነታት ንኽኣቱ ናብ ሓደ ገጽ ዝወሓደ ርሕቀት ይውክል።
ካብ ቀጥታዊ ቦታታት እናጎየኻ ክትዘልል ምፍታን ኩሉ ግዜ ከም ዘይሰርሕ ኣስተብሂልካ ትኸውን። እቲ ናይ ዘላሊ መጠወቒ ሓደ ሓደ ግዜ መልሲ ዘይህብ ኮይኑ ክስምዓካ ይኽእል።
እዚ ሓደ ካብቲ ን2D ፕላትፎርመር ዝኸውን Character Controller ምምዕባል ዝረአ ረቂቕ ነገራት እዩ። ተጻወትቲ ዋላ ቁሩብ ደንጉዮም ነቲ ናይ ምዝላል መጠወቒ ክጽቕጡ ከለዉ ናይ ምዝላል ክእለት የድልዮም። እዚ ኣምር እዚ ፍሉይ ክመስል ይኽእል እዩ፡ መብዛሕትኦም ፕላትፎርመርስ ብኸመይ ከም ዝሰርሑ ግን እዩ። ውጽኢቱ ድማ ከምቲ ኣብ ታሕቲ ዘሎ ኣኒሜሽን ዝተገልጸ ገጸ ባህሪ ካብ ኣየር ክደፍእ ዝመስል እዩ።
ነዚ መካኒክ ነተግብሮ። ነቲ ናይ ግዜ መስኮት (ብካልኢታት) ንምዕቃብ ሓድሽ ዓውዲ ከነተኣታቱ ኢና፡ ኣብዚ እዋን እዚ እቲ ገጸ ባህሪ ድሕሪ ምጥፋእ Grounded
state ገና ክዘልል ይኽእል።
// CharacterController.cs [Min(0)] [SerializeField] private float _rememberGroundTime = 0.1f;
ብተወሳኺ ነቲ ናይ ግዜ ማሕተም ንምዕቃብ ካልእ ዓውዲ ክንውስኽ ኢና ድሕሪኡ እቲ Grounded
state "ተረሲዑ"።
// CharacterController.cs private float _lostGroundTime;
እዚ ኩነታት እዚ ነቲ CharacterBody
ክስተት ተጠቒምካ ክከታተሎ እዩ። ነዚ ዕላማ እዚ ነቲ OnStateChanged
handler ከነስተኻኽሎ ኢና።
// CharacterController.cs private void OnStateChanged(CharacterState previousState, CharacterState state) { if (state == CharacterState.Grounded) { OnGrounded(); } else if (previousState == CharacterState.Grounded) { _lostGroundTime = Time.unscaledTime + _rememberGroundTime; } }
እቲ ገጸ ባህሪ ብሰንኪ ኮነ ኢልካ ምዝላል ድዩ ወይስ ብኻልእ ምኽንያት Grounded
state ስኢኑ ምፍላይ ኣገዳሲ እዩ። ድሮ _isJumping
ዝብል ሰንደቕ ዕላማ ኣለና፣ እዚ ድማ ኣብ ነፍሲ ወከፍ StopJumping
ኣብ ዝጽውዓሉ እዋን ተደራራቢ ተግባራት ንምክልኻል ይስረዝ።
ተደራራቢ ዝላ ምቁራጽ ንኣገባብ ጸወታ ስለዘይጸልዎ ካልእ ባንዴራ ከየተኣታቱ ወሲነ። ክትፍትኑ ናጻ ትኾኑ። ሕጂ እቲ _isJumping
ባንዴራ ዝጽረግ እቲ ገጸ ባህሪ ድሕሪ ዘሊሉ ምስ ዝዓለበ ጥራይ እዩ። ብኡ መሰረት ኮድ ነሐድሶ።
// CharacterController.cs private void StopJumping() { _jumpActionEndTime = 0; var velocity = _characterBody.Velocity; if (_isJumping && velocity.y > 0) { _characterBody.Velocity = new Vector2( velocity.x, velocity.y / _stopJumpFactor); } }
ኣብ መወዳእታ ድማ ነቲ OnJump
ዝብል ኣገባብ ክንከልሶ ኢና።
// CharacterController.cs public void OnJump(InputAction.CallbackContext context) { if (context.started) { if (_characterBody.State == CharacterState.Grounded || (!_isJumping && _lostGroundTime > Time.unscaledTime)) { Jump(); } else { _jumpActionEndTime = Time.unscaledTime + _jumpActionTime; } } else if (context.canceled) { StopJumping(); } }
ሕጂ፡ ካብ ቀጥታዊ ገጽ ምዝላል ድሕሪ ደጊም ንህርመት ጸወታ ኣይዘርግሖን እዩ፡ ዋላ’ኳ ርኡይ ዕሽነት እንተሃለዎ፡ ኣዝዩ ዝያዳ ተፈጥሮኣዊ ኮይኑ ይስምዓካ። እቲ ገጸ ባህሪ ቃል ብቓሉ ካብ ኣየር ክደፍእ ይኽእል እዩ፣ ካብቲ ስነመጎታዊ ዝመስል ንላዕሊ ርሒቑ ክኸይድ ይኽእል። ግን ልክዕ እዚ እዩ ንፕላትፎርመርና ዘድሊ።
እቲ ናይ መወዳእታ ምትንኻፍ ነቲ ገጸ ባህሪ ናብ ኣንፈት ምንቅስቓስ ገጹ ምግባር እዩ። ነዚ ብዝቐለለ መንገዲ ክንተግብሮ ኢና — ናይቲ ገጸ ባህሪ ኣብ መስመር x-axis ስኬል ብምቕያር። ኣሉታዊ ዋጋ ምቕማጥ ንካፕቴንና ብኣንጻሩ ኣንፈት ከም ዝጥምት ክገብሮ እዩ።
መጀመርታ ካብ 1 ንኸይፍለ ነቲ ኦሪጅናል ሚዛን ንዕቅቦ።
// CharacterController.cs public class CharacterController : MonoBehaviour { //... private Vector3 _originalScale; private void Awake() { //... _originalScale = transform.localScale; } }
ሕጂ ንጸጋም ወይ ንየማን ክንከይድ ከለና፡ ኣወንታዊ ወይ ኣሉታዊ ሚዛን ክንጥቀም ኢና።
// CharacterController.cs public class CharacterController : MonoBehaviour { public void OnMove(InputAction.CallbackContext context) { //... // Change character's direction. if (value.x != 0) { var scale = _originalScale; scale.x = value.x > 0 ? _originalScale.x : -_originalScale.x; transform.localScale = scale; } } }
ውጽኢቱ ንፈትኖ።
እዚ ጽሑፍ ኣዝዩ ዝርዝር ኮይኑ ተረኺቡ፡ እንተኾነ ግን ንኹሉ ኣገዳሲ መዳያት ምቁጽጻር ገጸ ባህርያት ኣብ 2D ፕላትፎርመር ክንሽፍኖ ክኢልና። ከም መዘኻኸሪ፡ ኣብ “ Character Controller ” ጨንፈር ናይቲ መኽዘን ናይ መወዳእታ ውጽኢት ክትዕዘብ ትኽእል ኢኻ።
እዚን እቲ ዝሓለፈ ጽሑፍን ሓጋዚ ኮይኑ እንተረኺብኩም ወይ እንተትረኽብዎ፡ ኣብ GitHub ላይክን ኮኾባትን እንተዝረኽቡ ምተመስገንኩ። ዝኾነ ጉዳይ እንተጋጢሙኩም ወይ ጌጋታት እንተረኺብኩም ክትበጽሑ ድሕር ኣይትበሉ። ስለቲ ትኹረትኩም የቐንየልና!