I have a project with just a rigidbody player Capsule, and a kinematic rigidbody Cube above it (which acts as a “Bar” for player to grab on to). I want Player to be able to fully swing around the bar if they ‘grab’ it and hold down movementkey W, which I am trying to achieve using a HingeJoint.
Right now if player Capsule jumps and collides with the Cube ‘bar’ above it, a HingeJoint is created. Then the player can hold down “W” to go forward on it, which should let them do a full rotation around the bar. Instead, it stops them about 80% of the way, which is undesired behavior. Gif of this:
Something weird of note is that if player simply presses W and releases quickly, the player is able to do a full rotation around the bar. So, there is something me holding W that makes it stop rotating at that point.
The project only has 2 scripts in it, which are both on the rigidbody player Capsule:
Capsule’s movement controller:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Smoothy : MonoBehaviour
{
Rigidbody _rigidbody = null;
public float horizontalInput;
public float verticalInput;
public Vector3 moveDirection;
public Vector3 moveDirectionRaw;
[SerializeField] float _movementMultiplier = 30.0f;
[SerializeField] Vector3 _playerCalculatedForce = Vector3.zero;
private void Awake()
{
_rigidbody = GetComponent<Rigidbody>();
}
public void Update()
{
horizontalInput = Input.GetAxis("Horizontal");
verticalInput = Input.GetAxis("Vertical");
moveDirection = new Vector3(horizontalInput, 0.0f, verticalInput).normalized;
moveDirectionRaw = new Vector3(Input.GetAxisRaw("Horizontal"), 0.0f, Input.GetAxisRaw("Vertical")).normalized;
if (Input.GetKeyDown(KeyCode.Space))
{
_rigidbody.AddForce(Vector3.up * 15f, ForceMode.Impulse);
}
}
private void FixedUpdate()
{
_playerCalculatedForce = moveDirection * _movementMultiplier;
_playerCalculatedForce *= _rigidbody.mass;
_rigidbody.AddForce(_playerCalculatedForce, ForceMode.Force);
}
}
and the HingeJoint creation code:
using System.Collections;
using Unity.VisualScripting;
using UnityEngine;
public class BarLogic : MonoBehaviour
{
public bool isSwinging = false;
public bool isColliding = false;
public GameObject cube;
public GameObject smoothPlayer;
RigidbodyConstraints originalConstraints;
RigidbodyConstraints barConstraints;
private void Awake()
{
originalConstraints = GetComponent<Rigidbody>().constraints;
barConstraints = RigidbodyConstraints.None;
}
private void OnTriggerEnter(Collider other)
{
isColliding = true;
print("Collision!");
if (other.CompareTag("Bar"))
{
if (!this.GetComponent<HingeJoint>() && !isSwinging)
{
//Create HingeJoint between bar and Player
isSwinging = true;
this.transform.rotation = Quaternion.Euler(Vector3.zero);
this.AddComponent<HingeJoint>();
GetComponent<Rigidbody>().constraints = barConstraints;
this.GetComponent<HingeJoint>().autoConfigureConnectedAnchor = false;
GetComponent<Rigidbody>().velocity = Vector3.zero;
this.GetComponent<HingeJoint>().anchor = new Vector3(-GetComponent<Rigidbody>().position.x, 2f, 0f);
this.GetComponent<HingeJoint>().connectedBody = other.GetComponent<Rigidbody>();
}
}
StartCoroutine(Reset());
}
IEnumerator Reset()
{
yield return new WaitForEndOfFrame();
isColliding = false;
}
private void Update()
{
//Player releases bar
if (Input.GetKeyDown(KeyCode.R))
{
isSwinging = false;
Destroy(this.GetComponent<HingeJoint>());
GetComponent<Rigidbody>().constraints = originalConstraints;
}
}
}
The code above only works if the cube ‘Bar’ has the tag “Bar” on it.
Any idea what might be causing this? Thank you!
this pic is just to show the HingeJoint settings: