Unity中绑定HingeJoint2D的旋转物体碰撞后收缩实现问题
问题描述
我有一个绑定在HingeJoint2D(黑色铰链关节)上可绕其旋转的橙色物体。当检测到与其他物体发生碰撞时(红色点位置),需要将该物体从铰链到碰撞点的部分收缩,同时要保持物体与铰链的连接以及自身宽度。
[示意图:橙色物体通过黑色铰链关节连接,红色点为碰撞位置]
[层级结构示意图:橙色物体作为子物体嵌套在父物体下]
现有尝试代码
碰撞检测逻辑
void OnCollisionEnter2D(Collision2D collision) { GameObject obj = collision.gameObject; Vector3 endPos =collision.contacts[0].point; float scaleX = Vector3.Distance(new Vector3(startPos.x, 0, 0), new Vector3(endPos.x, 0, 0)); float scaleY = Vector3.Distance(new Vector3(0, startPos.y, 0), new Vector3(0, endPos.y, 0)); Vector3 newScale = new Vector3(scaleX,scaleY, 1); obj.transform.parent.transform.localScale = obj.transform.TransformPoint(newScale); }
铰链位置初始化
startPos = GameObject.Find("hair").GetComponent<HingeJoint2D>().transform.position;
我将物体嵌套在父物体中并对父物体缩放,期望以此保持物体原位,但始终无法让物体保持正确位置和尺寸,请问该如何正确实现?
解决方案
核心问题在于你直接拆分XY轴计算距离,还错误用TransformPoint转换缩放值,导致缩放逻辑完全偏离预期。要实现从铰链到碰撞点收缩、维持宽度、不脱离铰链的效果,按以下步骤调整:
1. 先理清楚层级与轴心
保持父-子物体结构,但必须满足:
- 父物体的轴心点完全对齐铰链关节的位置(父物体position等于铰链的startPos)
- 橙色子物体的初始轴心在父物体的轴心处(也就是铰链位置),子物体的初始长度是从铰链到末端的原始长度
2. 修正碰撞时的缩放逻辑
不需要拆分XY轴计算,直接算铰链到碰撞点的直线距离,再基于这个距离调整父物体的长度方向缩放(宽度方向保持1不变):
// 提前缓存关键组件,避免运行时重复查找 private Transform parentTransform; private Transform hingeTransform; private float originalLength; // 橙色物体的初始长度 void Start() { // 找到铰链关节的Transform hingeTransform = GameObject.Find("hair").GetComponent<HingeJoint2D>().transform; // 获取父物体Transform(假设脚本挂在橙色子物体上) parentTransform = transform.parent; // 记录物体初始长度:取Sprite的实际宽度(根据你的物体方向调整X/Y) originalLength = GetComponent<SpriteRenderer>().bounds.size.x; // 强制父物体位置与铰链对齐,确保缩放时锚点正确 parentTransform.position = hingeTransform.position; } void OnCollisionEnter2D(Collision2D collision) { // 获取碰撞点的世界坐标 Vector3 collisionPos = collision.contacts[0].point; // 计算铰链到碰撞点的直线距离 float collisionDistance = Vector3.Distance(hingeTransform.position, collisionPos); // 计算缩放比例:碰撞距离/初始长度(加最小值避免缩到0) float lengthScale = Mathf.Max(collisionDistance / originalLength, 0.01f); // 只缩放长度方向(这里假设长度沿X轴,若沿Y轴就改localScale.y),宽度保持1 parentTransform.localScale = new Vector3(lengthScale, 1f, 1f); }
3. 几个关键注意事项
- 如果你的物体长度是沿Y轴延伸的,把代码里的
localScale.x改成localScale.y即可 - 可以直接把父物体设为铰链的子物体,这样父物体会自动继承铰链的旋转,不用额外处理旋转同步
- 绝对不要用
TransformPoint处理缩放值,localScale只需要传入比例系数,和坐标转换无关 - 如果碰撞检测触发不稳定,可改用
OnTriggerEnter2D,记得给碰撞体勾选「Is Trigger」
内容的提问来源于stack exchange,提问作者flowerProgrammer
相关产品推荐
相关产品推荐

