paint-brush
ከመይ ጌርና ኣብ ሓድነት 2D Character Controller ንፈጥር፡ 2ይ ክፋል@deniskondratev
653 ንባባት
653 ንባባት

ከመይ ጌርና ኣብ ሓድነት 2D Character Controller ንፈጥር፡ 2ይ ክፋል

Denis Kondratev17m2024/12/08
Read on Terminal Reader

ኣዝዩ ነዊሕ፤ ንምንባብ

እዚ ጽሑፍ እዚ ከመይ ጌርና ንሓደ Unity 2D character controller ከም እነዕብዮ ዘርኢ ኮይኑ፡ ሓድሽ ናይ ምእታው ስርዓት ኣወዳድባ፡ ዝተመሓየሸ ናይ ምዝላል መካኒክስ፡ ከምኡ’ውን ስሉጥ ምክትታል ካሜራ ዝሽፍን እዩ።
featured image - ከመይ ጌርና ኣብ ሓድነት 2D Character Controller ንፈጥር፡ 2ይ ክፋል
Denis Kondratev HackerNoon profile picture

ኣብዚ ጽሑፍ፡ ንነፍሲ ወከፍ ስጉምቲ ምውቃርን ምምሕያሽን መቆጻጸሪታት ብዕምቆት ብምምርማር፡ ኣብ ዩኒቲ ን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) ክቕበል እዩ። ንኽልቲኦም DW ን ብሓንሳብ ምጽቃጥ (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 ንጉድሎን።

ምድላው ናይቲ ገጸ ባህሪ

ሕጂ ኩሎም ኣካላት ድሉዋት ምስ ዝኾኑ PlayerInputCharacterController ዝበሃሉ ኣካላት ኣብቲ ኣብቲ 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 ላይክን ኮኾባትን እንተዝረኽቡ ምተመስገንኩ። ዝኾነ ጉዳይ እንተጋጢሙኩም ወይ ጌጋታት እንተረኺብኩም ክትበጽሑ ድሕር ኣይትበሉ። ስለቲ ትኹረትኩም የቐንየልና!