How To Code Ledge Grabbing for your Unity Game

Поделиться
HTML-код
  • Опубликовано: 18 апр 2023
  • Ledge Grabbing is a great way to make your game feel a little easier and more satisfying for your players. but how do you make it? Well, today, that's exactly what i'm going to show you!
    Get the project files here : / ledge-grabbing-81590751
    Join the discord for any help you need! : / discord
    support the channel and development over on patreon : / thegamingcaves
  • НаукаНаука

Комментарии • 20

  • @KawaiiProductions
    @KawaiiProductions 3 месяца назад

    Does this work for the Third Person template as well?

  • @fear-the-phantom
    @fear-the-phantom 4 месяца назад +1

    Good vid, gonna try it out for my Banjo-Kazooie style prototype

  • @elpela6975
    @elpela6975 3 месяца назад

    Hello, my problem is that sometimes it grabs a higher side and other times a lower side of the box.

  • @apoorvpandey3D
    @apoorvpandey3D 11 месяцев назад

    I use godot and this was very helpful to me. Thank you!

  • @GENNAROTHEBEST94
    @GENNAROTHEBEST94 5 месяцев назад

    is this can be use in the 2d context?

    • @thegamedevcave
      @thegamedevcave  5 месяцев назад +1

      Should be yeah, might need a 2d specific verion of line cast for it though, not sure

  • @RacTeamGames
    @RacTeamGames Год назад

    how can you add thr vector3s and i cant

    • @thegamedevcave
      @thegamedevcave  Год назад

      you're likely typing vector3 instead of Vector3.

    • @RacTeamGames
      @RacTeamGames Год назад

      @@thegamedevcave Im not its just not working

    • @thegamedevcave
      @thegamedevcave  Год назад

      @@RacTeamGames if you're having trouble with the basics like adding a variable I suggest you first take a step back and go through some of my unity basics videos ruclips.net/p/PLoReGgpfex3xS-zXTujxo_flRkLBgxxd3

  • @LaughingMajora
    @LaughingMajora 7 месяцев назад +1

    Hello! :D
    i have a problem, can you help me, please?
    my character doesnt keep hanging the edge :C im using a raycast jump
    this is my jump code
    do you need my entire code?
    private void PlayerJump()
    {
    if (Input.GetButtonDown("Jump") && isGrounded)
    {
    if(hanging)
    {
    _rb.useGravity = true;
    hanging = false;
    _rb.AddForce(Vector3.up * Jump, ForceMode.Impulse);
    StartCoroutine(EnableCantMove(0.25f));
    }
    else
    {
    _rb.AddForce(Vector3.up * Jump, ForceMode.Impulse);
    }
    }
    }

    • @thegamedevcave
      @thegamedevcave  7 месяцев назад

      Seems like you’re setting gravity to true when your character is hanging, it should be set to false and then back to true when the hanging stops

    • @LaughingMajora
      @LaughingMajora 7 месяцев назад

      @@thegamedevcave im kinda lost :'C
      can you help me, please?
      this is my full code
      public class RbController : MonoBehaviour
      {
      [SerializeField]
      private Rigidbody _rb;
      [SerializeField]
      private Camera _camera;
      [SerializeField]
      private float _rotation;
      [SerializeField]
      float Jump = 5f;
      public float movementSpeed;
      public float raycastDistance = 0.2f;
      public float swingDamping = 0.95f;
      public bool isJump = false;
      public bool isGrounded = false;
      public bool hanging;
      bool canMove = true;
      public Transform currentAnchor;
      private bool isAtach;
      private SpringJoint _springJoint;
      public LayerMask groundLayer;
      // Start is called before the first frame update
      void Start()
      {
      _rb = GetComponent();
      }
      // Update is called once per frame
      void Update()
      {
      PlayerMovement();
      PlayerJump();
      Anclar();
      LedgeGrab();
      RaycastHit hit;
      if (Physics.Raycast(transform.position, Vector3.down, out hit, raycastDistance, groundLayer))
      {
      isGrounded = true;
      }
      else
      {
      isGrounded = false;
      }
      if (isAtach)
      {
      ApplySwingDamping();
      }
      }
      private void PlayerMovement()
      {
      if (canMove)
      {
      float Hor = Input.GetAxis("Horizontal");
      float Ver = Input.GetAxis("Vertical");
      Vector3 velocity = Vector3.zero;
      Vector3 direction = Quaternion.Euler(0, _camera.transform.eulerAngles.y, 0) * new Vector3(Hor, 0, Ver);
      Vector3 movementDirection = direction.normalized;
      if (Hor != 0 || Ver != 0)
      {
      velocity = direction * movementSpeed;
      if (movementDirection != Vector3.zero)
      {
      Quaternion desiredRotation = Quaternion.LookRotation(movementDirection, Vector3.up);
      transform.rotation = Quaternion.Slerp(transform.rotation, desiredRotation, _rotation * Time.deltaTime);
      }
      }
      velocity.y = _rb.velocity.y;
      _rb.velocity = velocity;
      }

      }
      IEnumerator EnableCanMove(float waitTime)
      {
      yield return new WaitForSeconds(waitTime);
      canMove = true;
      }
      private void PlayerJump()
      {
      if (Input.GetButtonDown("Jump") && isGrounded)
      {
      if(hanging)
      {
      _rb.useGravity = true;
      hanging = false;
      _rb.AddForce(Vector3.up * Jump, ForceMode.Impulse);
      StartCoroutine(EnableCanMove(0.25f));
      }
      else
      {
      _rb.AddForce(Vector3.up * Jump, ForceMode.Impulse);
      }
      }
      }
      void Anclar()
      {
      if (Input.GetButtonDown("Sujetarse") && currentAnchor != null)
      {
      isAtach = true;
      _rb.useGravity = false;
      _springJoint = gameObject.AddComponent();
      _springJoint.connectedBody = currentAnchor.GetComponent();
      _springJoint.autoConfigureConnectedAnchor = false;
      _springJoint.connectedAnchor = new Vector3(0f, -7f, 0f);
      _springJoint.spring = 40.5f;
      _springJoint.damper = 10f;
      _springJoint.massScale = 2f;
      }
      else if (Input.GetButtonDown("Sujetarse") && isAtach)
      {
      isAtach = false;
      //_rb.useGravity = true;
      Destroy(_springJoint);
      }
      }
      void ApplySwingDamping()
      {
      _rb.velocity *= swingDamping;
      }
      void LedgeGrab()
      {
      if (_rb.velocity.y < 0 && !hanging)
      {
      RaycastHit downhit;
      Vector3 lineDownStart = (transform.position + Vector3.up * 1.5f) + transform.forward;
      Vector3 lineDownEnd = (transform.position + Vector3.up * 0.7f) + transform.forward;
      Physics.Linecast(lineDownStart,lineDownEnd,out downhit, LayerMask.GetMask("Ground"));
      Debug.DrawLine(lineDownStart,lineDownEnd);
      if(downhit.collider != null)
      {
      RaycastHit forwardHit;
      Vector3 lineForwardStart = new Vector3 (transform.position.x, downhit.point.y-0.1f,transform.position.z);
      Vector3 lineForwardEnd = new Vector3 (transform.position.x, downhit.point.y-0.1f, transform.position.z) + transform.forward;
      Physics.Linecast(lineForwardStart, lineForwardEnd, out forwardHit, LayerMask.GetMask("Ground"));
      Debug.DrawLine(lineForwardStart, lineForwardEnd);
      if (forwardHit.collider != null)
      {
      _rb.useGravity = false;
      _rb.velocity = Vector3.zero;
      hanging = true;
      Vector3 hangPos = new Vector3(forwardHit.point.x, downhit.point.y, forwardHit.point.z);
      Vector3 offset = transform.forward * -0.1f + transform.up * -1f;
      hangPos += offset;
      transform.position = hangPos;
      transform.forward = -forwardHit.normal;
      canMove = false;
      }
      }
      }
      }
      }

  • @TheDigitalLenny
    @TheDigitalLenny Год назад

    Hello I been having some issues with my fwdRayCast and tried using a debug to see why my player wasn't finding the ledge. It seems to only register the Down hit raycast are there any solutions to this problem?
    //Foward Cast
    if (downHit.collider != null)
    {
    Debug.Log("DOWN HIT");
    lineFwdStart = new Vector3(transform.position.x + downHit.point.y - 0.1f, transform.position.z);
    lineFwdEnd = new Vector3(transform.position.x + downHit.point.y - 0.1f, transform.position.z) + transform.forward;
    Physics.Linecast(lineFwdStart, lineFwdEnd, out forwardHit, hangMask);
    Debug.DrawLine(lineFwdStart, lineFwdEnd, Color.red);
    if (forwardHit.collider != null)
    {
    Debug.Log("FWD HIT");
    rb.useGravity = false;
    rb.velocity = Vector3.zero;
    isHanging = true;
    //Hang animation
    Vector3 hangingPos = new Vector3(forwardHit.point.x, downHit.point.y, forwardHit.point.z);
    Vector3 offset = transform.forward * -0.1f + transform.up * -1f;
    hangingPos += offset;
    transform.position = hangingPos;
    transform.forward = -forwardHit.normal;
    }
    }

    • @thegamedevcave
      @thegamedevcave  Год назад +1

      i'm thinking it might be this line
      lineFwdEnd = new Vector3(transform.position.x + downHit.point.y - 0.1f, transform.position.z) + transform.forward;
      you're adding transform.forward to it, which is correct but now your line cast is only casting a really short distance in front of the character, just 1 single unit. you want to probably muliply that transform.forward by some number (i'd suggest making it a variable to test out what number works best)

    • @TheDigitalLenny
      @TheDigitalLenny Год назад

      @@thegamedevcave Thank you the player is starting to react! to the hanging but is off and sometimes will be hanging about the wall haha. I also saw i had an error in my code
      i had: lineFwdEnd = new Vector3(transform.position.x + downHit.point.y - 0.1f, transform.position.z) + transform.forward;
      istead of: lineFwdEnd = new Vector3(transform.position.x, downHit.point.y - 0.1f, transform.position.z) + transform.forward;
      🤦‍♂😂

    • @elpela6975
      @elpela6975 3 месяца назад

      @@TheDigitalLenny try do this in the last part of de function:
      if (fwdHit.collider != null)
      {
      Invoke(nameof(NewPosHang), 0.01f);
      }
      }
      }
      }
      public void NewPosHang()
      {
      rb.useGravity = false;
      rb.velocity = Vector3.zero;
      hanging = true;
      Vector3 hangPos = new Vector3(fwdHit.point.x, downHit.point.y, fwdHit.point.z);
      Vector3 offset = transform.forward * -0.1f + transform.up * -1f;
      hangPos += offset;
      transform.position = hangPos;
      transform.forward = -fwdHit.normal;

      }