[Unity Tips] Unity2d プラットフォームでオタネニンジンの釣り竿エフェクトを作成します (git ソースコード付き)

序文

今日は 2D 釣り竿エフェクトを作成します。最初に完成品のエフェクトを見てみましょう。
ここに画像の説明を挿入

素材

釣り竿
ここに画像の説明を挿入

始める

まず 2D URP プロジェクトを作成し、空のオブジェクトを釣り竿として作成し、開始点と終了点として 2 つのサブオブジェクトを作成します。 構成レベルは次のとおりです。 釣り竿と釣り糸 + Line Renderer 新しい釣り竿マテリアル
ベジェ
ここに画像の説明を挿入
曲線
ここに画像の説明を挿入
基本
ここに画像の説明を挿入
クラス

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 贝塞尔曲线 动态.
/// </summary>
public class BezierHelper{
    
    

 // 一阶贝塞尔曲线,参数P0、P1、t对应上方原理内的一阶曲线参数.
    public static Vector3 Bezier(Vector3 p0, Vector3 p1, float t)
    {
    
    
        return (1 - t) * p0 + t * p1;
    }

    // 二阶贝塞尔曲线,参数对应上方原理内的二阶曲线参数.
    Vector3 Bezier(Vector3 p0, Vector3 p1, Vector3 p2, float t)
    {
    
    
        Vector3 p0p1 = (1 - t) * p0 + t * p1;
        Vector3 p1p2 = (1 - t) * p1 + t * p2;
        Vector3 temp = (1 - t) * p0p1 + t * p1p2;
        return temp;
    }
    
    // 三阶贝塞尔曲线,参数对应上方原理内的三阶曲线参数.
    public static  Vector3 Bezier(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
    {
    
    
        Vector3 temp;
        Vector3 p0p1 = (1 - t) * p0 + t * p1;
        Vector3 p1p2 = (1 - t) * p1 + t * p2;
        Vector3 p2p3 = (1 - t) * p2 + t * p3;
        Vector3 p0p1p2 = (1 - t) * p0p1 + t * p1p2;
        Vector3 p1p2p3 = (1 - t) * p1p2 + t * p2p3;
        temp = (1 - t) * p0p1p2 + t * p1p2p3;
        return temp;
    }

    // 多阶贝塞尔曲线,使用递归实现.
    public static Vector3 Bezier(float t, List<Vector3> p)
    {
    
    
        if (p.Count < 2)
            return p[0];
        List<Vector3> newp = new List<Vector3>();
        for (int i = 0; i < p.Count - 1; i++)
        {
    
    
            Debug.DrawLine(p[i], p[i + 1]);
            
            Vector3 p0p1 = (1 - t) * p[i] + t * p[i + 1];
            newp.Add(p0p1);
        }
        return Bezier(t, newp);
    }
}

新しい FishingRodCtrl スクリプトを作成し、ベジェ曲線を使用して釣り竿の曲がりを制御します。

using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using UnityEngine;
using System.Linq;
using UnityEngine.UIElements;

[System.Serializable] // 序列化类,使其在Unity编辑器中可见
public class CtrlPointInfo{
    
     // 控制点信息类
    public float DiffH; // 水平偏移量
    public float DiffV; // 垂直偏移量

}
public class FishingRodCtrl : MonoBehaviour
{
    
    
    private LineRenderer mLr; // 线渲染器
    private LineRenderer mLr_line;//鱼线的线渲染器

    private Transform mBeginTran; // 钓鱼竿开始的位置
    private Transform mEndTran; // 钓鱼竿结束的位置

    private float mStrength; // 钓鱼竿的受力大小
    private Transform mTarget; // 钓鱼竿的目标位置

    public List<CtrlPointInfo> CtrlPointInfos;//控制点的偏移信息列表

    void Start()
    {
    
    
        mLr = GetComponent<LineRenderer>();; // 获取线渲染器组件
        mBeginTran = transform.GetChild(0); // 获取第一个子物体的Transform组件,即钓鱼竿开始的位置
        mEndTran = transform.GetChild(1); // 获取第二个子物体的Transform组件,即钓鱼竿结束的位置

        mTarget = GameObject.Find("Target").GetComponent<Transform>(); // 找到名为"Target"的游戏对象,并获取其Transform组件,即钓鱼竿的目标位置
        mLr_line = GameObject.Find("鱼线").GetComponent<LineRenderer>(); // 找到名为"鱼线"的游戏对象,并获取其线渲染器组件
    }

