Visual Effect Graphを使って簡単な火の粉のようなエフェクト作りました。
デフォルトでは主に上方向に飛んで、重力によって落ちてきます。
これをSphereとCubeが衝突した場所に生成するときに、Cubeのどこに当たったかによって火の粉が出る向きを変えてみました。
Sphereを飛ばすスクリプトは以前の記事と同じもので、空のゲームオブジェクトに付けています。
Visual Effectを生成するのは、Sphereのプレハブにつけた別のスクリプトです。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VFX;
public class ColScript : MonoBehaviour
{
public VisualEffect vfx;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
private void OnCollisionEnter(Collision collision)
{
// 衝突したポイントに、Cubeの表面の向く方を上にしてエフェクトを生成する
var effect = Instantiate(vfx, collision.contacts[0].point , Quaternion.FromToRotation(Vector3.up,collision.contacts[0].normal));
// effect.gameObject.transform.parent = collision.gameObject.transform;
}
}
collision.contactsに衝突情報が入っています。
https://docs.unity3d.com/jp/460/ScriptReference/Collision-contacts.html
変数のpointとnormalがそれぞれ、接触点の座標と、接触点の法線です。
https://docs.unity3d.com/jp/460/ScriptReference/ContactPoint.html
エフェクトがデフォルトで上に向いているので、Quaternion.FromToRotationメソッドを使って、Vector3.up から collision.contacts[0].normal に向けるための回転値を取得して、エフェクトを生成するときの引数にします。
エフェクトのワールド座標とローカル座標
Visual Effect Graphでは、Initialize ParticleコンテキストのSet Velocity Randomブロックで一つ一つのパーティクルの速度をランダムで設定するときの値の範囲を決められますが、入力窓の左にデフォルトで「L」というマークがついています。これはこの値がローカル座標であることを表しています。
これを一度クリックするとワールド座標に変わります。
ワールド座標にすると、Visual Effectがどの向きにあっても、パーティクルは常にワールド座標の上方向に飛びます。
ローカル座標の上方向は、Visual Effectの回転についてくるので、ローカル座標に設定した方が自然です。
同様に、Update Particleコンテキストで設定する重力は、デフォルトのワールド座標のままにします。
これをローカル座標にすると、生成されたVisual Effectの向きによって重力の方向が変わります。
Cubeをアニメーションで動かす
Cubeにアニメーションをつけても、Cubeの向きに合わせてエフェクトが自然な向きになっていると思います。
エフェクトを生成したときに、エファクトをCubeの子オブジェクトにすると、飛び出したあとのパーティクルもその後のCubeの動きについていってしまって不自然になりました。
また、パーティクルがスポーンする期間がもっと長いとエフェクトが置いてきぼりになります。