很好地弯曲轨道和道具的方法?

问题描述

这是我的第一个游戏开发问题,请对学习统一的菜鸟保持温和。

所以我有这个跑步游戏项目,我希望赛道像 this Thumper trailer 一样弯曲和扭曲,另外还有 twisted corridor effect。但我不太擅长复杂的计算。

实际上在我的项目中,关卡有一个定义了长度的轨道。赛道是由500个单元的几个直线预制部分和道具组成的直线游戏对象。整个轨道使用 hlsl 着色器从相机位置弯曲到最远的顶点,并使用网络上找到的脚本:

#include "UnityCG.cginc"


struct appdata
{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    float4 color : COLOR;
};

struct v2f
{
    float2 uv : TEXCOORD0;
    UNITY_FOG_COORDS(1)
    float4 color : TEXCOORD2;
    float4 vertex : SV_POSITION;
};

sampler2D _MainTex;
float4 _MainTex_ST;
float _CurveStrengthY;
float _CurveStrengthX;
float _CurveTwist;

v2f vert(appdata v)
{
    v2f o;

    float _Horizon = 100.0f;
    float _Fadedist = 50.0f;


    o.vertex = UnityObjectToClipPos(v.vertex);

    float dist = UNITY_Z_0_FAR_FROM_CLIPSPACE(o.vertex.z);

    o.vertex.y -= _CurveStrengthY * dist * dist * _ProjectionParams.x;

    o.vertex.x -= _CurveStrengthX * dist * dist * _ProjectionParams.x;
    
    // how tf do i add twist
    
    o.uv = TRANSFORM_TEX(v.uv,_MainTex);

    o.color = v.color;

    UNITY_TRANSFER_FOG(o,o.vertex);
    return o;
}

fixed4 frag(v2f i) : SV_Target
{
    // sample the texture
    fixed4 col = tex2D(_MainTex,i.uv) * i.color;

    // apply fog
    UNITY_APPLY_FOG(i.fogCoord,col);
return col;
}

由这个脚本控制,我向弯曲添加随机值以查看用于测试目的的变化:

using UnityEngine;
using System.Collections;


[ExecuteInEditMode]
public class WorldCurver : MonoBehavIoUr
{

    float lerpDuration = 500f;

    float startValue=-0.004f;
    float endValue=0.004f;

    float randomTime = 0;

    [Range(-0.005f,0.002f)]
    public float curveY = 0.01f;

    [Range(-0.006f,0.006f)]
    public float curveX = 0.01f;


    [Range(0f,360f)]
    public float curveAngle = 0.01f;

    int m_CurveStrengthID_Y;
    int m_CurveStrengthID_X;
    int m_CurveTwistID;

    private void OnEnable()
    {

        m_CurveStrengthID_Y = Shader.PropertyToID("_CurveStrengthY");
        m_CurveStrengthID_X = Shader.PropertyToID("_CurveStrengthX");
        m_CurveTwistID = Shader.PropertyToID("_CurveTwist");
    

    }

    void Start() {

        StartCoroutine(bendpath());

    }

    IEnumerator bendpath()
    {
        while(true){

            float randomTime = Mathf.Round(Random.Range(lerpDuration,lerpDuration * 1.2f));
        
            float timeElapsed = 0;


            Debug.Log("Bending path in " + randomTime);

            float nextBendY = Random.Range(-0.0012f,0.001f);
            float nextBendX = Random.Range(-0.001f,0.001f);

            while (timeElapsed < lerpDuration)
            {
                curveY = Mathf.Lerp(curveY,nextBendY,timeElapsed / lerpDuration);
                curveX = Mathf.Lerp(curveX,nextBendX,timeElapsed / lerpDuration);
                timeElapsed += Time.fixedDeltaTime;

                yield return null;
            }

            yield return new WaitForSeconds(lerpDuration);

        }

    }



    void Update()
    {       

        Shader.SetGlobalFloat(m_CurveStrengthID_Y,curveY);
        Shader.SetGlobalFloat(m_CurveStrengthID_X,curveX);
        Shader.SetGlobalFloat(m_CurveAngleID,curveAngle);

    
    }
}

使用着色器的材质使it look like this

我希望将 CurveStrengthX 和 CurveStrengthY 分开显示,以便随着时间的推移进行更改,使其看起来像一条可以看到转弯的道路。它有效,轨道是弯曲的,但我的目标是让它看起来像一条路。当我改变 CurveStrength 值时,它看起来更像是一条弯曲的跑步机皮带向你滚动,而不是一条道路。另外,我无法在赛道的某个点添加曲折。

船在 Z 轴上直线前进,您可以从左到右以可变速度扫射。它独立于轨道,保持在 Y 中的一个固定值,以产生它漂浮在地面上的错觉,因为着色器使轨道在相机前再次笔直。相机以偏移量固定在船上。

所以我的问题是,有没有什么好的方法可以弯曲和扭转完整的轨道,看到即将到来的转弯并制造出导航的错觉?

我想避免:

  • 由于世界轴的旋转,在所有方向和长度上为路段制作更多转弯预制件。如果可能,我只想在无缝轨道中沿 Z 轴移动船。
  • 重写我的动作/输入系统

我认为可以完成工作的想法:

  • 添加到着色器,在轨道上连续弯曲和扭曲,以保持原始关卡和道具模型笔直(我更容易调整和调整关卡)
  • 使用着色器图重写具有弯曲和扭曲序列的着色器
  • 重写整个着色器
  • 也许可以使用样条曲线或其他东西沿着轨道弯曲
  • 完全放弃多次弯曲和曲折(但我希望不会)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)