JamesB 发表于 2022-2-18 10:06

10行代码在Unity中实现一条绳子

0.效果



1.代码

using UnityEngine;

public class Rope : MonoBehaviour
{
    private Transform[] ropeTransforms;
    private float ropeLength = 1;

    private float[] x;
    private float[] y;

    private void Start()
    {
      x = new float;
      y = new float;
    }

    private void Update()
    {
      DragRope(0, Camera.main.ScreenToWorldPoint(Input.mousePosition).x, Camera.main.ScreenToWorldPoint(Input.mousePosition).y);

      for (int i = 0; i < ropeTransforms.Length - 1; i++)
      {
            DragRope(i + 1, x, y);
      }
    }

    private void DragRope(int index, float x, float y)
    {
      //使用反正切,计算出鼠标位置与绳子原点的弧度
      float dx = x - this.x;
      float dy = y - this.y;
      float rad = Mathf.Atan2(dy, dx);

      //关键的每帧原理:
      //每帧根据此弧度的正弦和余弦偏移出绳子应该出现的位置。
      this.x = x - Mathf.Cos(rad) * ropeLength;
      this.y = y - Mathf.Sin(rad) * ropeLength;

      //将弧度转换为角度,为整条绳子的各个子线段赋值位置与旋转
      float deg = rad * Mathf.Rad2Deg;
      ropeTransforms.position = new Vector2(this.x, this.y);
      ropeTransforms.eulerAngles = new Vector3(0, 0, deg);
    }
}
2.几个要点


[*]Atan2:不同于Atan,它会正确处理象限和邻边为0的情况,我们首先用此函数计算出鼠标位置和绳子之间的弧度。
[*]Cos与Sin:正弦波与余弦波。每帧根据上边得到的弧度的正弦和余弦偏移出绳子应该出现的位置。这是实现绳子的每帧关键原理,我们从下方的动图可以看到,弧度从0开始,余弦在1/0/-1/0/1周期内运动,正弦在0/1/0/-1/0周期内运动。例如鼠标位置的x在2,那么 2 - (1 * 线段长度) = 1,所以线段的x位置应该来到1,余弦的最大值永远为1。又比如鼠标y位置在2,那么 2 - (1 * 线段长度) = 1,正弦的最大值也为1,所以线段的y位置应该来到1,正弦为1时余弦的值为0,所以x轴没有任何偏移。



[*]上面是首条线段和鼠标位置的计算逻辑,将10条线段形成一个数组,首尾相连,每帧执行相同的逻辑,就成为了一条绳子。
[*]最后,为了与Unity同步,将弧度转换为角度,赋值给Transform相关属性。
3.源码与Demo

为了让感兴趣的同学更加方便,在此提供源码与Demo,将文件导入Unity即可运行。

Doris232 发表于 2022-2-18 10:16

十呢?

Arzie100 发表于 2022-2-18 10:26

好耶

maltadirk 发表于 2022-2-18 10:31

[赞同]

lvfulin555 发表于 2022-6-8 10:18

哪里下载源码

lvfulin555 发表于 2022-6-8 10:21

题主,没有demo可以下载啊
页: [1]
查看完整版本: 10行代码在Unity中实现一条绳子