Unity3D酷炫特效之追踪电弧

概要

本文根据教程(【【Unity教程搬运】Unity VFX Graph - 电弧教程】https://www.bilibili.com/video/BV1hm4y1r7H6?vd_source=033061353294ae0352cec4c059f20a65)所制作的电弧进行开发,小伙伴可以先观看一下视频来完成素材准备,当然也可以通过unity商店直接购买(我可没说淘宝也能买嗷),素材名称:VFX Graph - Procedural Electricity - Vol. 1。

效果先行展示

此为效果图,使用了基于VFX Property Binder的动态绑定方法,写了个新属性PosBinder继承了VFXBinderBase

思考过程

上文红字提到的教程中有说到,这个电弧可以根据自身携带的VFXPropertyBinder组件对几个坐标进行动态绑定,即在电弧的Inspect界面将带有transform的组件拖拽至绑定点Postion对应的target即可,如图。

下文我们会将这几个带绿色方块的东西称作VFX Property(因为我也不是很确定这东西是不是这么命名的,还没研究的非常透彻),如下图

 (接上文黑字)但是这样导致一个严重的问题,如果不进行提前绑定,电流无法在游戏运行时主动的把敌人的信息绑定到Poston.target上来,而Unity自己提供的VFX Property数据是用private封装上的,虽然能在界面上看到这些经过序列化(SerializeField)的信息但是无法用代码获取到他们,所以依靠原本的VFX Property我们无法进行在运行时的动态绑定,此时我们需要自己写一个新的VFX Property来提供public的数据来供我们进行运行时的动态绑定。

经过查看VFXPropertyBinder的文档我们了解到,这些VFX Property是继承了一个叫做VFXBinderBase的东西实现的,如下图

 于是我们自定义一个新的类,就叫PosBinder(这个随便大家怎么喜欢怎么来,起名字无所谓的),继承VFXBinderBase。然后对VFXBinderBase需要的函数进行实现。

理论可行,进入实践

 写法如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VFX;
using UnityEngine.VFX.Utility;

[ExecuteInEditMode]
public class PosBinder : VFXBinderBase
{
    public ExposedProperty property;
    public Transform Target;

    public override bool IsValid(VisualEffect component)
    {
        return component.HasVector3(property);
    }

    public override string ToString()
    {
        return "Postion:"+ property.ToString()+"->"+ Target;
    }

    public override void UpdateBinding(VisualEffect component)
    {
        component.SetVector3(property, Target.position);
    }
}

ExposedProperty是给我们绑定结点一个命名,

Target就是我们这个结点要绑定的目标,

IsValid方法用来校验结点是否被重复注册等问题,

ToString就是绿方块后边这串字的由来

其中最核心的部分,就是UpdateBinding函数,这个函数实现结点在游戏中的动态绑定,看见Update想必大家并不陌生,这个函数就负责每帧对结点的目标进行一次绑定以防止其脱轨,具体实现方法不多做赘述。 

PosBinder实现完成后,我们需要在Unity界面将这个PosBinder用AddComponent的方式添加到该电弧的VFXPropertyBinder中,如图(这里用这种方法主要是博主不知道如何将PosBinder写到右下角那个加号里,如果有大佬有方法实现,还请多多指教)

 放上去后PosBinder还需要默认绑定来保证创建它时游戏不会报错,所以我们将他作为父物体,随便创建几个空物体放上去就好,像这样

 现在电弧部分就制作完成了,我们需要一个载体来实现调用它的属性并用他和敌人进行动态绑定,随便一个东西就行,实现代码如下

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEngine.VFX;
using UnityEngine.VFX.Utility;

[RequireComponent(typeof(Collider),typeof(Rigidbody),typeof(Transform))]
public class Bullet : MonoBehaviour
{
    private VFXPropertyBinder[] binder;
    private VisualEffect[] visualEffect;
    //bullet property difine
    public Collider BltColider;
    public Rigidbody BltRigidbody;
    public GameObject lightning;
    public List<GameObject> lightnings = new List<GameObject>();
    public int forwardForce=200;
    // Start is called before the first frame update
    void Start()
    {
        
        BltColider = gameObject.GetComponent<Collider>();
        BltRigidbody = gameObject.GetComponent<Rigidbody>();
        GetComponent<Rigidbody>().AddForce(transform.forward * forwardForce);
    }

    // Update is called once per frame
    void Update()
    {
        
        
    }

   
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "enemy")
        {
            
           // Position v1;
           

            Vector3 direction = other.transform.position - transform.position;
            GameObject lightningAttack = Instantiate(lightning, transform.position, transform.rotation);
            lightnings.Add(lightningAttack);
            binder = lightningAttack.GetComponentsInChildren<VFXPropertyBinder>();
            visualEffect = lightningAttack.GetComponentsInChildren<VisualEffect>();
            
                PosBinder[] posBinders = lightningAttack.GetComponentsInChildren<PosBinder>();
                posBinders[0].Target = transform;
                posBinders[1].Target = transform;
                posBinders[2].Target = transform;
                posBinders[3].Target = other.transform;
                posBinders[4].Target = transform;
                posBinders[5].Target = transform;
                posBinders[6].Target = transform;
                posBinders[7].Target = other.transform;
 
        }
    }
    
    private void OnDestroy()
    {
        for(int i = 0; i < lightnings.Count; i++)
        {
            Destroy(lightnings[i]);
        }
    }

}

完成后将这个脚本放到你的电弧承载物上,如果有电球的话那将是极好的。这个承载物需要有这些组件,并把制作好的电弧放到Lightning上

 结语

好啦现在你的电弧已经实现对敌人的动态绑定啦,我知道你想学爆炸,想要电球,我会尽快将电球和爆炸相关的文章发表让你看到的,如果你喜欢还请点一个小小的赞,感谢你你是个好人,超级大好人。

猜你喜欢

转载自blog.csdn.net/qq_56755504/article/details/131272992