我最终采取了略微不同的方法 . 我没有更改 spring 的连接锚,而是将其保持不变,并将连接的主体设置为静态定位的原点变换 .
按下键时,我暂时将 spring 设置为0,然后更改柱塞对象的位置 . 未按下按键时,我将 spring 设置为较高值,以便弹回到定位点 .
为了处理约束问题,我使用了一个脚本,它将旋转和x / y位置设置为每帧的原始值,而不是使用刚体检查器上的选项(仅锁定世界空间轴上的位置) .
脚本现在看起来像这样:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlungerController : MonoBehaviour {
public float movement_increment_z;
public float max_movement_z;
public float spring_power;
private SpringJoint spring;
private Vector3 orig_anchor;
private Quaternion orig_rotation;
private float orig_pos_x, orig_pos_y;
private void Start() {
spring = GetComponent();
if (!spring) { throw new System.Exception("spring joint is needed"); };
orig_anchor = spring.connectedAnchor;
orig_rotation = transform.localRotation;
orig_pos_y = transform.localPosition.y;
orig_pos_x = transform.localPosition.x;
}
public void processPlungerInput (bool isKeyPressed) {
if (isKeyPressed) {
spring.spring = 0;
if (transform.localPosition.z < max_movement_z) {
transform.localPosition += new Vector3(0,0,movement_increment_z);
}
} else {
spring.spring = spring_power;
}
}
// preserve only z axis movement and no rotation at all.
private void FixedUpdate() {
transform.localRotation = orig_rotation;
transform.localPosition = new Vector3(orig_pos_x, orig_pos_y, transform.localPosition.z);
}
}