前提・実現したいこと
初投稿です。
unityにて、物理シミュレーションを行うためのシーソーを作成しています。
シーソーの両端からボールを落下させる際に、Canvas内のDropdownを選択肢からあるものを選んだ状態でButtonをクリックすることで、シーソーの支点の位置やボールの質量を変更できるように実装することを目指しています。
まず、Hierarchy内にSeesawというオブジェクトを生成し、オブジェクト内には子オブジェクトとして、Cube_long,Cube_flcrum(支点にあたるもの),Seesaw_SphereA,Seesaw_SphereBを生成しています。それぞれRigidbodyをComponentとして追加しています。また、Cube_flucrumにHinge JointをComponentとして追加し、Cube_longにつなげています。A,Bそれぞれのボールの質量と支点の位置をドロップダウンにて選択して、反映ボタンをクリックするとそれぞれの値が変更されます。再生して状態でスタートボタンをクリックするとそれぞれのボールが落下し、やり直しボタンをクリックすると落下前の状態に戻るように実装しています。
Inspectorについて
親オブジェクト
◎Seesaw(Create Emptyにて生成)
・Transformについて Position(5 ,1.5 ,10),Rotation(0 ,0 ,0),Scale(1 ,1 ,1)
子オブジェクト
◎Cube_long(3D Object -> Cubeにて生成)
・Transformについて Position(0 ,0.5 ,-10),Rotation(0 ,0 ,0),Scale(1 ,0.5 ,10) ・Rigidbodyについて Mass->0.1, Drag->0, Angular Drag->0.05,Use Gravity ☑ Freeze Position ☑x☑y☑z
◎Cube_flcrum(3D Object -> Cubeにて生成)
・Transformについて Position(0 ,0.012 ,-10),Rotation(0 ,0 ,0),Scale(1 ,1 ,0.5) ・Rigidbodyについて Mass->1, Drag->0, Angular Drag->0.05, Freeze Position ☑x☑y☑z, Freeze Rotation□x☑y☑z ・Hinge jointについて Connected Body -> Cube_long(Rigidbody) Anchor(0, 0.5, 0),Axis(0, 0, 1), Auto Configure Connected☑ Connected Anchor(0, 0.024000, 0), Use Spring☑, Spring->10, Damper->1, Target Position->0, 他は多分デフォルトです(記憶ですが)
◎Seesaw_SphereA(3D Object -> Sphereにて生成)
・Transformについて Position(0 ,10 ,-14),Rotation(0 ,0 ,0),Scale(1 ,1 ,1) ・Rigidbodyについて Mass->0.1, Drag->0, Angular Drag->0.05,Use Gravity□ ※スクリプト「Seesaw_StartButton」をアタッチしています。 ・SphereColliderについて ※Materiarlに「Bound_Max」という名前のPhysicalMaterialをアタッチしています。 Bound_Maxについて DynamicFriction->0, StaticFriction->0, Bounciness->1
◎Seesaw_SphereB(3D Object -> Sphereにて生成)
・Transformについて Position(0 ,10 ,-6),Rotation(0 ,0 ,0),Scale(1 ,1 ,1) ・Rigidbodyについて Mass->0.1, Drag->0, Angular Drag->0.05,Use Gravity□ ※スクリプト「Seesaw_StartButton」をアタッチしています。 ・SphereColliderについて ※Materiarlに「Bound_Max」という名前のPhysicalMaterialをアタッチしています。
Canvas内のUI
◎Canvas
※スクリプト「Seesaw_RetryButton」をアタッチしています。
◎Dropdown_massA(UI -> Dropdownにて生成)
・Dropdown Options(1)(3)(5)を選択肢としています
◎Dropdown_massB(UI -> Dropdownにて生成)
・Dropdown Options(1)(3)(5)を選択肢としています
◎Dropdown_flcrum(UI -> Dropdownにて生成)
・Dropdown Options(中心)(右に1)(左に1)を選択肢としています
◎StatrButton(UI -> Buttonにて生成)
・Button Onclickにて スクリプト「Seesaw_StartButton」がアタッチされたSeesaw_SphereAを選択し、 プルダウンにて、「Seesaw_StartButton -> OnclickUseGravity()」を選択する。 同様に、スクリプト「Seesaw_StartButton」がアタッチされたSeesaw_SphereBを選択し、 プルダウンにて、「Seesaw_StartButton -> OnclickUseGravity()」を選択する。 ・子オブジェクト(Text -> スタート)
◎RetryButton(UI -> Buttonにて生成)
・Button Onclickにて スクリプト「Seesaw_StartButton」がアタッチされたCanvasを選択し、 プルダウンにて、「Seesaw_RetryButton -> OnclickRetry()」を選択する。 ・子オブジェクト(Text -> やり直し)
◎DropdownManagerA(Create Emptyにて生成)
※スクリプト「DropdownManager_Seesaw」をアタッチしています。 ・DropdownManager_Seesaw(Script) Rb -> Seesaw_SphereA(Rigidbody), Fulcrum -> Cube_flucrum, DropdownComponet_mass -> Dropdown_mass(Dropdown), DropdownComponet_fulcrum -> Dropdown_fulcrum(Dropdown)
◎DropdownManagerB(Create Emptyにて生成)
※スクリプト「DropdownManager_Seesaw」をアタッチしています。 ・DropdownManager_Seesaw(Script) Rb -> Seesaw_SphereB(Rigidbody), Fulcrum -> Cube_flucrum, DropdownComponet_mass -> Dropdown_mass(Dropdown), DropdownComponet_fulcrum -> Dropdown_fulcrum(Dropdown)
◎DropdownManageButton(UI -> Buttonにて生成)
・Button Onclickにて スクリプト「DropdownManager_Seesaw」がアタッチされたDropdownManagerAを選択し、 プルダウンにて、「DropdownManager_Seesaw -> Getvalue()」を選択する。 スクリプト「DropdownManager_Seesaw」がアタッチされたDropdownManagerBを選択し、 プルダウンにて、「DropdownManager_Seesaw -> Getvalue()」を選択する。 ・子オブジェクト(Text -> 反映)
発生している問題・エラーメッセージ
支点にあたるCube_flcrumの座標をシーソーの中心からずらした際にCube_longの挙動がおかしくなり、ボールがおかしなタイミングで跳ねたりします。
また、質量を極端に大きくしてシミュレーションを行うとボールがCube_longをすり抜けてしまいます。
該当のソースコード
◎Seesaw_StartButton.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Seesaw_StartButton : MonoBehaviour { public void OnClickUseGravity() { Rigidbody rd = this.GetComponent<Rigidbody>(); rd.useGravity = true; } }
◎Seesaw_RetryButton.cs
using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class Seesaw_RetryButton : MonoBehaviour { public void OnclickRetry() { SceneManager.LoadScene("SeesawScene"); } }
※シーン名を記述しておりませんでした。「SeesawScene」です。
◎DropdownManager_Seesaw.cs
using UnityEngine; using UnityEngine.UI; using System.Collections; public class DropdownManager_Seesaw : MonoBehaviour { public Rigidbody rb; public GameObject fulcrum; // Inspector [SerializeField] private Dropdown dropdownComponent_mass; [SerializeField] private Dropdown dropdownComponent_fulcrum; // ドロップダウンの値を取得する public void GetValue() { Debug.Log(dropdownComponent_mass.value); Debug.Log(dropdownComponent_fulcrum.value); //質量についてドロップダウンの選択された値に対応する質量を代入 if (dropdownComponent_mass.value == 0) { rb.mass = 0.1f; } else if (dropdownComponent_mass.value == 1) { rb.mass = 0.3f; } else if (dropdownComponent_mass.value == 2) { rb.mass = 0.5f; } //支点の座標についてドロップダウンの選択された値に対応する座標を代入 if (dropdownComponent_fulcrum.value == 0) { Vector3 tmp = fulcrum.transform.position; fulcrum.transform.position = new Vector3(tmp.x, tmp.y, 0); } else if (dropdownComponent_fulcrum.value == 1) { Vector3 tmp = fulcrum.transform.position; fulcrum.transform.position = new Vector3(tmp.x, tmp.y, 1); } else if (dropdownComponent_fulcrum.value == 2) { Vector3 tmp = fulcrum.transform.position; fulcrum.transform.position = new Vector3(tmp.x, tmp.y, -1); } } }
試したこと
①Cube_longがおかしなうごきをすることについて
Hingejointの値を1つずつ変えてみました。
おそらくHingejointの使い方がわかっていないことが原因かと思います。
②ボールがCube_longすり抜けてしまうことについて
おそらくCliderの問題だと思います。
ネットで調べて,それぞれのオブジェクトのRigidbody -> Collision Detection -> Continuousで解決できると書いてあったので試してみましたが解決できませんでした。
補足情報(FW/ツールのバージョンなど)
Microsoft Visual Studio Community 2019
Version 16.6.2
Unity 2019.3.15f1 Personal
PC,Max&Linux Standalone
あなたの回答
tips
プレビュー