Unityで、教材を作ってみました。

| Unity の物理演算やら、ハイクォリティなグラフィックを一切役立てない簡素なアプリ


 

 

上の図は、小学4年生ぐらいで習う面積を求める問題。

 

緑の部分を求めなくてはならないのだ。

 

考え方は基本、自由なのだが、もっとも分かりやすく少ない計算量で、回答したいところだ。

 

しかし、計算量を減らそうとすると、アイデアが、必要になる。

 

また、計算量は増えるが、見たままの感じで、4つの緑の部分をそれぞれ計算する方が、考え方は単純である。

 

どちらにせよ、うちの子供はつまずいていた。

 

全体の面積から、白い部分を引き算すればいいのだが、その考え方が理解できなかったらしい。

 

となれば、いろんなパターンを見せて、理解してもらおうとある程度、変動可能な図解を作ってみた。

 

間に合わせなので、デザインの方はご容赦願いたいのだが、色々、作っていくうちに Unity の勉強にもなったので、以下、コードを載せさせていただく。

 

何しろ、初めて完成物を作ったので大目に見ていただきたい。

 

 

 

| 解説


 

まずは、はじめに、適当な四角を用意する。

 

 

そして、UI のスライダーを使って、四角形の縦と横の長さを変更できるようにした。

 

 

以下のスクリプトが、この四角形オブジェクトにアタッチしたもの。

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SquareScale : MonoBehaviour
{

    public GameObject sliderV;
    public GameObject sliderH;

    public float verticalValue;
    public float horizontalValue;
    // Use this for initialization
    void Start()
    {
        sliderV = GameObject.Find("Slider");
        sliderH = GameObject.Find("SliderHorizontal");
    }

    // Update is called once per frame
    void Update()
    {
        SliderScript sliderValueV = sliderV.GetComponent<SliderScript>();
        SliderScriptH sliderValueH = sliderH.GetComponent<SliderScriptH>();
        verticalValue = sliderValueV.value1;
        horizontalValue = sliderValueH.value2;
        //transform.localScale = new Vector2(horizontalValue, verticalValue);

        iTween.ScaleTo(gameObject, iTween.Hash("x", horizontalValue, "y", verticalValue));

    }


}

 

本当は、Update 関数の中には、あまり、多くの処理を書きたくなかったのだけど、とりあえず、挙動は安定していたので、これで、良しとした。

(7年落ちのノートPCはうなりを上げていたが・・・。)

 

iTween を使って、滑らかな動きも入れてみた。(iTween イイ。)

 

 

何より、時間が掛ったのが、白いクロスしたものの挙動。

 

緑の四角形と連動して、長さを変えなくてはならないし、移動範囲もあわせて変動させなくてはならない。

 

もっと、簡単でPCへの負荷も少なくする方法もあるのだろうが、初心者の自分には、まだ、これが、精一杯。

 

以下、白い部分のスクリプト。

 

縦棒の方。(動きが、平行移動になるので、こちらを MoveBoarderH ( Horizonntal ) としている。)

 

 

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

public class MoveBoaderH : MonoBehaviour
{

    public GameObject sliderV;

    public GameObject sliderH;

    public GameObject sliderS;

    public float VerticalValue;

    public float HorizontalValue;

    public float scaleValue;

    void Start()
    {
        sliderV = GameObject.Find("Slider");

        sliderH = GameObject.Find("SliderHorizontal");

        sliderS = GameObject.Find("scaleSlider");
    }

    void Update()
    {
        SliderScript sliderValueV = sliderV.GetComponent<SliderScript>();

        VerticalValue = sliderValueV.value1;

        SliderScriptS slidervalueS = sliderS.GetComponent<SliderScriptS>();

        scaleValue = slidervalueS.valueScale;

        iTween.ScaleTo(gameObject, iTween.Hash("x", scaleValue, "y", VerticalValue));



    }

