예제 #1
0
    bool CheckCapsuleAtPos(Vector3 pos, Color debugColor, Vector3 fromPos)
    {
        Vector3 spawnPosReal = CollisionUtils.GetGroundedPos(pos);

        Vector3 A = spawnPosReal + Vector3.up * (m_Radius + 0.05f);     // take it little bit over the ground
        Vector3 B = spawnPosReal + Vector3.up * (m_Height - m_Radius);

        int Default      = 1 << LayerMask.NameToLayer("Default");
        int PhysicsMetal = 1 << LayerMask.NameToLayer("PhysicsMetal");

        if (Physics.CheckCapsule(A, B, m_Radius, Default | PhysicsMetal))
        {
            DebugDraw.DisplayTime = 1;
            //DebugDraw.Diamond( debugColor, 0.03f, A );
            //DebugDraw.LineOriented( debugColor, A, B, 0.05f );

            DebugDraw.Capsule(debugColor, m_Radius, A, B);

            //if( fromPos != null )
            {
                DebugDraw.LineOriented(Color.magenta, fromPos, A);
                DebugDraw.LineOriented(Color.magenta, fromPos, B);
                DebugDraw.LineOriented(Color.magenta, fromPos, 0.5f * (A + B));
            }

            return(false);
        }

        return(true);
    }
예제 #2
0
 protected override void OnUpdate()
 {
     for (int i = 0, c = Group.capsules.Length; i < c; i++)
     {
         var capsule = Group.capsules[i];
         var v       = capsule.pB - capsule.pA;
         var center  = capsule.pA + v * 0.5f;
         DebugDraw.Capsule(center, v.normalized, capsule.radius, v.magnitude + capsule.radius * 2, capsule.color);
     }
 }
예제 #3
0
    protected override void OnUpdate()
    {
        var capsuleArray = Group.GetComponentArray <CapsulePrimitive>();

        for (int i = 0, c = capsuleArray.Length; i < c; i++)
        {
            var capsule = capsuleArray[i];
            var v       = capsule.pB - capsule.pA;
            var center  = capsule.pA + v * 0.5f;
            DebugDraw.Capsule(center, v.normalized, capsule.radius, v.magnitude + capsule.radius * 2, capsule.color);
        }
    }
    public void DrawStateAtIndex(int stateIndex, HitCollisionHistory colliderCollection, Color color, float duration)
    {
        for (var i = 0; i < colliderCollection.colliders.Length; i++)
        {
            var bonePosition = buffer[stateIndex].bonePositions[i];
            var boneRotation = buffer[stateIndex].boneRotations[i];

            var worldPos = boneRotation * colliderCollection.colliders[i].localPosition + bonePosition;
            var worldRot = boneRotation * colliderCollection.colliders[i].localRotation;


            var capsuleCollider = colliderCollection.colliders[i].collider as CapsuleCollider;
            if (capsuleCollider != null)
            {
                DebugDraw.Capsule(worldPos, worldRot * Vector3.up, capsuleCollider.radius, capsuleCollider.height, color, duration);
            }
        }
    }
