Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Looking for basic scripts to follow for a dynamic 2D character build

Discussion in 'Getting Started' started by DTheChemist, Apr 14, 2021.

  1. DTheChemist

    DTheChemist

    Joined:
    Jan 18, 2021
    Posts:
    115
    Does anyone have any open source scripts to follow where a basic 2D character has Walk, Jump & crouch (to duck)? Ive been searching Github also. but not much luck yet. im just looking for something to study to get it to work properly to work with my script. And yes im aware it has something to do with the collision sizes n stuff. ive seen that but its getting the controller (and keyboard) to make my character crouch down by pressing down on the controller or any button i set it to on pc.

    Currently my character runs, jumps and attacks. Its 8 bit Nintendo style im at my wits in why i cant get my character to crouch.
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I'm not sure I understand the difficulty. 8-bit Nintendo style crouching is literally just switching to a different sprite. And of course you need to adjust your collider according to what sprite image is currently shown.

    But that's obvious, so what's the trouble you're running into?
     
  3. DTheChemist

    DTheChemist

    Joined:
    Jan 18, 2021
    Posts:
    115
    1) i dont know how to create the proper input trigger for crouch
    2) im not entirely sure how the collision box trigger script should look (i try to follow tutorials on youtube but either they make it too complicated to follow or its a half job video with no completion)
    &
    3) The animator settings. i have a free template that gives me an idea but im seeing theres different methods to doing it smh

    so basically 1st. what does the crouch input is supposed to look like exactly? Currently i got my character to run, jump and attack and i can use my keyboard or gamepad. But for some damn reason i cant figure out how to connect things right so that crouch input transforms my sprites to change to crouch animation

    example below. this is part of the input i did for jump and to move horizontal. i have my attack in a different CS file

    Code (CSharp):
    1.  
    2.         void Update()
    3.         {
    4.             mX = Input.GetAxisRaw("Horizontal");
    5.        
    6.             if (Input.GetButtonDown("Jump") && Is_Grounded())
    7.        
    8.             {
    9.               Jump();
    10.             }
    That script above is in my Playermovement

    here below is an example of whats in my PlayerAnim file where the Animator parameters activate


    Code (CSharp):
    1.  
    2. void Update()
    3. {
    4. //Anims
    5. anim.SetBool("Jumping", character.IsJumping());
    6. anim.SetBool("InAir", !character.Is_Grounded());
    7. anim.SetBool("isGrounded", character.Is_Grounded());
    8.  
    9. }
    10. void OnJump()
    11. {
    12. anim.SetTrigger("Jump");
    13. }
    14.  
    All im trying to do is get a clear idea how to start up the crouch sprite activator. im lost at this point how to do that
     
    Last edited: Apr 22, 2021
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Well you know how to use GetAxisRaw. Assuming you want to push "down" to crouch, you'd use that same function, something like this:

    Code (CSharp):
    1. bool isCrouching = false;
    2.  
    3. void Update() {
    4.     // ...other stuff you're already doing...
    5.  
    6.     bool crouch = Input.GetAxisRaw("Vertical") < -0.5f;
    7.     if (crouch && !isCrouching) StartCrouch();
    8.     else if (!crouch && isCrouching) EndCrouch();
    9. }
    Then you would write StartCrouch and EndCrouch methods that change your sprite.

    I personally don't much care for using Unity's Animator for this sort of thing; see my article on three ways to animate in Unity and see what you think for yourself. Depending on what approach you use, the contents of the StartCrouch and EndCrouch methods will vary. But initially, these should contain just Debug.Log statements that let you see when they are being called. Then run the game, press down on your D-pad (or use the down-arrow or S key), and verify that the messages appear as you expect.

    Then tackle the next step, with a more specific question: how do you make your character transition to the crouching sprite, using whichever of the three approaches to animation you have decided to embrace?
     
  5. DTheChemist

    DTheChemist

    Joined:
    Jan 18, 2021
    Posts:
    115
    Ahh ok i see what you did there. with the Bool crouch etc etc. And yeah i used Debug.Log before seeing an old tutorial. so ill do that too then. Thanks on this. ill look through your Article.

    One more thing ... is it better to keep the input expression ("Vertical") or can i change it to ("Crouch") so it stands out?

    after dinner im gonna dig in all of this

    oh with crouching i was doing it with the animator way that i was trying to follow in this Black and white free template 2D platformer i have. i got more comfortable doing that since it worked for my jump and run but im always open to other options to look into to try
     
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Input.GetAxisRaw("Crouch") would not work, because there isn't a "Crouch" axis. Or I should say there probably isn't one. You could define one in the Input Manager, if you know how. But you get a Horizontal and a Vertical axis by default, so I would recommend you just stick with those.

    So if you're using the animator approach, your StartCrouch and EndCrouch methods could simply set a boolean property on the animator. And then you'd have to have your animator controller set up with transitions based on that property, from your various standing/walking states to crouching, and from crouching back to standing.
     
  7. DTheChemist

    DTheChemist

    Joined:
    Jan 18, 2021
    Posts:
    115
    Ok im back to it. I looked over your article. really useful for damn sure. if i was starting over fresh clean again id definitely follow your entirely character build for mines. i may just do that anyway in a different build to see where it takes me in progress starting from scratch again with a script

    As for the crouch yeah i know how to put it in Input Manager. I had labeled Crouch in there before but theres already the default "Vertical" as you said. but since keeping that in there is better then ill run with that then this time to try for better results for what im trying to do.

    As for StartCrouch and EndCrouch would those be Void methods?

    would that be better to keep that in my Playermovement script with the InputAxis for the crouch?

    for example i had something like these below in there following a tutorial but it didnt work entirely smh (no compiler error but it just wasnt changing the sprites when i hit down). How would you make it look to connect with that. Ill be honest i was trying to figure out these two methods below to work with my own attempt at a crouch input.

    This one that i tried to follow in a tutorial method

    Code (CSharp):
    1.        
    2.  
    3. private void Crouch(){
    4.             if (playerControls.crouchingPressed){
    5.                 isCrouching = true;
    6.                 playerCollider.size = crouchColliderSize;
    7.                 playerCollider.offset = crouchColliderOffset;
    8.  
    9.             }
    10.         }
    11.  
    12.         private void StandUp(){
    13.             if (!playerControls.crouchingPressed){
    14.                 isCrouching = false;
    15.                 playerCollider.size = standColliderSize;
    16.                 playerCollider.offset = standColliderOffset;
    17.  
    18.             }
    19.         }
    20.     }
    21. }
    22.  
    Or this one from this Free template i have. i was trying to use that for crouch input i was figuring out at the time too in a different build

    Code (CSharp):
    1.  
    2.  
    3. private void UpdateCrouch()
    4.         {
    5.             if (!can_crouch)
    6.                 return;
    7.  
    8.             //Crouch
    9.             bool was_crouch = is_crouch;
    10.             if (move_input.y < -0.1f && is_grounded)
    11.             {
    12.                 is_crouch = true;
    13.                 movement = Vector2.zero;
    14.                 playerCollider.size = new Vector2(standColliderSize.x, standColliderSize.y * crouch_coll_percent);
    15.                 playerCollider.offset = new Vector2(standColliderOffset.x, standColliderOffset.y * crouch_coll_percent);
    16.  
    17.                 if (!was_crouch && is_crouch)
    18.                 {
    19.                     if (onCrouch != null)
    20.                         onCrouch.Invoke();
    21.                 }
    22.             }
    23.             else
    24.             {
    25.                 is_crouch = false;
    26.                 playerCollider.size = crouchColliderSize;
    27.                 playerCollider.offset = crouchColliderOffset;
    28.             }
    29.         }
    30.  

    how would you make either of those methods connect properly to the Bool crouch you shared?


    ill be trying to see what works using one of those with it in the meantime
     
  8. DTheChemist

    DTheChemist

    Joined:
    Jan 18, 2021
    Posts:
    115
    Ok this is what i did so far and tested it to make sure theres no compile errors. the other part ill try to connect tomorrow. Gonna get some sleep


    Code (CSharp):
    1.  
    2.  
    3. [Header("Crouch")]
    4. bool isCrouching = false;
    5. bool crouch = false;
    6.  
    7.      
    8.  
    9.         // For initialization
    10.         void Start()
    11.         {
    12.  
    13.         }
    14.  
    15.         void Update()
    16.         {
    17.             mX = Input.GetAxisRaw("Horizontal");
    18.             if (Input.GetButtonDown("Jump") && Is_Grounded())
    19.             {
    20.               Jump();
    21.             }
    22.             {
    23.                 bool crouch = Input.GetAxisRaw("Vertical") < -0.5f;
    24.                 if (crouch && !isCrouching) StartCrouch();
    25.                 else if (!crouch && isCrouching) EndCrouch();
    26.             }
    27.             //anim.SetFloat("Speed", Mathf.Abs(horizontalMove));
    28.             if (Mathf.Abs(mX) > 0.05f){
    29.                 anim.SetBool("isRunning", true);
    30.             }else{
    31.                 anim.SetBool("isRunning", false);
    32.             }if (mX > 0f){
    33.                 transform.localScale = new Vector3(1f, 1f, 1f);
    34.             }else if (mX < 0f){
    35.                 transform.localScale = new Vector3(-1f, 1f, 1f);
    36.             }
    37.             //
    38.             anim.SetBool("isGrounded", Is_Grounded());
    39.             //anim.SetBool("Crouch", IsCrouched());//
    40.         }
    41.  
    42.  
    43.         private void EndCrouch()
    44.         {
    45.             if (!crouch && isCrouching)
    46.             {
    47.                 isCrouching = false;
    48.                 playerCollider.size = standColliderSize;
    49.                 playerCollider.offset = standColliderOffset;
    50.  
    51.             }
    52.         }
    53.  
    54.  
    was that done properly?
     
    Last edited: Apr 25, 2021
  9. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Almost. I'm honestly surprised that compiles; your Awake method starts on line 7-8, and looks like it's intended to end at line 23, but I see no } there. So the Awake method just never ends as far as I can tell.

    Also the portion from lines 17-22 looks like it needs to be in Update (which runs every frame), not Awake (which runs only once).

    Your StartCrouch and EndCrouch methods look fine, except that they only effect they have is to change the player collider size and offset. They are not speaking to your Animator. You will need to use animator.SetBool to set a boolean property in the animator, as shown in the example in the docs.
     
  10. DTheChemist

    DTheChemist

    Joined:
    Jan 18, 2021
    Posts:
    115
    Ok i did this here just now.. obviously nothing worked with it because i did it wrong for crouch. im still looking it over. No compile errors though. i tried to add in a bool there. i thought that was the answer to get things happening


    Code (CSharp):
    1. private void StartCrouch()
    2.         {
    3.             if (crouch && !isCrouching)
    4.             {
    5.                 anim.SetBool("Crouch", true);
    6.                 playerCollider.size = crouchColliderSize;
    7.                 playerCollider.offset = crouchColliderOffset;
    8.  
    9.  
    10.             }
    11.         }
    12.  
    13.         private void EndCrouch()
    14.         {
    15.             if (!crouch && isCrouching)
    16.             {
    17.                 anim.SetBool("Crouch", false);
    18.                 playerCollider.size = standColliderSize;
    19.                 playerCollider.offset = standColliderOffset;
    20.  
    21.             }
    22.         }
     
  11. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    That's a necessary step, yeah

    Note that you don't need the if statements in StartCrouch and EndCrouch. If you followed my suggestion above, you've already checked those conditions before StartCrouch and EndCrouch are called. So by the time these methods are executing, they aren't supposed to check anything — they are supposed to just do what they say (start or end the crouch).

    So take out the if statements, and add in Debug.Log statements so you can be certain they're being called when you think they are.

    Then, if your character is still not crouching, then the problem is not in your code but in your animation controller. Check it over to make sure that you have a "Crouch" property, and that you have transitions set up to go to and from the crouching sprite based on the value of that property.
     
  12. DTheChemist

    DTheChemist

    Joined:
    Jan 18, 2021
    Posts:
    115
    Oh ok. i thought you meant it was fine to keep it in that other post i shared.... but i think i understand why you are confused. im trying not to share that big @ss wall of code im digging through and cleaning around. its way more code than that. ill share it

    ill remove the "if" statements. i thought i was being clever by using a similar script method i was following before and tried to alter it a bit for the result i was looking for

    but anyway heres the entire script

    Code (CSharp):
    1. namespace prototype.Platformer
    2. {
    3.  
    4.     public class PlayerMovement : MonoBehaviour
    5.     {
    6.         public PlayerAnim controller;//
    7.  
    8.      
    9.  
    10.         public AudioClip jumpAudio;
    11.         public AudioClip respawnAudio;
    12.         public AudioClip ouchAudio;
    13.         //
    14.         public UnityAction onJump;
    15.         public UnityAction onLand;
    16.         public UnityAction onCrouch;
    17.         //
    18.         //
    19.         [Header("Movement")]
    20.         public float Speed = 7f;//
    21.         public float jumpForce = 7f;//20
    22.         public Rigidbody2D rb;
    23.         private BoxCollider2D playerCollider;
    24.         //
    25.         public LayerMask ground_Layer;
    26.         public Transform groundPoint;
    27.         public float groundRadius;
    28.         //
    29.         public Animator anim;
    30.         public Transform ceilPoint;
    31.         private bool ceiled;
    32.         public bool Grounded;
    33.         private bool is_grounded;//
    34.         //
    35.         [Header("Vectors")]
    36.         private Vector2 standColliderSize;//
    37.         private Vector2 standColliderOffset;//
    38.         private Vector2 crouchColliderSize;//
    39.         private Vector2 crouchColliderOffset;//
    40.         private Vector2 movement;//move
    41.         private Vector2 move_input;
    42.         //
    43.         [Header("Fall Below Level")]
    44.         public bool reset_when_fall = true;
    45.         public float fall_pos_y = -5f;
    46.         public float fall_damage_percent = 0.25f;
    47.         public float ground_raycast_dist = 0.1f;
    48.         //
    49.         [Header("Crouch")]
    50.         bool isCrouching = false;
    51.         bool crouch = false;
    52.      
    53.         public float crouch_coll_percent = 0.5f;//
    54.      
    55.         private bool is_jumping = false;
    56.         //
    57.      
    58.         float mX;
    59.         private bool Standing;
    60.         private bool Crouching;
    61.         //
    62.  
    63.         void Awake()
    64.         {
    65.             rb = GetComponent<Rigidbody2D>();
    66.             anim = GetComponent<Animator>();
    67.  
    68.          
    69.             playerCollider = GetComponent<BoxCollider2D>();
    70.             //
    71.             standColliderSize = playerCollider.size;//
    72.             standColliderOffset = playerCollider.offset;//
    73.  
    74.             crouchColliderSize = new Vector2(standColliderSize.x, standColliderSize.y * crouch_coll_percent);//
    75.             crouchColliderOffset = new Vector2(standColliderOffset.x, standColliderOffset.y * crouch_coll_percent);//
    76.  
    77.         }
    78.  
    79.         // For initialization
    80.         void Start()
    81.         {
    82.  
    83.         }
    84.  
    85.         void Update()
    86.         {
    87.             mX = Input.GetAxisRaw("Horizontal");
    88.             if (Input.GetButtonDown("Jump") && Is_Grounded())
    89.             {
    90.               Jump();
    91.             }
    92.  
    93.             {
    94.  
    95.                 bool crouch = Input.GetAxisRaw("Vertical") < -0.5f;
    96.                 if (crouch && !isCrouching) StartCrouch();
    97.                 else if (!crouch && isCrouching) EndCrouch();
    98.             }
    99.  
    100.          
    101.  
    102.             if (Mathf.Abs(mX) > 0.05f){
    103.                 anim.SetBool("isRunning", true);
    104.             }else{
    105.                 anim.SetBool("isRunning", false);
    106.             }if (mX > 0f){
    107.                 transform.localScale = new Vector3(1f, 1f, 1f);
    108.             }else if (mX < 0f){
    109.                 transform.localScale = new Vector3(-1f, 1f, 1f);
    110.             }
    111.             //
    112.             anim.SetBool("isGrounded", Is_Grounded());
    113.          
    114.         }
    115.  
    116.         void FixedUpdate()
    117.         {
    118.        
    119.  
    120.  
    121.             Vector2 movement = new Vector2(mX * Speed, rb.velocity.y);
    122.             Grounded = Physics2D.OverlapCircle(groundPoint.position, groundRadius, ground_Layer);
    123.             ceiled = Physics2D.OverlapCircle(ceilPoint.position, groundRadius, ground_Layer);
    124.  
    125.             rb.velocity = movement;
    126.  
    127.             StartCrouch();
    128.  
    129.         }
    130.  
    131.         void Jump()
    132.         {
    133.  
    134.             Vector2 movement = new Vector2(rb.velocity.x, jumpForce);
    135.  
    136.             rb.velocity = movement;
    137.         }
    138.  
    139.  
    140.         public Vector2 GetMove()
    141.         {
    142.             return movement;
    143.         }
    144.  
    145.         public bool IsJumping()
    146.         {
    147.             return is_jumping;
    148.         }
    149.  
    150.         private void StartCrouch()
    151.         {
    152.             if (crouch && !isCrouching)
    153.             {
    154.                 anim.SetBool("Crouch", true);
    155.                 playerCollider.size = crouchColliderSize;
    156.                 playerCollider.offset = crouchColliderOffset;
    157.  
    158.  
    159.             }
    160.         }
    161.  
    162.         private void EndCrouch()
    163.         {
    164.             if (!crouch && isCrouching)
    165.             {
    166.                 anim.SetBool("Crouch", false);
    167.                 playerCollider.size = standColliderSize;
    168.                 playerCollider.offset = standColliderOffset;
    169.  
    170.             }
    171.         }
    172.  
    173.         public bool Is_Grounded()
    174.         {
    175.             Collider2D groundCheck = Physics2D.OverlapCircle(groundPoint.position, groundRadius, ground_Layer);//feet//0.5f//Collider2D
    176.  
    177.             if (groundCheck != null)
    178.             {
    179.                 return true;
    180.             }
    181.  
    182.             return false;
    183.         }
    184.     }
    185. }
     
    Last edited: Apr 24, 2021
  13. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I was not confused by the partial script. The comments in my last response still apply.
     
  14. DTheChemist

    DTheChemist

    Joined:
    Jan 18, 2021
    Posts:
    115
    that was a mistake post. i dont know why my post came out looking like that with 17-22 looking that way. it was late and i was sleepy at that time. pardon that. but that script above you is the exact code from my file. but anyway i fixed that past post just now for viewing


    the script above your post is my actual real code from my File.
     
    Last edited: Apr 25, 2021