public PlatformCharacterPhysics(PlatformCharacterPhysics other) { m_pos = other.m_pos; m_vel = other.m_vel; m_acc = other.m_acc; m_gravity = other.m_gravity; m_gravityScale = other.m_gravityScale; m_terminalVel = other.m_terminalVel; m_maxHSpeed = other.m_maxHSpeed; m_drag = other.m_drag; }
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; }