Top/Devel/Unity/2点指定でCylinderを生成する

2点指定でCylinderを生成するはてなブックマーク

Unityは円柱(Cylinder)のプリミティブをデフォルトで持っており、
メニューやコードから生成することができるが、
通常、円柱の2つの端点を指定して生成することはできない。


これをできるようにしたのが下記のUnityパッケージ。



コードはこんな感じ。

fileCylinderBetweenTwoPoints.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CylinderBetweenTwoPoints : MonoBehaviour {
    [SerializeField]
    private Transform cylinderPrefab;

    private GameObject leftSphere;
    private GameObject rightSphere;
    private GameObject cylinder;

    private void Start () {
        leftSphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        rightSphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        leftSphere.transform.position = new Vector3(-1, 0, 0);
        rightSphere.transform.position = new Vector3(1, 0, 0);

        InstantiateCylinder(cylinderPrefab, leftSphere.transform.position, rightSphere.transform.position);
    }

    private void Update () {
        leftSphere.transform.position = new Vector3(-1, -2f * Mathf.Sin(Time.time), 0);
        rightSphere.transform.position = new Vector3(1, 2f * Mathf.Sin(Time.time), 0);

        UpdateCylinderPosition(cylinder, leftSphere.transform.position, rightSphere.transform.position);
    }

    private void InstantiateCylinder(Transform cylinderPrefab, Vector3 beginPoint, Vector3 endPoint)
    {
        cylinder = Instantiate<GameObject>(cylinderPrefab.gameObject, Vector3.zero, Quaternion.identity);
        UpdateCylinderPosition(cylinder, beginPoint, endPoint);
    }

    private void UpdateCylinderPosition(GameObject cylinder, Vector3 beginPoint, Vector3 endPoint)
    {
        Vector3 offset = endPoint - beginPoint;
        Vector3 position = beginPoint + (offset / 2.0f);

        cylinder.transform.position = position;
        cylinder.transform.LookAt(beginPoint);
        Vector3 localScale = cylinder.transform.localScale;
        localScale.z = (endPoint - beginPoint).magnitude;
        cylinder.transform.localScale = localScale;
    }
}


ただし、上記コードに与える円柱プレハブは、通常のプリミティブの円柱ではNG。

というのも、円柱の方向が求めている方向と異なるため。


これについては、プリミティブを作成し求める方向に回転させた後、
下記のようにしてメッシュをアセットとして保存すれば、解消する。

AssetDatabase.CreateAsset(mesh, path);
AssetDatabase.SaveAssets();


なお、 今回は簡単のために、テラシュールブログさんのMeshCombiner.csを使用した。


アセットとして保存するプリミティブをカプセル(Capsule)にすれば、カプセルも2点指定で生成することができる。

利用例

参考

Amazon

差分 一覧