Здравствуйте!
Простите за глупый вопрос. Есть игра про перемещение в одной плоскости по экрану, нужна кошка-крюк. Сейчас это реализовано так: при нажатии кнопки Z луч находит точку соприкосновения со стеной и к ней привязывается с помощью hinge joint. Расстояние между игроком и точкой соприкосновения (segment[0]) сохраняется. При повторном нажатии джойнт ломается, из режима виса выходим. Эта часть кода работает нормально (ShootHook()).
Но нужно, чтобы в режиме виса на джойнте "цепь", на которой игрок висит, надламывалась при столкновении с препятствием (ChainBreak()). В апдейте луч рассчитывает расстояние между игроком и точкой соприкосновения с препятствиями (segment[1]), и если оно меньше segment[0], то старый джойнт уничтожается, создается новый. Но в сцене игрок при этом сравнении создает джойнт внутри себя и застревает на месте, а нажатие на Z перестает давать хоть какие-то результаты.
Итак, два вопроса: почему якорь создается внутри игрока и как все же лучше реализовать надлом цепи?
Спасибо за внимание.
public class HookBehaviour : MonoBehaviour
{
public GameObject origin; // начало луча
Ray ray = new Ray(); // луч из верхушки ракеты прямо по оси Y
RaycastHit hit; // точка попадания крюком в стену
Vector3[] segment = new Vector3[10]; // отрезки цепи
public bool hooked = false; // переключатель виса на крюке
public bool segm = false; // переключатель надлома цепи
HingeJoint joint; // соединение ракеты с точкой попадания
void Start()
{
origin = GameObject.Find("RayOrigin");
}
void Update()
{
ray.origin = origin.transform.position;
ray.direction = transform.up;
if (!hooked) Debug.DrawRay(ray.origin, ray.direction*100, Color.yellow);
else Debug.DrawRay(ray.origin, ray.direction*100, Color.green);
ShootHook();
ChainBreak();
}
void ShootHook()
{
if (Input.GetKeyDown(KeyCode.Z))
{
if (!hooked && Physics.Raycast(ray, out hit) && hit.collider.tag == "Hooked")
{
segment[0] = hit.point - ray.origin;
joint = gameObject.AddComponent<HingeJoint>();
joint = GetComponent<HingeJoint>();
joint.anchor = origin.transform.InverseTransformPoint(hit.point)*2.3f;
joint.axis = new Vector3(0,0,1);
hooked = !hooked;
}
else if (hooked)
{
hooked = !hooked;
Destroy(joint);
}
}
}
void ChainBreak() //надлом цепи при столкновении
{
if (Physics.Raycast(ray, out hit) && hooked)
{
segment[1] = hit.point - ray.origin;
if (segment[1].sqrMagnitude < segment[0].sqrMagnitude && !segm)
{
segm = !segm;
Destroy(joint);
joint = gameObject.AddComponent<HingeJoint>();
joint = GetComponent<HingeJoint>();
joint.anchor = origin.transform.InverseTransformPoint(hit.point)*2.3f;
joint.axis = new Vector3(0,0,1);
}
else return;
}
}
}