예제 #5
0
    //collide camera and place it to the best position
    void CollideCamera5()
    {
        //
#if CAMERA_DEBUG_DRAW
        Color col;
#endif

        Transform desiredTransform = CameraBehaviour.GetDesiredCameraTransform();
        if (desiredTransform)
        {
            Vector3    desiredPosition = desiredTransform.position;
            Quaternion desiredRotation = desiredTransform.rotation;

            float dif = (desiredPosition - PrevPos).sqrMagnitude;

#if !CAMERA_DEBUG_DRAW //disable the optimization when Debug Draw is on
            //exit if the camera didn't move or rotate
            if (dif < 0.0001f &&
                Mathf.Approximately(PrevRot.x, desiredRotation.x) &&
                Mathf.Approximately(PrevRot.y, desiredRotation.y) &&
                Mathf.Approximately(PrevRot.z, desiredRotation.z) &&
                Mathf.Approximately(PrevRot.w, desiredRotation.w))
            {
                return;
            }
#endif

            //blend the transform (this is useful especially when the CameraState changes or when the camera moves very fast)
            if (dif > 0.1f)
            {
                desiredPosition = Vector3.Lerp(PrevPos, desiredPosition, Time.deltaTime * 20);
                desiredRotation = Quaternion.Slerp(PrevRot, desiredRotation, Time.deltaTime * 20);
            }

            PrevPos = desiredPosition;
            PrevRot = desiredRotation;

            Vector3 FinalPos;

            //pokud je jiny CameraState nez CameraState3RD, tak muzeme nasledujici testy preskocit a jen nastavit CameraTransform.position a CameraTransform.rotation a zavolat UpdateLocalPlayerInstance();
//			if ( (CameraBehaviour.State is CameraState3RD) || (CameraBehaviour.State is CameraStateCover) || (CameraBehaviour.State is CameraStateDeath) )
            {
                LayerMask mask = ObjectLayerMask.Default | ObjectLayerMask.PhysicsMetal;
                //~( ObjectLayerMask.Ragdoll | ObjectLayerMask.IgnoreRayCast | ObjectLayerMask.PhysicBody );
                const float minNear   = 0.02f;               //0.05f still penetrates walls while rolling
                const float minRadius = 0.12f;               //0.1f
                const float maxRadius = 0.3f;                //with 0.5f the camera collides too often when player runs close to obstacles
                bool        IsRolling = CameraBehaviour.Owner.PlayerComponent.IsRolling;
                bool        IsAlive   = CameraBehaviour.Owner.IsAlive;
                float       radius    = IsRolling ? minRadius : maxRadius;        //in dodge, use minRadius for collisions

                //for testing collision between Head and TargetPos ("CameraTargetDir" node)
                Vector3 HeadPos   = CameraBehaviour.Owner.EyePosition;
                Vector3 TargetPos = CameraBehaviour.CameraOrigin.position;
                Vector3 headDir   = TargetPos - HeadPos;

                //shift the HeadPos to not allow the camera to move into player's head
                HeadPos += headDir * 0.5f;               //middle point between head and target
                headDir  = TargetPos - HeadPos;

                float      headLength = headDir.magnitude;
                RaycastHit headHit;

#if CAMERA_DEBUG_DRAW
                DebugDraw.Line(Color.magenta, HeadPos, TargetPos + headDir.normalized * radius);                                //c
                DebugDraw.Diamond(Color.magenta, 0.03f, TargetPos);
                DebugDraw.Diamond(Color.green, 0.03f, desiredPosition);
#endif

                //check whether the TargetPos is behind collision or not (it is controlled by animation and usually is outside the player's capsule collider)
                //this happens when players 'shoulder' (i.e. the "CameraTargetDir") gets behind a wall
                if (Physics.Raycast(HeadPos, headDir, out headHit, headLength + radius, mask))
                {
                    float m = Mathf.Max(0, headHit.distance - radius);
                    TargetPos = HeadPos + headDir.normalized * m;                   //move the TargetPos along the line to a safe place

                    if (headHit.distance < radius)
                    {
                        radius = Mathf.Max(minRadius, headHit.distance - 0.001f);                         //change the radius based on the collision distance
                    }
#if CAMERA_DEBUG_DRAW
                    DebugDraw.Diamond(Color.cyan, 0.03f, headHit.point);
                    DebugDraw.Diamond(Color.white, 0.03f, TargetPos);                                              //new TargetPos

                    DebugDraw.Line(Color.green, headHit.point, headHit.point + headHit.normal * (radius + 0.01f)); //b
                    DebugDraw.Line(Color.yellow, headHit.point + headHit.normal * (radius + 0.01f), TargetPos);
#endif
                }

                //
                Vector3     dir = desiredPosition - TargetPos;
                Vector3     dirN = dir.normalized;
                float       length = dir.magnitude;
                float       q, dist;
                const float safeDist = maxRadius + 0.1f;                 //shift the capsule in front of the TargetPos a little

                //do the sphere (capsule) collision with scene
                RaycastHit[] hits = Physics.SphereCastAll(TargetPos - dirN * safeDist, radius, dirN, length + safeDist, mask);

                //sort by distance
                if (hits.Length > 1)
                {
                    System.Array.Sort(hits, CollisionUtils.CompareHits);
                }

                //			FinalPos        = desiredPosition;
                dist = length;                                             //default position at the desiredPosition if we will not collide
                MainCamera.nearClipPlane = Mathf.Max(0.2f, radius * 0.5f); //radius * 0.5f;				//was 0.3f;

                foreach (RaycastHit hit in hits)
                {
                    if (hit.collider.gameObject.layer == InteractionObject.UseLayer)
                    {
                        continue;
                    }

                    if (hit.collider.isTrigger)
                    {
                        continue;
                    }

                    if (hit.collider == IgnoredCollider)
                    {
                        continue;
                    }

                    //				FinalPos = hit.point + hit.normal * minRadius;		//was 0.3f; changed to 0.1f to help fix the camera-player intersection (when player was running backwards against wall)
                    dist = Mathf.Min(length, hit.distance + radius - safeDist - minRadius);

                    if (dist < 0)                     //can become < 0 due to safeDist
                    {
                        dist = 0;
                    }

                    //				FinalPos = TargetPos + dirN * q;
                    MainCamera.nearClipPlane = (IsRolling || !IsAlive) ? minNear : 0.2f;
                    //0.02f;							//was 0.05f; the new value needs testing on devices (check z-fight)

#if CAMERA_DEBUG_DRAW
                    col = Color.grey; col.a = 0.5f;
                    Debug.DrawLine(desiredPosition, TargetPos, col, 0.5f);
                    DebugDraw.Diamond(Color.red, 0.03f, hit.point);

                    col = Color.gray; col.a = 0.5f;
                    DebugDraw.Capsule(col, radius, TargetPos - dirN * safeDist, TargetPos + dirN * length);
#endif

                    break;                     //need to care just about the nearest valid hit
                }

                //
                float ratio = (Mathf.Abs(PrevDist - dist) / length) + (1 - (radius - minRadius) / maxRadius);

                if (PrevDist < dist)                 //we're returning back - do it slower
                {
                    ratio *= 0.5f;
                }

                float speed = Mathf.Clamp(ratio, 0.2f, 1.0f) * 25;
                //change the blend speed based on the distance between actual and computed distance (position)

                q = Mathf.Lerp(PrevDist, dist, Time.deltaTime * speed);               //smoothly blend between previous and current position

                //			if ( Mathf.Abs(PrevDist - dist) > 0.01f )
                //				Debug.Log ("radius=" + radius + ", dist=" + dist + ", PrevDist=" + PrevDist + ", ratio=" + ratio + ", q=" + q + ", speed=" + speed);

                PrevDist = q;

#if CAMERA_DEBUG_DRAW
                DebugDraw.Diamond(Color.yellow, 0.03f, TargetPos + dirN * dist);                                //where we need to be (we're interpolating to this pos)
#endif

                //set Final Position
                FinalPos = TargetPos + dirN * q;
            }
//			else
//			{
//				FinalPos = desiredPosition;
//			}

            //set Final Position
            CameraTransform.position = FinalPos;

            //CameraTransform.rotation = Quaternion.Lerp(CameraTransform.rotation, desiredRotation, 15.0f * Time.deltaTime);
            CameraTransform.rotation = desiredRotation;

            //
#if CAMERA_DEBUG_DRAW
            col = Color.yellow; col.a = 0.5f;
            DebugDraw.Diamond(col, 0.03f, FinalPos);
#endif

            UpdateLocalPlayerInstance();
        }
    }