//This takes a list of raycasthits (which have been obtained from a downwards spherecast) and tries to decide if the character is grounded. //The raycasthit which determines the grounded state also contains information about normals. public void UpdateWithCollisions(List <RaycastHit> a_Collisions) { m_ValidHits.Clear(); m_IsGrounded = false; Vector3 downCenter = m_CapsuleCollider.GetDownCenter(); //Discard all hitresults that are above the lower hemisphere (locally), or have an inacceptable angle (locally or globally) for (int i = 0; i < a_Collisions.Count; i++) { float hitPointDot = Vector3.Dot(a_Collisions[i].point, Vector3.up); float downCenterDot = Vector3.Dot(downCenter, Vector3.up); float reqAngle = m_CapsuleCollider.GetMaxGroundedAngle(); float angle = Vector3.Angle(Vector3.up, a_Collisions[i].normal); if (hitPointDot < downCenterDot && Mathf.Abs(angle) < reqAngle) { m_ValidHits.Add(a_Collisions[i]); } } if (m_ValidHits.Count != 0) { float shortestDistance = m_ValidHits[0].distance; m_MostValidHit = m_ValidHits[0]; for (int i = 1; i < m_ValidHits.Count; i++) { if (m_ValidHits[i].distance < shortestDistance) { shortestDistance = m_ValidHits[i].distance; m_MostValidHit = m_ValidHits[i]; } } m_IsGrounded = true; } }
void SpawnParticles() { Vector3 position = Vector3.zero; Vector3 normal = Vector3.zero; CGroundedInfo groundInfo = m_CharacterController.GetCollider().GetGroundedInfo(); CSideCastInfo sideCastInfo = m_CharacterController.GetCollider().GetSideCastInfo(); bool valid = false; if (groundInfo.m_IsGrounded) { position = groundInfo.GetPoint(); normal = new Vector3(groundInfo.GetNormal().x, groundInfo.GetNormal().y, 0.0f); valid = true; } else if (sideCastInfo.m_WallCastCount >= 2) { position = sideCastInfo.GetSidePoint(); normal = sideCastInfo.GetSideNormal(); valid = true; } else { position = m_Collider.GetDownCenter() - m_Collider.GetUpDirection() * m_Collider.GetRadius(); normal = m_Collider.GetUpDirection(); valid = true; } if (valid) { m_ParticleSystem.transform.position = position; m_ParticleSystem.transform.LookAt(position + normal, Vector3.back); m_ParticleSystem.Emit(m_EmissionCount); } }
public bool CanBeResized(float a_Length, CapsuleResizeMethod a_Method) { Vector3 newPosition = m_Position; switch (a_Method) { case CapsuleResizeMethod.FromCenter: return(!Physics.CheckCapsule(newPosition - m_CapsuleCollider.GetUpDirection() * a_Length * 0.5f, newPosition + m_CapsuleCollider.GetUpDirection() * a_Length * 0.5f, m_CapsuleCollider.GetRadius(), m_CapsuleCollider.GetLayerMask())); case CapsuleResizeMethod.FromBottom: return(!Physics.CheckCapsule(m_CapsuleCollider.GetDownCenter(), m_CapsuleCollider.GetDownCenter() + m_CapsuleCollider.GetUpDirection() * a_Length, m_CapsuleCollider.GetRadius() - m_CapsuleCollider.GetResizeCastMargin(), m_CapsuleCollider.GetLayerMask())); case CapsuleResizeMethod.FromTop: return(!Physics.CheckCapsule(m_CapsuleCollider.GetUpCenter(), m_CapsuleCollider.GetUpCenter() - m_CapsuleCollider.GetUpDirection() * a_Length, m_CapsuleCollider.GetRadius() - m_CapsuleCollider.GetResizeCastMargin(), m_CapsuleCollider.GetLayerMask())); } return(true); }
void Start() { //Make sure that we start at the right height, and that the parent is aligned to the lower demisphere //Prevents having to manually adjust both sprite and parent Vector3 originalPosition = transform.position; m_SpriteTransformHook.transform.position = m_CapsuleCollider.GetDownCenter(); transform.position = originalPosition; m_StartHeight = transform.localPosition.y; }
//This takes the results of a sidecast and tries to determine if a wall is found. //Using the sidecast information, it sends out three probes (from the center of the top and bottom hemispheres and the center of the capsule). //It counts the amount of hits that are valid and stores this for other classes to access. void WallCast(RaycastHit a_SidecastHit) { if (Vector3.Angle(Vector3.up, a_SidecastHit.normal) > m_CapsuleCollider.GetMaxWallAngle() || Vector3.Angle(Vector3.up, a_SidecastHit.normal) < m_CapsuleCollider.GetMaxGroundedAngle()) { m_WallCastCount = 0; return; } float wallCastMargin = m_CapsuleCollider.GetWallCastMargin(); float wallCastDistance = m_CapsuleCollider.GetWallCastDistance(); Vector3 hitPos = a_SidecastHit.point; Vector3 normal = a_SidecastHit.normal; Vector3 currentUp = m_CapsuleCollider.GetUpDirection(); Vector3 direction = CState.GetDirectionAlongNormal(Vector3.up, normal); Vector3 startHitPos1 = Vector3.zero; Vector3 startHitPos2 = Vector3.zero; Vector3 startHitPos3 = Vector3.zero; Vector3 normalOff = normal * (m_CapsuleCollider.GetRadius() - wallCastMargin); //Determines where the sidecast has hit. This to orient the probes in the correct way. if (Vector3.Dot(currentUp, hitPos) <= Vector3.Dot(currentUp, m_CapsuleCollider.GetDownCenter()))//Hit on the lower hemisphere { startHitPos1 = m_CapsuleCollider.GetDownCenter() + direction * m_CapsuleCollider.GetDefaultLength() - normalOff; startHitPos2 = m_CapsuleCollider.GetDownCenter() - normalOff; startHitPos3 = m_CapsuleCollider.GetDownCenter() + direction * m_CapsuleCollider.GetDefaultLength() * 0.5f - normalOff; } else if (Vector3.Dot(currentUp, hitPos) >= Vector3.Dot(currentUp, m_CapsuleCollider.GetUpCenter()))//Hit on the upper hemisphere { startHitPos1 = m_CapsuleCollider.GetUpCenter() - direction * m_CapsuleCollider.GetDefaultLength() - normalOff; startHitPos2 = m_CapsuleCollider.GetUpCenter() - normalOff; startHitPos3 = m_CapsuleCollider.GetUpCenter() - direction * m_CapsuleCollider.GetDefaultLength() * 0.5f - normalOff; } else //Hit somewhere in the middle { startHitPos1 = m_CapsuleCollider.GetDownCenter(true) + direction * m_CapsuleCollider.GetDefaultLength() - normalOff; startHitPos2 = m_CapsuleCollider.GetDownCenter(true) - normalOff; startHitPos3 = m_CapsuleCollider.GetDownCenter(true) + direction * m_CapsuleCollider.GetDefaultLength() * 0.5f - normalOff; } RaycastHit newHit; m_WallCastCount = 0; if (Physics.Raycast(startHitPos1, -normal, out newHit, wallCastDistance + wallCastMargin, m_CapsuleCollider.GetLayerMask())) { m_WallCastCount++; } if (Physics.Raycast(startHitPos2, -normal, out newHit, wallCastDistance + wallCastMargin, m_CapsuleCollider.GetLayerMask())) { m_WallCastCount++; } if (Physics.Raycast(startHitPos3, -normal, out newHit, wallCastDistance + wallCastMargin, m_CapsuleCollider.GetLayerMask())) { m_WallCastCount++; } }