0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OculusQuestで凧あげしてみた

0
Posted at

はじめに

OculusQuestで凧あげしてみました。

開発環境

Unity 2019.3.6f1
XR Interaction Toolkit 0.9.3
Oculus XR Plugin 1.2.0

作成方法

凧本体

・Planeオブジェクトを適当な大きさで作成し、RigidbodyコンポーネントとClothコンポーネントをつけます。
・裏面も見えるように、Cull Offにしたシェーダーを設定します。

持ち手

・CUBEオブジェクトを適当な大きさで作成し、Hinge Jointコンポーネントと、XR Grab Interactableコンポーネントをつけます。

・見えないようにしたSphereオブジェクトの間をLine Rendererで線を引いて作ります。なわとびの縄のシミュレーションを参考にさせていただきました。手動だと大変なのでスクリプトを作成しました。

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

[RequireComponent(typeof(LineRenderer))]
public class Rope : MonoBehaviour
{

    [Tooltip("Material for LineRenderer")]
    public Material material;
    [Tooltip("Number of line vertices")]
    public int numVertices = 10;
    [Tooltip("Object at start (RequireComponent(typeof(HingeJoint)))")]
    public GameObject startObject;
    [Tooltip("Object at end (RequireComponent(typeof(Rigidbody)))")]
    public GameObject endObject;
    [Tooltip("Layer name for rope")]
    public string ropeLayer;

    private LineRenderer line;
    private List<GameObject> m_verticesList = new List<GameObject>();

    void Start()
    {
        Vector3 startPosition = new Vector3(0, 0, 0);
        Vector3 endPosition = new Vector3(10.0f, 0, 0);
        int div = numVertices - 1;
        if (startObject != null)
        {
            startPosition = startObject.transform.position;
            div++;
        }
        if (endPosition != null)
        {
            endPosition = endObject.transform.position;
            div++;
        }
        Vector3 space = (endPosition - startPosition) / div;

        Vector3 position = startPosition;
        if (startObject != null)
        {
            startObject.transform.parent = transform;
            m_verticesList.Add(startObject);
            position += space;
        }

        Quaternion rotation = startObject.transform.rotation;
        Vector3 scale = new Vector3(0.1f, 0.1f, 0.1f);
        for (int i = 0; i < numVertices; i++)
        {
            GameObject sphere = CreateSphere(position, rotation, scale);
            if (m_verticesList.Count > 0)
            {
                m_verticesList[m_verticesList.Count - 1].GetComponent<HingeJoint>().connectedBody = sphere.GetComponent<Rigidbody>();
            }
            m_verticesList.Add(sphere);
            position += space;
        }
        if (endObject != null)
        {
            m_verticesList[m_verticesList.Count - 1].GetComponent<HingeJoint>().connectedBody = endObject.GetComponent<Rigidbody>();
            endObject.transform.parent = transform;
            m_verticesList.Add(endObject);
        }

        line = GetComponent<LineRenderer>();
        if (material != null)
        {
            line.material = new Material(material);
        }
    }

    void Update()
    {
        line.positionCount = m_verticesList.Count;
        int idx = 0;
        foreach (GameObject v in m_verticesList)
        {
            line.SetPosition(idx, v.transform.position);
            idx++;
        }
    }

    private GameObject CreateSphere(Vector3 position, Quaternion rotation, Vector3 scale)
    {
        GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        sphere.transform.parent = transform;
        sphere.transform.position = position;
        sphere.transform.rotation = rotation;
        sphere.transform.localScale = scale;
        Rigidbody rb = sphere.AddComponent<Rigidbody>();
        rb.useGravity = true;
        rb.mass = 0.1f;
        rb.drag = 100.0f;
        HingeJoint joint = sphere.AddComponent<HingeJoint>();
        joint.enableCollision = true;
        //JointLimits limits = joint.limits;
        //limits.min = 0;
        //limits.bounciness = 0;
        //limits.bounceMinVelocity = 0;
        //limits.max = 90;
        //joint.limits = limits;
        //joint.useLimits = true;
        JointSpring hingeSpring = joint.spring;
        hingeSpring.spring = 5;
        hingeSpring.damper = 10;
        hingeSpring.targetPosition = 0;
        joint.spring = hingeSpring;
        joint.useSpring = true;
        sphere.GetComponent<MeshRenderer>().enabled = false;
        if (ropeLayer != null)
        {
            sphere.layer = LayerMask.NameToLayer(ropeLayer);
        }
        return sphere;
    }

    public void Add()
    {
        GameObject sphere = m_verticesList[m_verticesList.Count - 1];
        Vector3 position = sphere.transform.position;
        Vector3 prevPosiotion = position;
        position += position - m_verticesList[m_verticesList.Count - 2].transform.position;
        sphere.transform.position = position;

        Quaternion rotation = m_verticesList[m_verticesList.Count - 2].transform.rotation;
        Vector3 scale = new Vector3(0.1f, 0.1f, 0.1f);
        sphere = CreateSphere(prevPosiotion, rotation, scale);
        HingeJoint joint = sphere.GetComponent<HingeJoint>();
        joint.connectedBody = m_verticesList[m_verticesList.Count - 1].GetComponent<Rigidbody>();
        m_verticesList.Insert(m_verticesList.Count - 1, sphere);

        sphere = m_verticesList[m_verticesList.Count - 3];
        joint = sphere.GetComponent<HingeJoint>();
        joint.connectedBody = m_verticesList[m_verticesList.Count - 2].GetComponent<Rigidbody>();
    }
}

・適当なオブジェクトを作成して、上記スクリプトとLine Rendererコンポーネントをつけます。糸は風の影響を受けないようにレイヤーで設定しておくとよいです。
image.png

・凧を持ち上げるために、上方に力を加えるスクリプトを使います。Rigidbodyが風を受けるようにするを参考にさせていただきました。

Wind.cs
using UnityEngine;
using System.Collections;

public class Wind : MonoBehaviour
{
    public float coefficient;   // 空気抵抗係数
    public Vector3 velocity;    // 風速

    void OnTriggerStay(Collider other)
    {
        if (other.attachedRigidbody)
        {
            // 相対速度計算
            var relativeVelocity = velocity - other.attachedRigidbody.velocity;

            // 空気抵抗を与える
            other.attachedRigidbody.AddForce(coefficient * relativeVelocity);
        }
    }
}.cs

・見えないようにしたSphereオブジェクトを適当な大きさで作成し、上記スクリプトをつけます。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?