Example #1
0
 private void DrawWavesOnHit(ICollection <ForceFieldEffectInstanceNode> effects, Vector3 hitPosition, bool playSound)
 {
     foreach (ForceFieldEffectInstanceNode node in effects)
     {
         ForceFieldEffect component         = node.effectInstance.GameObject.GetComponent <ForceFieldEffect>();
         MeshCollider     outerMeshCollider = component.outerMeshCollider;
         if (Vector3.Distance(hitPosition, outerMeshCollider.ClosestPointOnBounds(hitPosition)) < 0.1f)
         {
             component.DrawWave(hitPosition, playSound);
         }
     }
 }
        public static void PushOutFromMesh(MeshCollider mesh, Collision collision, float pointRadius, ref Vector3 point)
        {
            Vector3 closest;
            float   plus = 0f;

            closest = mesh.ClosestPointOnBounds(point);
            plus    = (closest - mesh.transform.position).magnitude;

            bool  inside    = false;
            float insideMul = 1f;

            if (closest == point)
            {
                inside    = true;
                insideMul = 7f;
                closest   = mesh.transform.position;
            }

            Vector3 targeting    = closest - point;
            Vector3 rayDirection = targeting.normalized;
            Vector3 rayOrigin    = point - rayDirection * (pointRadius * 2f + mesh.bounds.extents.magnitude);

            float rayDistance = targeting.magnitude + pointRadius * 2f + plus + mesh.bounds.extents.magnitude;

            if ((point - closest).magnitude < pointRadius * insideMul)
            {
                Vector3 collisionPoint;

                if (!inside)
                {
                    collisionPoint = collision.contacts[0].point;
                }
                else
                {
                    Ray        ray = new Ray(rayOrigin, rayDirection);
                    RaycastHit hit;
                    if (mesh.Raycast(ray, out hit, rayDistance))
                    {
                        collisionPoint = hit.point;
                    }
                    else
                    {
                        collisionPoint = collision.contacts[0].point;
                    }
                }

                float hitToPointDist = (point - collisionPoint).magnitude;

                if (hitToPointDist < pointRadius * insideMul)
                {
                    Vector3 toNormal = collisionPoint - point;
                    Vector3 pushNormal;

                    if (inside)
                    {
                        pushNormal = toNormal + toNormal.normalized * pointRadius;
                    }
                    else
                    {
                        pushNormal = toNormal - toNormal.normalized * pointRadius;
                    }

                    float dot = Vector3.Dot((collisionPoint - point).normalized, rayDirection);
                    if (inside && dot > 0f)
                    {
                        pushNormal = toNormal - toNormal.normalized * pointRadius;
                    }

                    point = point + pushNormal;
                }
            }
        }
        void FeedBack()
        {
            if (boundSpheres != null)
            {
                // 遍历自身所有碰撞球,若与外物有碰撞,则计算“力”反馈后的位置
                for (int i = 0; i < boundSpheres.Length; ++i)
                {
                    BoundSphere sphere = boundSpheres[i];

                    if (sphere == null)
                    {
                        continue;
                    }

                    foreach (Collider collider in Physics.OverlapSphere(OffsetPosition(sphere.offset), sphere.radius, _collidable))
                    {
                        Vector3 position     = OffsetPosition(sphere.offset);
                        Vector3 contactPoint = Vector3.zero;

                        if (collider.gameObject == _target.gameObject)
                        {
                            continue; // 排除自身
                        }

                        if (collider.isTrigger)
                        {
                            continue;
                        }

                        if (collider is BoxCollider)
                        {
                            contactPoint = TransformTools.Instance.ClosestPoint((BoxCollider)collider, position);
                        }
                        else if (collider is SphereCollider)
                        {
                            contactPoint = TransformTools.Instance.ClosestPoint((SphereCollider)collider, position);
                        }
                        else if (collider is MeshCollider)
                        {
                            TriangleTreeMgr ttm = collider.GetComponent <TriangleTreeMgr>();
                            if (ttm == null)
                            {
                                ttm = collider.gameObject.AddComponent <TriangleTreeMgr>();
                            }
                            if (ttm != null)
                            {
                                contactPoint = ttm.ClosestPointOn(position, sphere.radius, displayDebugInfo, displayExtendedDebugInfo);
                            }
                            else
                            {
                                // Make last ditch try for convex colliders
                                MeshCollider mc = (MeshCollider)collider;
                                if (mc.convex)
                                {
                                    contactPoint = mc.ClosestPointOnBounds(position);
                                }
                                else
                                {
                                    continue;
                                }
                            }
                        }
                        else if (collider is CapsuleCollider)
                        {
                            contactPoint = TransformTools.Instance.ClosestPoint((CapsuleCollider)collider, position);
                        }
                        else if (collider is TerrainCollider)
                        {
                            // 无须处理,地面和foot的碰撞检测在其它模块
                        }
                        else if (collider is WheelCollider)
                        {
                            Debug.LogWarning("[Moter] WheelColliders not supported");
                        }
                        else
                        {
                            continue;
                        }

                        if (contactPoint != Vector3.zero)
                        {
                            // If the sphere is feet
                            // We have a ground and we're touching
                            // And the sphere position is above the contact position
                            // We should ignore it
                            if (sphere.isFeet && IsOnGround && position.y > contactPoint.y)
                            {
                                continue;
                            }

                            // If this is the head sphere
                            // And we're jumping
                            // And we hit the "top" of the sphere, abort jumping
                            if (sphere.isHead && IsJumping && contactPoint.y > (position.y + sphere.radius * 0.25f))
                            {
                                JumpDone(null);
                            }

                            // Vector from contact point to position
                            Vector3 v = position - contactPoint;

                            // Draw debug line
                            if (displayDebugInfo)
                            {
                                Debug.DrawLine(position, contactPoint, Color.red);
                            }

                            // Display extend debug info
                            if (displayExtendedDebugInfo)
                            {
                                Debug.Log("[Moter] Contact point " + contactPoint);
                            }

                            // Move object away from collision
                            _target.position += Vector3.ClampMagnitude(v, Mathf.Clamp(sphere.radius - v.magnitude, 0, sphere.radius));
                        }
                    }
                }
            }
        }
Example #4
0
    void PushBack()
    {
        if (spheres != null)
        {
            for (int i = 0; i < spheres.Length; ++i)
            {
                CollisionSphere s = spheres[i];

                if (s != null)
                {
                    foreach (Collider collider in Physics.OverlapSphere(OffsetPosition(s.Offset), bodyRadius, walkable))
                    {
                        Vector3 position     = OffsetPosition(s.Offset);
                        Vector3 contactPoint = Vector3.zero;

                        if (collider is BoxCollider)
                        {
                            contactPoint = RPGCollisions.ClosestPointOn((BoxCollider)collider, position);
                        }
                        else if (collider is SphereCollider)
                        {
                            contactPoint = RPGCollisions.ClosestPointOn((SphereCollider)collider, position);
                        }
                        else if (collider is MeshCollider)
                        {
                            RPGMesh rpgMesh = collider.GetComponent <RPGMesh>();

                            if (rpgMesh != null)
                            {
                                contactPoint = rpgMesh.ClosestPointOn(position, bodyRadius, displayDebugInfo, displayExtendedDebugInfo);
                            }
                            else
                            {
                                // Make last ditch try for convex colliders
                                MeshCollider mc = (MeshCollider)collider;

                                if (mc.convex)
                                {
                                    contactPoint = mc.ClosestPointOnBounds(position);
                                }
                                else
                                {
                                    continue;
                                }
                            }
                        }
                        else if (collider is CapsuleCollider)
                        {
                            Debug.LogWarning("[RPGMotor] CapsuleCollider not supported");
                        }
                        else if (collider is TerrainCollider)
                        {
                        }
                        else if (collider is WheelCollider)
                        {
                            Debug.LogWarning("[RPGMotor] WheelColliders not supported");
                        }
                        else
                        {
                            continue;
                        }

                        if (contactPoint != Vector3.zero)
                        {
                            // If the sphere is feet
                            // We have a ground and we're touching
                            // And the sphere position is above the contact position
                            // We should ignore it
                            if (s.IsFeet && HasGround && CurrentGround.IsTouching && position.y > contactPoint.y)
                            {
                                continue;
                            }

                            // If this is the head sphere
                            // And we're jumping
                            // And we hit the "top" of the sphere, abort jumping
                            if (s.IsHead && IsJumping && contactPoint.y > (position.y + bodyRadius * 0.25f))
                            {
                                JumpDone(null);
                            }

                            // Vector from contact point to position
                            Vector3 v = position - contactPoint;

                            // Draw debug line
                            if (displayDebugInfo)
                            {
                                Debug.DrawLine(position, contactPoint, Color.red);
                            }

                            // Display extend debug info
                            if (displayExtendedDebugInfo)
                            {
                                Debug.Log("[RPGMotor] Contact point " + contactPoint);
                            }

                            // Move object away from collision
                            target.position += Vector3.ClampMagnitude(v, Mathf.Clamp(bodyRadius - v.magnitude, 0, bodyRadius));
                        }
                    }
                }
            }
        }
    }
