読者です 読者をやめる 読者になる 読者になる

しゅみぷろ

プログラミングとか

Splatoonの塗りみたいのを再現したい その3

はじめに

f:id:es_program:20160501144056p:plain:w400

esprog.hatenablog.com

esprog.hatenablog.com

塗りを作るその3です。エフェクトを付けてベチャっと塗った感を出しました。

f:id:es_program:20160501142352g:plain:w400

結構それらしくなってきた気がします。

エフェクト作る技術力が無かったのでこちらのアセットを使わせて頂きました。

実装

実装と言っても、着弾時(ペイント時)にパーティクルのプレハブをInstantiateするだけです。

using Es.TexturePaint;
using System.Collections;
using UnityEngine;

namespace Es.TexturePaint.Sample
{
  public class MousePainter : MonoBehaviour
  {
    [SerializeField]
    private GameObject touchEffect;

    private void Update()
    {
      if(Input.GetMouseButtonDown(0))
      {
        var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hitInfo;
        if(Physics.Raycast(ray, out hitInfo))
        {
          var paintObject = hitInfo.transform.GetComponent<DynamicPaintObject>();
          if(paintObject != null)
          {
            if(touchEffect != null)
            {
              var effectObject = Instantiate(touchEffect);
              effectObject.transform.position = hitInfo.point;
              effectObject.transform.rotation = Quaternion.LookRotation(hitInfo.normal);
              effectObject.GetComponent<ParticleSystem>().startColor = paintObject.BlushColor;
            }
            paintObject.Paint(hitInfo);
          }
        }
      }
    }
  }
}

マウス左クリックの際にレイを飛ばし、ヒットしたオブジェクトの位置にパーティクルの生成とペイント処理を行うサンプルのプログラムです。 DynamicPaintObjectは自作のテクスチャペイントを行うためのコンポーネントで、今回の場合レイのヒット情報からペイント処理を行っています。

パーティクルの生成と値の設定は

var effectObject = Instantiate(touchEffect);
effectObject.transform.position = hitInfo.point;
effectObject.transform.rotation = Quaternion.LookRotation(hitInfo.normal);
effectObject.GetComponent<ParticleSystem>().startColor = paintObject.BlushColor;

で行っています。

また、このエフェクトのプレハブには、エフェクト終了後自身のGameObjectをDestroyするように以下のようなスクリプトを付けています。

using System.Collections;
using UnityEngine;

[RequireComponent(typeof(ParticleSystem))]
public class ParticleAutoDestroy : MonoBehaviour
{
  private ParticleSystem particle;

  private void Awake()
  {
    particle = GetComponent<ParticleSystem>();
  }

  private void Update()
  {
    if(!particle.IsAlive())
      Destroy(gameObject);
  }
}

ParticleSystemのIsAliveを調べることにより破棄するかどうかを判断しています。