关于Unity中关节的使用(二)
导入
1.创建工程
2.导入joint_scene.unitypackage
3.运行发现机械爪子摇来摇去,因为line节点下面的子节点之间相互碰撞带动的关系
4.为了消除这种乱摇,我们在右上角添加一个catch层,把line节点整个设置成catch层,然后在Edit---->Project Settings---->Physics---->碰撞矩阵里面设置catch层和catch层不碰撞
5.重新运行,机械爪子正常
原理
机械爪子正常之后,发生它上下来回运动,慢慢停下来,但是它的子节点之间又不是弹簧关节,而是固定关节,确实是比较神奇的一个点。
这个神奇的点是这样实现的,首先我们要把几个物体彼此连在一起,要有陷入的那种连接,然后彼此之间的连接都设置为固定关节,把质量调大一点10,最上面那个物体固定坐标,运行,就会有弹簧的效果。
代码解释
Line.position = Line.position + offsetPosition * 1.2f * Time.deltaTime;
速度x时间=距离
距离x方向=坐标偏移量
1.2f是速度
Time.deltaTime是时间
offsetPosition是方向
控制机械爪子的脚本JointControl是挂载在MainCatcher节点下的
JointControl内容是:
using UnityEngine; using System.Collections; using UnityEngine.UI; using UnityEngine.EventSystems; public class JointControl : MonoBehaviour { public Transform[] claws0; //爪子一级支节 public Transform[] claws1; //爪子二级支节 public Transform[] claws2; //爪子三级支节 private float angle; //爪子打开或合拢的角度 private float offset; //角度步长 public Transform Line; //绳子对象 private Vector3 offsetPosition; //绳子移动步长 private bool isMove; //绳子移动标志位 void Start () { angle = 0; //默认爪子为开启 } void Update () { if (angle + offset >= 0 && angle + offset < 20) { //爪子可进行操作 for (int i = 0; i < 4; i++) { //进行开启或合拢 claws0[i].Rotate(Vector3.left, offset * 2.5f, Space.Self); //三级支节分别进行操作 claws1[i].Rotate(Vector3.left, offset * 0.2f, Space.Self); claws2[i].Rotate(Vector3.left, offset * 1.8f, Space.Self); } angle += offset; } if (isMove) { //移动绳子 // Line.position = Vector3.Lerp(Line.position, Line.position + offsetPosition * 1.2f, Time.deltaTime * 1.2f); Line.position = Line.position + offsetPosition * 1.2f * Time.deltaTime; } this.ctrl_update(); } public void ControlCatcher(int i) { //开启或合拢爪子监听方法 offset = i == 1 ? -0.2f : 0.2f; } public void MoveCatcher(int i) { //移动绳子监听方法 Vector3[] poses = new Vector3[6] {Vector3.forward, Vector3.back, Vector3.left, Vector3.right, Vector3.up, Vector3.down}; offsetPosition = poses[i]; isMove = true; } public void MoveButtonUp() { // 按钮抬起监听方法 isMove = false; } void ctrl_update() { if (Input.GetKeyDown(KeyCode.UpArrow)) { this.MoveCatcher(4); } else if (Input.GetKeyDown(KeyCode.DownArrow)) { this.MoveCatcher(5); } else if (Input.GetKeyDown(KeyCode.LeftArrow)) { this.MoveCatcher(2); } else if (Input.GetKeyDown(KeyCode.RightArrow)) { this.MoveCatcher(3); } else if (Input.GetKeyDown(KeyCode.W)) { this.MoveCatcher(0); } else if (Input.GetKeyDown(KeyCode.S)) { this.MoveCatcher(1); } else if (Input.GetKeyUp(KeyCode.UpArrow) || Input.GetKeyUp(KeyCode.DownArrow) || Input.GetKeyUp(KeyCode.LeftArrow) || Input.GetKeyUp(KeyCode.RightArrow) || Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.S)) { this.MoveButtonUp(); } else if (Input.GetKeyDown(KeyCode.Space)) { this.ControlCatcher(1); } else if (Input.GetKeyDown(KeyCode.P)) { this.ControlCatcher(0); } } }
调试小技巧:
想要判断某个节点是不是被脚本控制运行的,可以在运行的过程中关闭脚本,看物体是否正常运动,如果是则和该脚本无关。