滑动条带动剖切功能的实现

       模型的剖切功能需要将模型的材质shader进行特定的更改,需要一定的语言功底,下面将附上挂在需要被剖切的模型上的代码以及需要自己添加的新的shader代码。

这些ui需要自己进行添加。

解下来是挂在模型上的脚本:

using UnityEngine;
using UnityEngine.UI;

public class PoushiDemo : MonoBehaviour
{
    public Slider sliderX;
    public Slider sliderY;
    public Slider sliderZ;
    public Image image;
    public Shader cutShader;

    private Vector3 cutNormal;
    private string cutAxis;
    private bool cuttingEnabled = false;  // 剖切功能的开关
    private Renderer[] renderers;
    private Shader[][] originalShaders;

    void Start()
    {
        if (cutShader == null)
        {
            Debug.LogError("Cut Shader is not specified!");
            return;
        }

        renderers = GetComponentsInChildren<Renderer>();
        if (renderers.Length == 0)
        {
            Debug.LogError("No Renderer component found on children!");
            return;
        }

        originalShaders = new Shader[renderers.Length][];
        for (int i = 0; i < renderers.Length; i++)
        {
            originalShaders[i] = new Shader[renderers[i].materials.Length];
            for (int j = 0; j < renderers[i].materials.Length; j++)
            {
                originalShaders[i][j] = renderers[i].materials[j].shader;
            }
        }

        Bounds totalBounds = renderers[0].bounds;
        for (int i = 1; i < renderers.Length; i++)
        {
            totalBounds.Encapsulate(renderers[i].bounds);
        }

        sliderX.minValue = totalBounds.min.x;
        sliderX.maxValue = totalBounds.max.x;
        sliderX.value = sliderX.minValue; 
        sliderX.onValueChanged.AddListener(delegate { cutAxis = "x"; UpdateCutNormal(); });

        sliderY.minValue = totalBounds.min.y;
        sliderY.maxValue = totalBounds.max.y;
        sliderY.value = sliderY.minValue;  
        sliderY.onValueChanged.AddListener(delegate { cutAxis = "y"; UpdateCutNormal(); });

        sliderZ.minValue = totalBounds.min.z;
        sliderZ.maxValue = totalBounds.max.z;
        sliderZ.value = sliderZ.minValue;  
        sliderZ.onValueChanged.AddListener(delegate { cutAxis = "z"; UpdateCutNormal(); });

        SwitchCuttingMaterial(cuttingEnabled);
    }

    public void ToggleCutting()
    {
        cuttingEnabled = !cuttingEnabled;
        SwitchCuttingMaterial(cuttingEnabled);
        image.gameObject.SetActive(!image.gameObject.activeSelf);
    }

    void SwitchCuttingMaterial(bool cutting)
    {
        for (int i = 0; i < renderers.Length; i++)
        {
            Renderer renderer = renderers[i];
            if (renderer.materials.Length > 0)
            {
                Material[] materials = new Material[renderer.materials.Length];
                for (int j = 0; j < renderer.materials.Length; j++)
                {
                    Material originalMaterial = renderer.materials[j];
                    Material newMaterial = new Material(cutting ? cutShader : originalShaders[i][j]);
                    newMaterial.color = originalMaterial.color;
                    materials[j] = newMaterial;
                }
                renderer.materials = materials;
            }
        }
    }

    void UpdateCutNormal()
    {
        switch (cutAxis)
        {
            case "x":
                cutNormal = Vector3.right;
                break;
            case "y":
                cutNormal = Vector3.up;
                break;
            case "z":
                cutNormal = Vector3.forward;
                break;
        }
    }

    private void Update()
    {
        if (!cuttingEnabled || cutShader == null || sliderX == null || sliderY == null || sliderZ == null)
        {
            return;
        }

        Vector4 cutPos = new Vector4(sliderX.value, sliderY.value, sliderZ.value, 0);

        foreach (Renderer renderer in renderers)
        {
            if (renderer.materials.Length > 0)
            {
                foreach (Material material in renderer.materials)
                {
                    material.SetVector("_CutPos", cutPos);
                    material.SetVector("_CutNormal", cutNormal);
                }
            }
        }
    }
}

shader的Demo如有需要请关注加私信,谢谢!

(在校生的第一次博客!)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值