メインコンテンツまでスキップ

ボタン

Buttonコンポーネントは、エレメントをボタンにします。エンティティのエレメントへの入力に反応し、ボタンのホバーや押下に応じてイメージの見た目を変え、clickなどのイベントを発火します。そのエレメントでは入力を有効にする必要があります。

デフォルト、ホバー、押下、非アクティブの4つの状態それぞれで表示した、1つのオレンジ色のボタン。ホバー時は明るく、押下時は暗く、非アクティブ時は濃いグレーになります

ボタンの作成​

const button = new pc.Entity('button');
button.addComponent('element', {
type: pc.ELEMENTTYPE_IMAGE,
anchor: [0.5, 0.5, 0.5, 0.5],
pivot: [0.5, 0.5],
width: 200,
height: 60,
color: new pc.Color(1, 0.55, 0.2),
useInput: true
});
button.addComponent('button', {
imageEntity: button,
hoverTint: new pc.Color(1, 0.7, 0.45),
pressedTint: new pc.Color(0.8, 0.4, 0.1)
});
screen.addChild(button);

// ラベルは入力を持たない子のテキストエレメントなので、ラベルへのクリックはボタンに届く
const buttonText = new pc.Entity('text');
buttonText.addComponent('element', {
type: pc.ELEMENTTYPE_TEXT,
fontAsset: font.id,
text: 'Play',
color: new pc.Color(0.1, 0.1, 0.1),
anchor: [0.5, 0.5, 0.5, 0.5],
pivot: [0.5, 0.5]
});
button.addChild(buttonText);

button.button.on('click', () => {
console.log('Play');
});

アプリケーションを作成するときにpc.ButtonComponentSystemを登録します。

イメージ​

ボタンが見た目を変えるのは1つのイメージエレメント、つまりイメージエンティティ(imageEntity)にあるイメージエレメントです。通常はボタン自身のエンティティですが、エレメントのグループの背後にある背景など、別のエンティティにすることもできます。入力の受け取り元は変わりません。ボタンは常に自身のエンティティのエレメントへの入力に反応し、これには入力が有効な子からバブリングしてくるイベントも含まれます。

エディターのUser Interface › Buttonは、イメージエンティティをボタン自身に設定します。<pc-button>も、image属性で別のエンティティを指定しない限り同様です。エンジンでは、imageEntityは設定するまでnullです。イメージエンティティのないボタンもイベントは発火しますが、見た目は変わりません。

トランジション​

ボタンは、デフォルト、ホバー、押下、非アクティブの4つの状態のいずれかにあります。Transition Modeは、イメージで状態をどのように表すかを決めます。

ティント​

デフォルトのTintモードでは、状態ごとにティントの色があります。

状態プロパティエンジンのデフォルト
デフォルトイメージ自身の色と不透明度
ホバーhoverTint0.75, 0.75, 0.75
押下pressedTint0.5, 0.5, 0.5
非アクティブinactiveTint0.25, 0.25, 0.25

ティントはイメージの色に乗算されるのではなく、イメージの色を置き換えます。そのため、デフォルトのグレーのティントでは、オレンジ色のボタンがグレーになります。ティントのアルファもイメージの不透明度になり、デフォルトのティントのアルファは1なので、半透明のボタンはホバーされると不透明になります。ティントには、ボタンの色を明るくした色と暗くした色を、ボタンに持たせたいアルファで選んでください。

Fade Duration(fadeDuration)は、指定したミリ秒をかけてティントの間をフェードします。デフォルトは0で、ティントはすぐに切り替わります。

スプライトの切り替え​

Sprite Changeモードでは、各状態が専用のスプライトアセットとフレームを表示します。hoverSpriteAssetとhoverSpriteFrame、pressedSpriteAssetとpressedSpriteFrame、inactiveSpriteAssetとinactiveSpriteFrameです。デフォルトの状態では、イメージ自身のスプライトを表示します。1つのスプライトの異なるフレームを使えば、1枚のテクスチャアトラスからボタンの状態一式を作れます。

エンジンではtransitionModeをpc.BUTTON_TRANSITION_MODE_SPRITE_CHANGEに、エディターではTransition ModeをSprite Changeに設定し、<pc-button>ではtransition-mode="sprite"を指定します。

イベント​

ボタンのイベントは、Buttonコンポーネントでリッスンします。

イベント発火するタイミング
clickボタンがクリックまたはタップされたとき、あるいはXRでセレクトされたとき
hoverstart, hoverendマウスまたはXRコントローラーによるボタンのホバーが始まったとき、終わったとき
pressedstart, pressedend何らかの入力によるボタンの押下が始まったとき、終わったとき
mouseenter, mouseleave, mousedown, mouseupエレメントのマウスイベント
touchstart, touchend, touchleave, touchcancelエレメントのタッチイベント
selectstart, selectend, selectenter, selectleaveエレメントのXRのセレクトイベント

入力イベントは、エレメント自身のイベントと同じイベントオブジェクトを受け取ります。各環境でどこでリッスンするかは、イベントのリッスンを参照してください。

button.button.on('pressedstart', () => {
button.setLocalScale(0.95, 0.95, 1);
});
button.button.on('pressedend', () => {
button.setLocalScale(1, 1, 1);
});

押下中のボタンからポインターを外すと押下は終わり、そこで離してもクリックにはなりません。

ヒットパディング​

Hit Padding(hitPadding)は、ボタンが入力を受け取る領域を、各辺でスクリーンの単位での距離だけ広げます。順序は左、下、右、上です。見た目を変えずに、小さなボタンをタップしやすくできます。

// 32 × 32の閉じるボタンが、その周囲16単位でも反応するようにする
closeButton.button.hitPadding = new pc.Vec4(16, 16, 16, 16);

ボタンの無効化​

ボタンを無効にするには、activeをfalseに設定します。ボタンは非アクティブのティントまたはスプライトを表示し、ボタンのイベントを発火しなくなります。エレメントは引き続き入力を受け取るため、エレメント自身のイベントは発火し続け、ボタンは本来なら背後のエレメントに届くはずのクリックも受け止め続けます。入力を通過させるにはエレメントのuseInputもオフにし、ボタンを隠すにはエンティティを無効にします。

buyButton.button.active = coins >= price;

タッチとXR​

  • タッチ。 タッチにはホバー状態がありません。タップされたボタンは、デフォルトの状態から押下状態になり、また元に戻ります。touchendで、ボタンはそのタップに対してブラウザがエミュレートするマウスイベントをキャンセルします。キャンセルしなければ、それらのイベントでボタンがホバー状態になってしまいます。clickハンドラーの中で自身を隠すボタンはそのtouchendを受け取れないため、エミュレートされたイベントが背後にあるものに届いてしまいます。対処方法はタッチスクリーンを参照してください。
  • XR。 コントローラーや手でボタンを指すとボタンはホバー状態になり、セレクトでボタンが押下されてクリックされます。XRのUIを参照してください。

サウンドとカーソル​

ボタンには独自のサウンドやカーソルはありません。clickイベントでサウンドを再生し(例えば、ボタンに付けたSoundコンポーネントから)、ホバー時にカーソルを変更します。

button.button.on('hoverstart', () => {
app.graphicsDevice.canvas.style.cursor = 'pointer';
});
button.button.on('hoverend', () => {
app.graphicsDevice.canvas.style.cursor = '';
});

関連情報​