本記事では、UnityでScrollView上で線を描画する方法について書きます。
ScrollView上で、線を描画するために、
- ScrollViewのContentにImageコンポーネントをアタッチしたゲームオブジェクトを設定する
- Imageにドットの集合で線を描画する
ということをしました。
他にもっと簡単にできる方法があるかもしれません。が、見つけられなかったので、この方法を採用しました。
MackableGraphic クラスを使用しても線は描画できます。しかし、ScrollView上で線を描画する場合、スクロールすると、線がはみ出ます。これはGUIで使うものではないように思います。
開発環境
- Windows10 Home 64bit
- Unity Version 2020.3.17f1 Personal
- Visual Studio Community 2019 16.11.2
- .NET Standard2.0
目次
やりたいこと
- ScrollView 上に星型のラインを表示する
- ScrollView のバーを動かしたとき、ラインがスクロールビューからはみ出ないようにする
- ラインの表示非表示を自由にできるようにする
実際に実装したものは↓のような動きをします。
ライン表示を実装する
SampleSence上に、ScrollView を作成しました。
ScrollView → Viewport → Content の子ゲームオブジェクトに、
- 背景白のImageコンポーネントを実装したゲームオブジェクト
- 背景透明、黒色の星ラインのImageコンポーネントを実装したゲームオブジェクト
をScriptで追加します。2つを重ねて表示することでラインを表示します。
黒色の星ラインのゲームオブジェクトを非アクティブ化することで、ラインを消すことができます。
動画はGUIで表示切替をしてますが、スクリプトでもSetActiveを使えばできます。
ScrollView にアタッチするMonoBehaiver の拡張クラスは↓のようになります。
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Assets.Script
{
/// <summary>
/// ScrollView -> Viewport -> Content
/// </summary>
class StarImage : MonoBehaviour
{
/// <summary>星ライン座標一覧</summary>
private readonly LineCords StarLineCords = new LineCords(
new List<LineCord>()
{
new LineCord(200,143),
new LineCord(288,79),
new LineCord(254,183),
new LineCord(342,246),
new LineCord(233,246),
new LineCord(200,350),
new LineCord(167,246),
new LineCord(58,246),
new LineCord(146,183),
new LineCord(112,79)
});
/// <summary>星ライン幅</summary>
private readonly int StarLineWidth = 5;
/// <summary>イメージ幅</summary>
private readonly int ImageWidth = 400;
/// <summary>イメージ高さ</summary>
private readonly int ImageHeight = 400;
private void Start()
{
GameObject viewport = transform.Find("Viewport").gameObject;
GameObject content = viewport.transform.Find("Content").gameObject;
content.GetComponent<RectTransform>().sizeDelta = new Vector2(ImageWidth, ImageHeight);
// 背景イメージ ゲームオブジェクトの生成
GameObject backGameObject = Instantiate(new GameObject());
backGameObject.AddComponent<Image>();
backGameObject.transform.parent = content.transform;
backGameObject.name = "BackImage";
backGameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(ImageWidth, ImageHeight);
backGameObject.GetComponent<RectTransform>().anchorMin = new Vector2(0, 1);
backGameObject.GetComponent<RectTransform>().anchorMax = new Vector2(0, 1);
backGameObject.GetComponent<RectTransform>().pivot = new Vector2(0, 1);
backGameObject.transform.localPosition = new Vector3(0, 0, 0);
// 背景を白にする
Color backColor = new Color(255, 255, 255, 255);
Texture2D backTexture = new Texture2D(ImageWidth, ImageHeight, TextureFormat.ARGB32, false);
for (int x = 0; x < ImageWidth; x++)
{
for (int y = 0; y < ImageHeight; y++)
{
backTexture.SetPixel(x, y, backColor);
}
}
// 背景の反映
Image backImage = backGameObject.GetComponent<Image>();
backImage.sprite = Sprite.Create(backTexture, new Rect(0, 0, backTexture.width, backTexture.height), new Vector2(0.5F, 0.5F));
backTexture.Apply();
// ラインイメージ ゲームオブジェクトの生成
GameObject lineGameObject = Instantiate(new GameObject());
lineGameObject.AddComponent<Image>();
lineGameObject.transform.parent = content.transform;
lineGameObject.name = "LineImage";
lineGameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(ImageWidth, ImageHeight);
lineGameObject.GetComponent<RectTransform>().anchorMin = new Vector2(0, 1);
lineGameObject.GetComponent<RectTransform>().anchorMax = new Vector2(0, 1);
lineGameObject.GetComponent<RectTransform>().pivot = new Vector2(0, 1);
lineGameObject.transform.localPosition = new Vector3(0, 0, 0);
Texture2D lineTexture = new Texture2D(ImageWidth, ImageHeight, TextureFormat.ARGB32, false);
// 背景を白にする
Color lineBackColor = new Color(255, 255, 255, 0);
for (int x = 0; x < ImageWidth; x++)
{
for (int y = 0; y < ImageHeight; y++)
{
lineTexture.SetPixel(x, y, lineBackColor);
}
}
// ラインを黒にする
Color lineColor = new Color(0, 0, 0, 100);
// ラインのドットに黒を設定する
List<Tuple<int, int>> list = StarLineCords.CreateLineDotListCircle(StarLineWidth);
foreach (Tuple<int, int> dot in list)
{
lineTexture.SetPixel(dot.Item1, dot.Item2, lineColor);
}
// ラインの反映
Image lineImage = lineGameObject.GetComponent<Image>();
lineImage.sprite = Sprite.Create(lineTexture, new Rect(0, 0, lineTexture.width, lineTexture.height), new Vector2(0.5F, 0.5F));
lineTexture.Apply();
}
}
}
ラインのドット一覧を出力する、ライン座標クラス LineCords はここでは割愛します。プロジェクトは↓からダウンロードできます。
まとめ
UnityでScrollView上で線を描画する方法について書きました。
ScrollView上で、線を描画するために、
- ScrollViewのContentにImageコンポーネントをアタッチしたゲームオブジェクトを設定する
- Imageにドットの集合で線を描画する
をしました。
コメント