##はじめに
この記事は SLP KBIT Advent Calendar 2019 の21日目の記事です。
SLP KBIT Advent Calendar 2019
##概要
ピンボールが作りたくなったので、Unityで実装していきたいと思いました。
中でも今回はピンボールのボールをはじく部分をHingeJointを用いてつくっていきます。
##実行環境
Unity version:2019.2.9f1
##参考URL
スクリプトリファレンス
Hinge Jointでシーソーを作る
【Unity】 重力を変更する
##事前準備
scene上に3Dオブジェクトを置きます。
名前 | 3D Object |
---|---|
Floor | Cube |
Ball | Sphere |
AxisL, R | Cylinder |
FlipperL, R | Cube |
このように配置しました。 | |
##HingeJoint
ヒンジとはドアの接合部に使われているような回転の支点となる部分の事だそうです。
UnityではHingeJointがついている物体をヒンジで接合されているように動かすことができるようです。
今回はHingeJointの中でもSpringという変数をつかってばねの力でボールを弾こうと思います。
##使ってみます
まずHingeJointComponentを軸になるオブジェクトに加えます。
軸には重力がかかってほしくないのでUseGravityのチェックを外し、
物理の影響を受けてほしくないのでIs Kinematicのチェックをつけます。
ここではAxisRにAdd Componentしています。
HingeJointは2つのRigidbody(剛体)をつなげるので動かす部分にRigidbodyを加えます。
ここではFlipperRにAdd Componentしています
2つのRigidbodyをHingeJointで繋げるために、
AxisRのHingeJoint内のConenected BodyにFlipperRをドラッグアンドドロップします。
これをAxisLとFlipperLにも行います。
この後AxisRのHingeJointのEdit Joint Angular LimitsでHingeの向きと方向を編集します。
Axisの値で調整します。
矢印を軸として、円に沿って力が加わるので上向きにします。(反時計回りが正)
変更前
変更後
この時点でAxisRのHingeJointの
UseSpringにチェックを入れ、Springに40000、Damperに0、TargeetPositionを-60にすると
このようになりました。(AxisLも変更済み)
この時にフリッパーが回転しすぎたりしないようにAxisRのHingeJoint内のUse Limitsにチェックを入れ、
Minに-60、Maxに0を入れます。(AxisLも同様)
この後、左クリックで左フリッパー、右クリックで右フリッパーを動かしてみます。
##コード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Flipper : MonoBehaviour
{
// Inspecterで値を変更する
public float spring = 40000;
public float openAngle = 60; // 開く角度
public float closeAngle = 0; // 閉じる角度
// Hinge Joint
private HingeJoint hjL; // AxisL
private HingeJoint hjR; // AxisR
// JointSpring
private JointSpring jL; // AxisL
private JointSpring jR; // AxisR
void Start()
{
// AxisLとAxisRを探す
GameObject flipperL = GameObject.Find("AxisL");
GameObject flipperR = GameObject.Find("AxisR");
// HingeJointを受け取る
hjL = flipperL.GetComponent<HingeJoint>();
hjR = flipperR.GetComponent<HingeJoint>();
// Springを受け取る
jL = hjL.spring;
jR = hjR.spring;
}
void Update()
{
// 左クリックを押す
if (Input.GetMouseButtonDown(0))
{
jL.spring = spring;
jL.targetPosition = openAngle;
hjL.spring = jL;
}
// 左クリックを離す
if (Input.GetMouseButtonUp(0))
{
jL.spring = spring;
jL.targetPosition = closeAngle;
hjL.spring = jL;
}
// 右クリックを押す
if (Input.GetMouseButtonDown(1))
{
jR.spring = spring;
jR.targetPosition = -openAngle;
hjR.spring = jR;
}
// 右クリックを離す
if (Input.GetMouseButtonUp(1))
{
jR.spring = spring;
jR.targetPosition = closeAngle;
hjR.spring = jR;
}
}
}
Update関数内でボタンを検知しています。
左クリックをすると40000の力で60度左フリッパーが回転、
右クリックをすると40000の力で-60度右クリックが回転します。
##実行結果
Edit→Project Settings→PhysicsでGravityの方向を変更します。
フリッパーが重力の影響を受けないようにFlipperL、FlipperRのUseGravityのチェックを外しました。
重力を反映させるためBallにRigidbodyをつけます。
実行するとこんな感じになりました。
カクついていますが何とか動いています。
##終わりに
結構ちゃんとフリッパーしてくれていると感じました。
ピンボールはフリッパーだけではできないので他の部分も実装してみたいと思いました。