예제 #1
0
    void OnDrawGizmosSelected()
    {
        if (!m_showGuides)
        {
            return;
        }

        float maxWalkSpeed = m_platformPhysics.SolveMaxSpeedWithAccAndDrag(WalkingAcc, WalkingDrag);

        maxWalkSpeed = Mathf.Min(maxWalkSpeed, MaxWalkingSpeed);

        if (m_jumpingGuideMode == eJumpingGuideMode.MovingDirection)
        {
            if (m_platformPhysics.HSpeed > 0.1f * maxWalkSpeed)
            {
                m_simulatedMovingDir = 1f;
            }
            else if (m_platformPhysics.HSpeed < -0.1f * maxWalkSpeed)
            {
                m_simulatedMovingDir = -1f;
            }
        }
        else if (m_jumpingGuideMode == eJumpingGuideMode.Right)
        {
            m_simulatedMovingDir = 1f;
        }
        else if (m_jumpingGuideMode == eJumpingGuideMode.Left)
        {
            m_simulatedMovingDir = -1f;
        }

        if (!Application.isPlaying || IsGrounded || IsClimbing)
        {
            m_jumpingGuideBasePos = transform.position;
        }

        if (Application.isPlaying)
        {
            if (IsGrounded || IsClimbing)
            {
                m_simulatedStartingHSpeed = m_platformPhysics.HSpeed;
            }
        }
        else
        {
            m_simulatedStartingHSpeed = maxWalkSpeed;
        }

        Vector3 simulationPos   = m_jumpingGuideBasePos + m_jumpingGuideOffset;
        float   maxHDist        = 0f;
        float   minHoldJumpTime = Time.fixedDeltaTime;
        int     iters           = Mathf.CeilToInt(JumpingAccTime / minHoldJumpTime) + 1;
        float   jumpingAccTime  = 0;
        float   timeDt          = Time.fixedDeltaTime;

        PlatformCharacterPhysics physics = new PlatformCharacterPhysics(m_platformPhysics);

        for (int iter = 0; iter < iters; ++iter, jumpingAccTime += minHoldJumpTime)
        {
            physics.Position  = Vector3.zero;
            physics.HDrag     = WalkingDrag;
            physics.MaxHSpeed = MaxWalkingSpeed;
            physics.Velocity  = new Vector3(m_simulatedStartingHSpeed, JumpingSpeed);
            float time          = 0f;
            float maxWhileIters = 1000;
            do
            {
                Vector3 prevPos = physics.Position;
                physics.AddAcceleration(m_simulatedMovingDir * Vector2.right * AirborneAcc);
                if (time < jumpingAccTime)
                {
                    physics.Acceleration += transform.up * m_jumpingAcc;
                }
                time += timeDt;
                float timeToGround = physics.SolveTimeToPosY(0f);
                if (timeToGround >= timeDt)
                {
                    physics.UpdatePhysics(timeDt);
                }
                else
                {
                    physics.UpdatePhysics(timeToGround);
                    physics.Position = new Vector3(physics.Position.x, 0f); // for float imprecisions, pos.y will me almost but not equal to 0f. This will end the loop.
                }

                Gizmos.color = Color.Lerp(new Color(0f, 1f, 0f, 0.2f), new Color(0f, 1f, 0f, 0.5f), 1f - (iter + 1f) / iters);
                Gizmos.DrawLine(prevPos + simulationPos, physics.Position + simulationPos);
                // Draw max and min high line depending on
                if (iter == 0 || iter == iters - 1)
                {
                    Gizmos.color = new Color(0f, 0f, 0f, 0.2f);
                    Gizmos.DrawSphere(prevPos + simulationPos, 0.03f * GizmoUtils.GetGizmoSize(prevPos + simulationPos));
                }
            }while (physics.Position.y > 0 && --maxWhileIters > 0);
            //Debug.Assert(maxIters > 0, "Infinite loop detected!");
            Gizmos.DrawSphere(physics.Position + simulationPos, 0.03f * GizmoUtils.GetGizmoSize(physics.Position + simulationPos));
            maxHDist = Mathf.Max(maxHDist, Mathf.Abs(physics.Position.x));
        }
        maxHDist *= m_simulatedMovingDir;
        float minJumpHeight = physics.SolveMaxJumpHeight(m_jumpingSpeed);
        float maxJumpHeight = physics.SolveMaxJumpHeight(m_jumpingSpeed, m_jumpingAcc, m_jumpingTime);

        Gizmos.color = new Color(1f, 1f, 0f, 1f);
        Gizmos.DrawLine(simulationPos + new Vector3(-maxHDist * .25f, minJumpHeight), simulationPos + new Vector3(maxHDist * .75f, minJumpHeight));
        Gizmos.color = new Color(1f, 1f, 0f, 1f);
        Gizmos.DrawLine(simulationPos + new Vector3(-maxHDist * .25f, maxJumpHeight), simulationPos + new Vector3(maxHDist * .75f, maxJumpHeight));
        Gizmos.color = Color.white;
    }