public void HorizontalRaycast() { float skin = 0.015f; float yOffest = 0.05f; float velX = velocity.x * Time.deltaTime; int dirX = (velX > 0 || velX < 0) ? (int)Mathf.Sign(velX) : 0; Transform[] startRayPoint = (dirX == 1) ? rightRayPoints : leftRayPoints; if (movementState == E_MOVE_STATE.RIGHT || movementState == E_MOVE_STATE.LEFT) { //detect shortest distance bool rayHit = false; for (int i = 0; i < startRayPoint.Length; ++i) { Transform point = startRayPoint[i]; RaycastHit2D ray = Physics2D.Raycast(new Vector2(point.position.x + skin * dirX, point.position.y + yOffest), Vector3.right * dirX, Mathf.Abs(velX), m_platform); if (ray) { velocity.x = 0; horTargetVelocity.x = 0; movementState = E_MOVE_STATE.STILL; } } } //OTHER ENTITIES COLLISION float rayLength = 0.02f; for (int i = 0; i < 2; ++i) { Transform[] entityStartPoints = (i == 0) ? rightRayPoints : leftRayPoints; int rayDir = (i == 0) ? 1 : -1; for (int j = 0; j < entityStartPoints.Length; ++j) { Transform point = entityStartPoints[j]; RaycastHit2D ray = Physics2D.Raycast(new Vector2(point.position.x + rayLength * rayDir, point.position.y), Vector3.right * rayDir, Mathf.Abs(rayLength), m_entity); if (ray) { ResponsiveEntity entityScript = ray.collider.gameObject.GetComponent <ResponsiveEntity>(); if (entityScript) { GameObject mario = gameObject; entityScript.OnMarioTouched(ResponsiveEntity.E_MARIO_TOUCHED.HOR, ref mario); } } } } }
public void VerticalRaycast() { float skin = 0.0015f; float velY = velocity.y * Time.deltaTime; int dir = (velY > 0 || velY < 0) ? (int)Mathf.Sign(velY) : 0; if (dir == 0) { return; } Transform[] startRayPoint = (dir == 1) ? topRayPoints : botRayPoints; //float distance = Mathf.Abs(velocity.y * Time.deltaTime) + skin; float shortestGroundDist = 777777777f; //detect shortest distance bool rayHit = false; for (int i = 0; i < startRayPoint.Length; ++i) { Transform point = startRayPoint[i]; RaycastHit2D ray = Physics2D.Raycast(new Vector2(point.position.x, point.position.y - skin * dir), Vector3.up * dir, Mathf.Abs(velY), m_platform); if (ray) { rayHit = true; if (ray.distance + skin * dir < shortestGroundDist) { if (dir == -1) { shortestGroundDist = ray.distance + skin * dir; } //no skin for hitting celling so it doesn't stuck for second ==> NO IDEA WHY if (dir == 1) { shortestGroundDist = ray.distance - 0.1f; } } } } if (rayHit) { velocity.y = 0; MoveBy(new Vector2(0, shortestGroundDist * dir)); if (dir == -1) { grounded = true; } } else { if (dir == -1) { grounded = false; } } //OTHER ENTITIES COLLISION float rayLength = 0.1f; for (int i = 0; i < 2; ++i) { Transform[] entityStartPoints = (i == 0) ? topRayPoints : botRayPoints; int rayDir = (i == 0) ? 1 : -1; for (int j = 0; j < entityStartPoints.Length; ++j) { Transform point = entityStartPoints[j]; RaycastHit2D ray = Physics2D.Raycast(new Vector2(point.position.x, point.position.y + rayLength * rayDir), Vector3.up * rayDir, Mathf.Abs(rayLength), m_entity); if (ray) { ResponsiveEntity entityScript = ray.collider.gameObject.GetComponent <ResponsiveEntity>(); if (entityScript) { GameObject mario = gameObject; if (rayDir == 1) { entityScript.OnMarioTouched(ResponsiveEntity.E_MARIO_TOUCHED.BOT, ref mario); } if (rayDir == -1) { entityScript.OnMarioTouched(ResponsiveEntity.E_MARIO_TOUCHED.TOP, ref mario); } } } //EXCEPTION FOR HITABLE BLOCKS BECOUSE IT IS SUPOSE TO HAVE PLATFORM AND ENTITY LAYER IN ONE RaycastHit2D hitBlock = Physics2D.Raycast(new Vector2(point.position.x, point.position.y + rayLength * rayDir), Vector3.up * rayDir, Mathf.Abs(rayLength), m_platform); if (hitBlock) { ResponsiveEntity entityScript = hitBlock.collider.gameObject.GetComponent <ResponsiveEntity>(); if (entityScript) { GameObject mario = gameObject; if (rayDir == 1) { if (entityScript.id == MapManager.E_ENTITY_ID.BLOCK_COIN || entityScript.id == MapManager.E_ENTITY_ID.BRICK || entityScript.id == MapManager.E_ENTITY_ID.UNDERGROUND_BRICK) { entityScript.OnMarioTouched(ResponsiveEntity.E_MARIO_TOUCHED.BOT, ref mario); } } if (rayDir == -1) { if (entityScript.id == MapManager.E_ENTITY_ID.CLOUD_TRAVEL) { entityScript.OnMarioTouched(ResponsiveEntity.E_MARIO_TOUCHED.TOP, ref mario); } } } } } } }