    void Update()
    {
    
    
        DrawFishingRod();
        DrawFishingLine();
    }

    //绘制鱼竿
    private void DrawFishingRod(){
    
    
        var drawPoints = GetDarwFishingRodPoints(); // 获取绘制钓鱼竿的点
        mLr.positionCount = drawPoints.Count; // 设置线渲染器的顶点数
        mLr.SetPositions(drawPoints.ToArray()); // 设置线渲染器的所有顶点的位置
    }

    //绘制鱼线
    private void DrawFishingLine(){
    
    
        Vector3[] points = new Vector3[2]{
    
    mEndTran.position, mTarget.position}; // 创建一个包含钓鱼竿结束的位置和目标位置的向量数组
        mLr_line.positionCount = 2; // 设置鱼线的线渲染器的顶点数为2
        mLr_line.SetPositions(points); // 设置鱼线的线渲染器的所有顶点的位置
    }

    //获取绘制鱼竿的点
    private List<Vector3> GetDarwFishingRodPoints(){
    
    
        mStrength = Mathf.Clamp(Vector2.Distance(mEndTran.position, mTarget.position) - 5, 0, 100) * 0.2f; // 计算力的大小,通过目标位置和钓鱼竿结束的位置的距离,然后减去5,最后乘以0.2

        List<Vector3> points = new List<Vector3>(); // 创建一个新的向量列表,用于存储点
        //获取控制点
        List<Vector3> mCtrlPoints = new List<Vector3>();
        mCtrlPoints.Add(mBeginTran.position); // 将钓鱼竿开始的位置添加到控制点列表中
        //循环创建控制点
        for (int i = 0; i < CtrlPointInfos.Count; i++) // 遍历控制点的偏移信息列表
        {
    
    
            Vector3 ctrlPoint = mBeginTran.position + (mEndTran.position - mBeginTran.position) * CtrlPointInfos[i].DiffH; // 计算控制点的位置,首先进行水平方向的偏移
            ctrlPoint = ctrlPoint + (Vector3)Vector2.Perpendicular(mEndTran.position - mBeginTran.position) * CtrlPointInfos[i].DiffV * -1 * mStrength; // 然后进行垂直方向的偏移
            mCtrlPoints.Add(ctrlPoint); // 将计算出的控制点添加到控制点列表中
        }

        //最好一个控制点单独控制,从鱼竿竿稍 向力的反方向偏移,可以使曲线顺滑
        Vector3 lastCtrlPoint = mEndTran.position + (mEndTran.position - mTarget.position).normalized * CtrlPointInfos.Last().DiffV * mStrength;

        mCtrlPoints.Add(mEndTran.position); // 将钓鱼竿结束的位置添加到控制点列表中

        for (int i = 0; i < 100; i++){
    
     // 遍历100次
            points.Add(BezierHelper.Bezier(i/100f, mCtrlPoints)); // 使用贝塞尔曲线算法计算点的位置,并添加到点列表中
        }
        return points; // 返回点列表
    }
}

スクリプトのマウント、パラメータの設定、
ここに画像の説明を挿入
エフェクトの実行

ここに画像の説明を挿入

ソースコード

https://gitcode.net/unity1/unity2d-fishing
ここに画像の説明を挿入

参考

【動画】https://www.bilibili.com/video/BV1QL411q7Tr

終わり

バラの贈り物、香りを贈りましょう!記事の内容が少しでもお役に立てましたら、点赞评论和关注できるだけ早くフィードバックをいただけるよう、ケチらずに書いていただけると、それが支持創作活動を続ける最大のモチベーションとなります。もちろん、記事存在错误などで何か見つけた場合は更好的解决方法、コメントやプライベートメッセージを送ってください。

さて、私は向宇https://xiangyu.blog.csdn.net

小さな会社で趣味で黙々と働いていた開発者が、最近Unityを独学で勉強し始めました。何か問題が発生した場合は、コメントやプライベート メッセージを私に送ってください。私が必ずしも問題を知っているとは限りませんが、関係者全員の情報を確認し、最善の提案を提供できるよう努めます。より多くの人々の助けになれば幸いです。プログラミングを学びたい人、励まし合いましょう〜
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_36303853/article/details/132516540