Example #5
0
    void PushBack()
    {
        if (spheres != null)
        {
            for (int i = 0; i < spheres.Length; ++i)
            {
                CollisionSphere s = spheres[i];

                if (s != null)
                {
                    foreach (Collider collider in Physics.OverlapSphere(OffsetPosition(s.Offset), bodyRadius, walkable))
                    {
                        Vector3 position     = OffsetPosition(s.Offset);
                        Vector3 contactPoint = Vector3.zero;

                        if (collider is BoxCollider)
                        {
                            contactPoint = RPGCollisions.ClosestPointOn((BoxCollider)collider, position);
                        }
                        else if (collider is SphereCollider)
                        {
                            contactPoint = RPGCollisions.ClosestPointOn((SphereCollider)collider, position);
                        }
                        else if (collider is MeshCollider)
                        {
                            RPGMesh rpgMesh = collider.GetComponent <RPGMesh>();

                            if (rpgMesh != null)
                            {
                                contactPoint = rpgMesh.ClosestPointOn(position, bodyRadius, displayDebugInfo, displayExtendedDebugInfo);
                            }
                            else
                            {
                                MeshCollider mc = (MeshCollider)collider;

                                if (mc.convex)
                                {
                                    contactPoint = mc.ClosestPointOnBounds(position);
                                }
                                else
                                {
                                    continue;
                                }
                            }
                        }
                        else if (collider is CapsuleCollider)
                        {
                        }
                        else if (collider is TerrainCollider)
                        {
                        }
                        else if (collider is WheelCollider)
                        {
                            Debug.LogWarning("[RPGMotor] WheelColliders not supported");
                        }
                        else
                        {
                            continue;
                        }

                        if (contactPoint != Vector3.zero)
                        {
                            //如果这个sphere是脚
                            //我们接触一个地面
                            //并且球的位置在接触位置之上
                            //我们应该忽略它
                            if (s.IsFeet && HasGround && CurrentGround.IsTouching && position.y > contactPoint.y)
                            {
                                continue;
                            }

                            //如果这个球是头
                            //并且跳跃
                            //并且撞到了头,就终止跳跃
                            if (s.IsHead && IsJumping && contactPoint.y > (position.y + bodyRadius * 0.25f))
                            {
                                JumpDone(null);
                            }

                            Vector3 v = position - contactPoint;

                            if (displayDebugInfo)
                            {
                                Debug.DrawLine(position, contactPoint, Color.red);
                            }

                            if (displayExtendedDebugInfo)
                            {
                                //Debug.Log("[RPGMotor] Contact point " + contactPoint);
                            }

                            target.position += Vector3.ClampMagnitude(v, Mathf.Clamp(bodyRadius - v.magnitude, 0, bodyRadius));
                        }
                    }
                }
            }
        }
    }
Example #6
0
 /// <summary>
 /// 获取MeshCollider上距离target最近的点(不能用!没效果)
 /// </summary>
 public Vector3 ClosestPoint(MeshCollider collider, Vector3 target)
 {
     return(collider.ClosestPointOnBounds(target)); // (不能用!没效果)
 }