问题描述
我是一个初学者,我有一个立方体在空气中,元素附着在他身上,没有像节点一样旋转,我有几个立方体用于模拟带提示关节的绳索。我在立方体上单击鼠标右键,然后从方向玩家到节点生成绳索,并将最后一个元素绳索与玩家相连,这非常有效。当玩家没有速度,并且在刚体元素上阻止旋转时。但有时如果我被跳跃并尝试在移动元素中生成绳索,绳索会出现奇怪的旋转,有时会出现立方体旋转块。我怎么能用旋转绳或我不知道,有什么建议吗?谢谢。
PS:抱歉我的英语不好。
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);
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 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);
}
}
}
}
可以把github上的代码和项目一起放。
我在这里尝试实现服从,但我确信这是错误的方向,我只是不知道如何使用轮换,我感到困惑
if (i == 1)
{
joint.autoConfigureConnectedAnchor = true;
}
else
{
joint.autoConfigureConnectedAnchor = false;
joint.connectedAnchor = new Vector3(0f,-0.4f);
}
GitHub https://github.com/Heges/first-2d-platformer/tree/main/2D-platformer
解决方法
我不确定但是
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
}
}
它仍然不能很好地工作,但是我的问题已经解决了。 限制了可以召唤绳索的距离,事实证明,当自动生成绳索的某些部分时,提示关节默认为其值,例如 AutoAnchor。在创建过程中禁用它们,似乎一切都正常
HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();
joint.anchor = Vector2.up;
joint.connectedAnchor = new Vector2(0f,-0.4f);
joint.connectedBody = previosRb;
previosRb = toInstantiate.GetComponent<Rigidbody>();