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

RE:ADV

UnityでADVを作るブログ

【Unity】RectTransformの外枠に沿って線を引く!【uGUI】

Vectrosityという線を引くアセットを購入しました。
magicbullet.hatenablog.jp
befool.co.jp

シルバー事件リマスター版が出たのを機にプレイ動画を一気見したせいで、フィルムウィンドウと呼ばれていたあのシステムが気になりだしたのです。
このゲームで<ウィンドウ>と呼ばれるものは線で演出されています。動きや、トランジションも線で視線を誘導します。
今見返してみると同期・非同期が計算されて配置されていて、作劇法・ノベルゲーのシステムとして興味深いのはもちろん、プログラムの題材としてもおもしろいと感じました。

さて、線を引けるようになったのはいいのですが、しばらくいじっているとuGUIと連携できれば様々な問題が解決することに気づきます。
LineとMonoBehaviourとの連携です。これは言い換えるとGameObjectとの連携ということになります。
UnityはGameObject-MonoBehaviourを基点にAPIを組み上げている側面があり、これと連携することで画面構築上(ググラビリティ上?)相当な恩恵を得ることができます。(気づくのにけっこう時間がかかった...)

考えていると、Panelの外枠に線を引ければそれだけでもいろいろできるようになることに気づきました。
(っていうかPanelがUI>>Imageの絵なしバージョンってことさえこのとき知ったのですが)
オブジェクトのコピーが簡単にできるので、同じ動きをするオブジェクトがあると役割を変えて重ね掛けができるんですね。
ここで立ちはだかったのが、RectTransformです。
UnityのUIを考える人全員の前に立ちはだかる壁になるのではないか。そう思うくらい強かったです。
そもそもインスペクターウィンドウに表示されているものの意味がわからないじゃないですか。
いや、感覚的にはアンカーもピボットもなんとなくはわかりますよ。
でもそれらのエディタUIが隠している計算がさっぱりわからない。
Script的に公開されているプロパティも意味がわからない...。
ググるしかありません。
tsubakit1.hateblo.jp

www.slideshare.net

とくに今回は二つ目のスライドに助けられました。(読んでも意味がわからなくて、出てくるプロパティを片っ端からDebug.Log()したのは内緒だ)
結論を述べると、親のCanvas下に作られたPanelのRectTransform、この矩形の角の四つの頂点をスクリプトから指定するには(このスクリプトコンポーネントとしてPanel自身にアタッチするとして)、以下のように書きます。

using Vectrosity;
using UnityEngine;
using System.Collections.Generic;

public class VRectTest : MonoBehaviour
{
    private RectTransform rect;

    private Vector2 TopRight;
    private Vector2 TopLeft;
    private Vector2 BottomLeft;
    private Vector2 BottomRight;

void Start()
{
    //自分自身がアタッチしたGameObjectのコンポーネントを取得する場合はgameObject
    //自分がアタッチしているかわからないシーン内のゲームオブジェクトを探して
    //キャッシュするにはGameObject.Find("ゲームオブジェクトの名前")
    rect = gameObject.GetComponent<RectTransform>();

    var offsetMax = rect.offsetMax;//アンカーからのオフセット(右上)
    var offsetMin = rect.offsetMin;//アンカーからのオフセット(左下)

    //アンカーがCanvasの四隅を指定している場合
    TopRight = new Vector2(Screen.width + offsetMax.x, Screen.height + offsetMax.y);
    TopLeft = new Vector2(offsetMin.x, Screen.height + offsetMax.y);
    BottomLeft = new Vector2(offsetMin.x, offsetMin.y);
    BottomRight = new Vector2(Screen.width + offsetMax.x, offsetMin.y);
}}

f:id:aktaat:20161030085023p:plain
これが...
f:id:aktaat:20161030085027p:plain
f:id:aktaat:20161030085031p:plain
こう!

どこかの一辺だけに線を引くとかも選択的にできるようになりました。