    void OnMouseDrag()
    {
        Vector3 objectPointInScreen
            = Camera.main.WorldToScreenPoint(this.transform.position); // objectの空間座標をスクリーン座標に変換している。

        Vector3 mousePointInScreen
            = new Vector3(Input.mousePosition.x,
                          objectPointInScreen.y,               // マウスのスクリーン座標を変数に格納している。
                          objectPointInScreen.z);

        Vector3 mousePointInWorld = Camera.main.ScreenToWorldPoint(mousePointInScreen); // マウスのスクリーン座標を空間座標に変換している。
        mousePointInWorld.z = this.transform.position.z;    //  objectの空間座標のz軸をマウスの空間座標のz軸に代入している。つまり、z軸は、移動させていない。
        int m = Mathf.FloorToInt(mousePointInWorld.x);

        SliderScriptH sliderValueH = sliderH.GetComponent<SliderScriptH>();

        HorizontalValue = sliderValueH.value2;

        SliderScriptS slidervalueS = sliderS.GetComponent<SliderScriptS>();

        scaleValue = slidervalueS.valueScale;

       
            if (scaleValue == 1.0f)
            {
                float m1 = Mathf.Clamp(m, -1.0f * HorizontalValue / 2.0f + 0.5f, HorizontalValue / 2.0f - 0.5f);

                this.transform.position = new Vector3(m1, mousePointInWorld.y, mousePointInWorld.z);
            }
            else if (scaleValue == 2.0f)
            {
                float m1 = Mathf.Clamp(m, -1.0f * HorizontalValue / 2.0f + 1.0f, HorizontalValue / 2.0f - 1.0f);

                this.transform.position = new Vector3(m1, mousePointInWorld.y, mousePointInWorld.z);
            }
            else if (scaleValue == 3.0f)
            {
                float m1 = Mathf.Clamp(m, -1.0f * HorizontalValue / 2.0f + 1.5f, HorizontalValue / 2.0f - 1.5f);

                this.transform.position = new Vector3(m1, mousePointInWorld.y, mousePointInWorld.z);
            }
        
    }

}

 

同じく、横棒の方。

 

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

public class MoveBoaderV : MonoBehaviour
{

    public GameObject sliderH;

    public GameObject sliderV;

    public GameObject sliderS;

    public float horizontalValue;

    public float VerticalValue;

    public float scaleValue;

    void Start()
    {
        sliderH = GameObject.Find("SliderHorizontal");

        sliderV = GameObject.Find("Slider");

        sliderS = GameObject.Find("scaleSlider");
    }



    void Update()
    {
        SliderScriptH sliderValueH = sliderH.GetComponent<SliderScriptH>();

        horizontalValue = sliderValueH.value2;

        SliderScriptS slidervalueS = sliderS.GetComponent<SliderScriptS>();

        scaleValue = slidervalueS.valueScale;

        iTween.ScaleTo(gameObject, iTween.Hash("x", horizontalValue, "y", scaleValue));





    }

    void OnMouseDrag()
    {
        Vector3 objectPointInScreen
            = Camera.main.WorldToScreenPoint(this.transform.position);

        Vector3 mousePointInScreen
            = new Vector3(objectPointInScreen.x,
                          Input.mousePosition.y,
                          objectPointInScreen.z);

        Vector3 mousePointInWorld = Camera.main.ScreenToWorldPoint(mousePointInScreen);
        mousePointInWorld.z = this.transform.position.z;
        int m = Mathf.FloorToInt(mousePointInWorld.y);

        SliderScript sliderValueV = sliderV.GetComponent<SliderScript>();

        VerticalValue = sliderValueV.value1;

        SliderScriptS slidervalueS = sliderS.GetComponent<SliderScriptS>();

        scaleValue = slidervalueS.valueScale;


        if (scaleValue == 1.0f)
        {
            float m1 = Mathf.Clamp(m, -1.0f * VerticalValue / 2.0f + 2.0f, VerticalValue / 2.0f + 1.0f);

            this.transform.position = new Vector3(mousePointInWorld.x, m1 + 0.5f, mousePointInWorld.z);
        }
        else if (scaleValue == 2.0f)
        {
            float m1 = Mathf.Clamp(m, -1.0f * VerticalValue / 2.0f + 2.0f + 0.5f, VerticalValue / 2.0f + 1.0f - 0.5f);

            this.transform.position = new Vector3(mousePointInWorld.x, m1 + 0.5f, mousePointInWorld.z);

        }
        else if (scaleValue == 3.0f)
        {
            float m1 = Mathf.Clamp(m, -1.0f * VerticalValue / 2.0f + 2.0f + 1.0f, VerticalValue / 2.0f + 1.0f - 1.0f);

            this.transform.position = new Vector3(mousePointInWorld.x, m1 + 0.5f, mousePointInWorld.z);
        }
       
    }

}

 

白い部分の棒を、ドラッグで移動できるようにした処理は、定型文みたいのを、拾ってきて、それぞれの動きに、制限をかけている。

 

そして、今回、新たな発見というか、とても便利だったのが、Mathf.Clamp(m, -1.0f * VerticalValue / 2.0f + 2.0f + 0.5f, VerticalValue / 2.0f + 1.0f – 0.5f); で、利用している、Math.Clamp 関数なるモノだった。

 

変数そのものに、変化の範囲を指定できるので、かなり、コードを簡略化出来た。

 

後は、適当に、式や値を、テキストで表示すれば、完成。

 

良かったら、お子様の算数の勉強にお役立てください。

 

 

コメント

タイトルとURLをコピーしました