- Home /
Hint Joint like a rope have weird behavior
i am beginer and i have cube in air with element attached him with no rotation like a node, i have a couple cubes for simulate rope with hint joint. i have clicking right click at a cube and spawn rope from direction player to node and attaching last element rope with player and this working very vell. when player doesnt have velocity, and blocked rotation on rigidbody elements. but sometimes if i have been jumped and try to spawn rope in moving elements rope have weird rotations, and sometimes cubes rotation blocks. how i could work with rotations rope or i dont know, any advice? thanks. p.s sorry for bad english.
private void CheckMouseActivity() { float x = Input.mousePosition.x; float y = Input.mousePosition.y; float z = Input.mousePosition.z;
Vector3 point = new Vector3(x, y, z);
if (Input.GetMouseButton(1) && !m_ropeIsActive)
{
m_aiming = true;
Ray ray = Camera.main.ScreenPointToRay(point);
GenerateRope(ray);
}
if(Input.GetButton("Jump") && m_ropeIsActive)
{
for (int i = 0; i < rope.Count; i++)
{
DestroyImmediate(rope[i]);
//rope[i].active = false;
}
playerRb.AddForce(new Vector3(6f, 6f), ForceMode.Impulse); //TODO переделать, добавить импульс в зависимости от скорости и направления
m_ropeIsActive = false;
m_hooked = false;
}
//check bounds in playing area
}
void GenerateRope(Ray ray)
{
layerMask = ~layerMask;
if (Physics.Raycast(ray, out RaycastHit hit, 10f, layerMask))
{
if (hit.transform.CompareTag("node") && !m_ropeIsActive)
{
activeHook = hit.transform.gameObject;
m_CanMove = false;
Vector3 hitPos = hit.transform.position;
Transform hook = hit.transform.GetChild(0);
Vector3 hookInverseNormal = hook.up * -1f;
Rigidbody previosRb = hit.transform.GetChild(0).GetComponent<Rigidbody>();//hook
Vector3 distanceFromNode = transform.position - hit.point;
int distance = (int)distanceFromNode.magnitude;
BoxCollider link = linkPrefub.GetComponent<BoxCollider>();//(int)link.size.magnitude / 2;
int length = (int)((distance - 1f) / sizeCell);
float ropeLength = sizeCell * 10f;
if (length < minLength)
{
length = minLength;
}
//else if (length > ropeLength)
//{
// length = (int)ropeLength * 2;
//}
for (int i = 1; i < length - 1; i++)
{
var t = sizeCell * i; //позиция под новый куб
Vector3 dirToPlayer = transform.position - hit.transform.position;//направление до игрока,
Vector3 newPos = dirToPlayer.normalized * t;
GameObject toInstantiate = Instantiate(linkPrefub, hit.transform.position + new Vector3(newPos.x, -t, default), Quaternion.identity, hit.transform);
rope.Add(toInstantiate);
HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();
if (i == 1)
{
joint.autoConfigureConnectedAnchor = true;
}
else
{
joint.autoConfigureConnectedAnchor = false;
joint.connectedAnchor = new Vector3(0f, -0.4f);
}
joint.enableCollision = false;
joint.connectedBody = previosRb;
previosRb = toInstantiate.GetComponent<Rigidbody>();
}
m_ropeIsActive = true;
m_hooked = true;
m_CanMove = true;
}
}
else
{
//what to do if not did hit
}
}
void FixedUpdate(){
if (m_ropeIsActive)
{
if (m_hooked && activeHook)
{
//TODO крутить нод хука чтобы выглядило красиво
}
if (rope.Count != 0)
{
Rigidbody lastElementRope = rope[rope.Count - 1].GetComponent<Rigidbody>();
if (lastElementRope)
{
HingeJoint joint = GetComponent<HingeJoint>();
//joint.autoConfigureConnectedAnchor = false;
//joint.connectedBody = lastElementRope;
//joint.anchor = Vector2.zero;
//joint.connectedAnchor = new Vector2(0f, -0.4f);
}
}
}
}
can put code from github with project I experimented here trying to achieve obedience, but I am convinced that this is the wrong direction, I just do not know how to work with rotations, I got confused
if (i == 1)
{
joint.autoConfigureConnectedAnchor = true;
}
else
{
joint.autoConfigureConnectedAnchor = false;
joint.connectedAnchor = new Vector3(0f, -0.4f);
}
https://github.com/Heges/first-2d-platformer/tree/main/2D-platformer
Answer by shyxiaolong · Apr 23, 2021 at 08:09 AM
i am not sure but
void GenerateRope(Ray ray)
{
layerMask = ~layerMask;
if (Physics.Raycast(ray, out RaycastHit hit, 10f, layerMask))
{
Vector3 direction = transform.position - hit.transform.position;
if (direction.magnitude <= sizeOfRope)
{
if (hit.transform.CompareTag("node") && !m_ropeIsActive)
{
activeHook = hit.transform.gameObject;
m_CanMove = false;
Transform hook = hit.transform.GetChild(0);
Vector3 hookInverseNormal = hook.up * -1f;
float dot = Vector3.Dot(hookInverseNormal, ray.direction.normalized);
Debug.Log(dot);
Quaternion rotation = hit.transform.rotation;
Rigidbody previosRb = hit.transform.GetChild(0).GetComponent<Rigidbody>();//hook
Vector3 distanceFromNode = transform.position - hit.point;
int distance = (int)distanceFromNode.magnitude;
BoxCollider link = linkPrefub.GetComponent<BoxCollider>();//(int)link.size.magnitude / 2;
int length = (int)((distance - 1f) / sizeCell); //size of cell rope -1f размер игрока
float ropeLength = sizeCell * sizeOfRope;
if (length < minLength)
{
length = minLength;
}
//else if (length > ropeLength) // и слишком длинных
//{
// length = (int)ropeLength * 2;
//}
for (int i = 1; i < length - 1; i++)
{
var t = sizeCell * i; //позиция под новый куб
Vector3 dirToPlayer = transform.position - hit.transform.position;//направление до игрока,
Vector3 newPos = dirToPlayer.normalized * t;
GameObject toInstantiate = Instantiate(linkPrefub, hit.transform.position + new Vector3(newPos.x, -t, default), Quaternion.identity, hit.transform);
rope.Add(toInstantiate);
HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();
joint.anchor = Vector2.up;
joint.connectedAnchor = new Vector2(0f, -0.4f);
joint.connectedBody = previosRb;
previosRb = toInstantiate.GetComponent<Rigidbody>();
}
m_ropeIsActive = true;
m_hooked = true;
}
}
else
{
//what to do if not did hit
}
}
it is still don't work very well but.like my problem is solved. limited the distance from which the rope can be summoned, and as it turned out, when autogenerating parts of the rope, the Hint Joint defaults to its values such as AutoAnchor. disabling them during creation, it seems that everything seems to work as it should
HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();
joint.anchor = Vector2.up;
joint.connectedAnchor = new Vector2(0f, -0.4f);
joint.connectedBody = previosRb;
previosRb = toInstantiate.GetComponent<Rigidbody>();