归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
阅读:472回复:0

Google ARCore开发教程3-物理特性

楼主#
更多 发布于:2017-09-02 22:11

图片:20170902_162235.mp4_20170902_220546.170.png



Unity中物理引擎内容比较丰富,本节中介绍的物理特性主要是刚体和碰撞体。
首先在Unity中实现简单的自由落体与碰撞

图片:clipboard.png

图片:clipboard1.png



场景中新建一个plane,调整到合适位置和大小。
创建一个Cube的prefab,并指定Rigidbody,制作一个刚体。
然后将以下脚本绑定到Main Camera中即可。


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

public class DropObjects : MonoBehaviour {
    public GameObject andy;
        // Use this for initialization
        void Start () {
                
        }
        
        // Update is called once per frame
        void Update () {
        if (Input.GetMouseButtonDown(0))
        {
            Instantiate(andy, Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10.0f)), Quaternion.identity);
        }
        }
}


这样就在Unity里简单实现了一个体现刚体和碰撞的小例子。

同样,在ARCore的工程中,给TrackedPlaneVisualizer加上MeshCollider
新建一个预制体NewAndy,将Andy作为其子系,并调整Andy的localposition使其Y轴有个高度,从而实现自由落体的效果。

图片:clipboard2.png



图片:clipboard3.png




另外给Andy加上Rigidbody和Box Collider。

图片:clipboard4.png



最后修改TrackedPlaneVisualizer.cs脚本如下:

//-----------------------------------------------------------------------
// <copyright file="TrackedPlaneComponent.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------

namespace GoogleARCore.HelloAR
{
    using System.Collections.Generic;
    using UnityEngine;
    using GoogleARCoreInternal;

    /// <summary>
    /// Visualizes a TrackedPlane in the Unity scene.
    /// </summary>
    public class TrackedPlaneVisualizer : MonoBehaviour
    {
        /// <summary>
        /// The ARCore tracked plane to represent.
        /// </summary>
        private TrackedPlane m_trackedPlane;

        private List<Vector3> m_meshVertices = new List<Vector3>();

        private List<Color> m_meshColors = new List<Color>();

        private List<int> m_meshIndices = new List<int>();

        private Mesh m_mesh;

        private MeshRenderer m_meshRenderer;
       private MeshCollider _meshCollider;

        public bool makePhysics = true;


        /// <summary>
        /// The Unity Awake() method.
        /// </summary>
        private void Awake()
        {
            m_mesh = GetComponent<MeshFilter>().mesh;
            m_meshRenderer = GetComponent<UnityEngine.MeshRenderer>();
        }

        /// <summary>
        /// The Unity Update() method.
        /// </summary>
        private void Update()
        {
            if (m_trackedPlane == null)
            {
                return;
            }
            else if (m_trackedPlane.SubsumedBy != null)
            {
                Destroy(gameObject);
                return;
            }
            else if (!m_trackedPlane.IsValid || Frame.TrackingState != FrameTrackingState.Tracking)
            {
                 m_meshRenderer.enabled = false;
                 return;
            }

            m_meshRenderer.enabled = true;
            if (m_trackedPlane.IsUpdated)
            {
                _UpdateMeshWithCurrentTrackedPlane();
            }
        }

        /// <summary>
        /// Update the TrackedPlane reference.
        /// </summary>
        /// <param name="plane">The TrackedPlane reference..</param>
        public void SetTrackedPlane(TrackedPlane plane)
        {
            m_trackedPlane = plane;
            _UpdateMeshWithCurrentTrackedPlane();
        }

        private void _UpdateMeshWithCurrentTrackedPlane()
        {
            // Note that GetBoundaryPolygon returns points in clockwise order.
            m_trackedPlane.GetBoundaryPolygon(ref m_meshVertices);

            Vector3 planeCenter = m_trackedPlane.Position;
            int planePolygonCount = m_meshVertices.Count;

            // The following code convert a polygon to a mesh with two polygons, inner
            // polygon renders with 100% opacity and fade out to outter polygon with opacity 0%, as shown below.
            // The indices shown in the diagram are used in comments below.
            // _______________     0_______________1
            // |             |      |4___________5|
            // |             |      | |         | |
            // |             | =>   | |         | |
            // |             |      | |         | |
            // |             |      |7-----------6|
            // ---------------     3---------------2
            m_meshColors.Clear();

            // Fill transparent color to vertices 1 to 3.
            for (int i = 0; i < planePolygonCount; ++i)
            {
                m_meshColors.Add(new Color(0.0f, 0.0f, 0.0f, 0.0f));
            }

            // Feather distance 0.2 meters.
            const float FEATHER_LENGTH = 0.2f;

            // Feather scale over the distance between plane center and vertices.
            const float FEATHER_SCALE = 0.2f;

            // Add vertex 4 to 5.
            for (int i = 0; i < planePolygonCount; ++i)
            {
                Vector3 v = m_meshVertices;

                // Vector from plane center to current point
                Vector3 d = v - planeCenter;

                float scale = 1.0f - Mathf.Min((FEATHER_LENGTH / d.magnitude), FEATHER_SCALE);
                m_meshVertices.Add(scale * d + planeCenter);

                m_meshColors.Add(new Color(0.0f, 0.0f, 0.0f, 1.0f));
            }

            m_meshIndices.Clear();
            int verticeLength = m_meshVertices.Count;
            int verticeLengthHalf = verticeLength / 2;
            // Generate triangle (4, 5, 6) and (4, 6, 7).
            for (int i = verticeLengthHalf + 1; i < verticeLength - 1; ++i)
            {
                m_meshIndices.Add(verticeLengthHalf);
                m_meshIndices.Add(i);
                m_meshIndices.Add(i + 1);
            }

            // Generate triangle (0, 1, 4), (4, 1, 5), (5, 1, 2), (5, 2, 6), (6, 2, 3), (6, 3, 7)
            // (7, 3, 0), (7, 0, 4)
            for (int i = 0; i < verticeLengthHalf; ++i)
            {
                m_meshIndices.Add(i);
                m_meshIndices.Add((i + 1) % verticeLengthHalf);
                m_meshIndices.Add(i + verticeLengthHalf);

                m_meshIndices.Add(i + verticeLengthHalf);
                m_meshIndices.Add((i + 1) % verticeLengthHalf);
                m_meshIndices.Add((i + verticeLengthHalf + 1) % verticeLengthHalf + verticeLengthHalf);
            }

            m_mesh.Clear();
            m_mesh.SetVertices(m_meshVertices);
            m_mesh.SetIndices(m_meshIndices.ToArray(), MeshTopology.Triangles, 0);
            m_mesh.SetColors(m_meshColors);

           if (makePhysics)
            {
                if (_meshCollider == null)
                {
                    _meshCollider = GetComponent<MeshCollider>();
                }

                // Cheap Hack to make MeshCollider update its mesh. Really not efficient
                _meshCollider.sharedMesh = null;
                _meshCollider.enabled = false;
                _meshCollider.enabled = true;
                _meshCollider.sharedMesh = m_mesh;
            }
        }

    }
}

最终效果截图:

图片:20170902_162235.mp4_20170902_223150.812.png

图片:20170902_162235.mp4_20170902_223205.128.png

图片:20170902_162235.mp4_20170903_102500.gif






视频案例:
https://v.qq.com/x/page/m0545zunmkq.html

工程源码:

链接:http://pan.baidu.com/s/1nuLdVtB 密码:
此帖售价 2 铜币,已有 0 人购买 [记录] [购买]
此段为出售的内容,购买后显示
AR学院(www.arvrschool.com),从这里感触未来!

欢迎分享

游客

返回顶部