//Check if ground is valid layer, this one check only the first hit collision (more strict) public bool CheckValidFloor() { Vector3 center = transform.position + Vector3.up * build_ground_dist; Vector3 p0 = center; Vector3 p1 = center + Vector3.right * build_obstacle_radius; Vector3 p2 = center + Vector3.left * build_obstacle_radius; Vector3 p3 = center + Vector3.forward * build_obstacle_radius; Vector3 p4 = center + Vector3.back * build_obstacle_radius; Vector3 dir = Vector3.down * (build_ground_dist + build_ground_dist); RaycastHit h0, h1, h2, h3, h4; bool f0 = PhysicsTool.RaycastCollision(p0, dir, out h0); bool f1 = PhysicsTool.RaycastCollision(p1, dir, out h1); bool f2 = PhysicsTool.RaycastCollision(p2, dir, out h2); bool f3 = PhysicsTool.RaycastCollision(p3, dir, out h3); bool f4 = PhysicsTool.RaycastCollision(p4, dir, out h4); f0 = f0 && PhysicsTool.IsLayerIsInLayerMask(h0.collider.gameObject.layer, floor_layer); f1 = f1 && PhysicsTool.IsLayerIsInLayerMask(h1.collider.gameObject.layer, floor_layer); f2 = f2 && PhysicsTool.IsLayerIsInLayerMask(h2.collider.gameObject.layer, floor_layer); f3 = f3 && PhysicsTool.IsLayerIsInLayerMask(h3.collider.gameObject.layer, floor_layer); f4 = f4 && PhysicsTool.IsLayerIsInLayerMask(h4.collider.gameObject.layer, floor_layer); if (build_flat_floor) { return(f1 && f2 && f3 && f4 && f0); //Floor must be valid on all sides } else { return(f1 || f2 || f3 || f4 || f0); //Floor must be valid only on one side } }
void Update() { if (TheGame.Get().IsPaused()) { return; } if (character.IsDead()) { return; } //Swim if (!is_swimming && PhysicsTool.IsAnyLayerIsInLayerMask(cground_layers, water_layer)) { StartSwim(); } else if (is_swimming && !PhysicsTool.IsAnyLayerIsInLayerMask(cground_layers, water_layer)) { StopSwimming(); } //Swim adjust offset if (swim_mesh_offset != null) { swim_mesh_offset.transform.localPosition = Vector3.Lerp(swim_mesh_offset.transform.localPosition, swim_mesh_tpos, 20f * Time.deltaTime); } }
//Detect if there is an obstacle in front of the character private void DetectFronted() { float radius = destruct.hit_range * 2f; Vector3 center = destruct.GetCenter(); Vector3 dir = move_target_avoid - transform.position; Vector3 dirl = Quaternion.AngleAxis(-45f, Vector3.up) * dir.normalized; Vector3 dirr = Quaternion.AngleAxis(45f, Vector3.up) * dir.normalized; RaycastHit h, hl, hr; bool fc = PhysicsTool.RaycastCollision(center, dir.normalized * radius, out h); bool fl = PhysicsTool.RaycastCollision(center, dirl.normalized * radius, out hl); bool fr = PhysicsTool.RaycastCollision(center, dirr.normalized * radius, out hr); is_fronted_center = fc && (target == null || h.collider.gameObject != target); is_fronted_left = fl && (target == null || hl.collider.gameObject != target); is_fronted_right = fr && (target == null || hr.collider.gameObject != target); int front_count = (fc ? 1 : 0) + (fl ? 1 : 0) + (fr ? 1 : 0); front_dist = (fc ? h.distance : 0f) + (fl ? hl.distance : 0f) + (fr ? hr.distance : 0f); if (front_count > 0) { front_dist = front_dist / (float)front_count; } is_fronted = is_fronted_center || is_fronted_left || is_fronted_right; }
private bool IsPositionValid(Vector3 pos) { Vector3 center = pos + Vector3.up * 0.5f; Vector3 ground_pos; return(PhysicsTool.FindGroundPosition(center, 1f, valid_floor, out ground_pos)); }
//Find landing position to make sure it wont land on an obstacle private bool FindGroundPosition(Vector3 pos, float radius, out Vector3 ground_pos) { Vector3 offest = new Vector3(Random.Range(-radius, radius), 0f, Random.Range(radius, radius)); Vector3 center = pos + offest; bool found = PhysicsTool.FindGroundPosition(center, 50f, character.ground_layer.value, out ground_pos); return(found); }
private float FindYPosition(Vector3 pos) { Vector3 center = pos + Vector3.up * 10f; Vector3 ground_pos; bool found = PhysicsTool.FindGroundPosition(center, 20f, valid_floor, out ground_pos); return(found ? ground_pos.y : pos.y); }
//Detect if character is on the floor private void DetectGrounded() { float hradius = GetColliderHeightRadius(); float radius = GetColliderRadius(); Vector3 center = GetColliderCenter(); float gdist; Vector3 gnormal; is_grounded = PhysicsTool.DetectGround(transform, center, hradius, radius, ground_layer, out gdist, out gnormal); ground_normal = gnormal; float slope_angle = Vector3.Angle(ground_normal, Vector3.up); is_grounded = is_grounded && slope_angle <= slope_angle_max; }
private void FixedUpdate() { if (TheGame.Get().IsPaused()) { return; } if (character.IsDead()) { return; } Vector3 center = character.GetColliderCenter(); float hradius = character.GetColliderHeightRadius(); cground_layers = PhysicsTool.DetectGroundLayers(center, hradius); }
public void Spawn() { CraftData data = spawn_data[Random.Range(0, spawn_data.Length)]; if (data != null) { float radius = Random.Range(0f, spawn_radius); float angle = Random.Range(0f, 360f) * Mathf.Deg2Rad; Vector3 offset = new Vector3(Mathf.Cos(angle), 0f, Mathf.Sin(angle)) * radius; Vector3 pos = transform.position + offset; Vector3 ground_pos; bool found = PhysicsTool.FindGroundPosition(pos, 100f, valid_floor_layer.value, out ground_pos); if (found) { CraftData.Create(data, ground_pos); } } }
//Find the height to build public Vector3 FindBuildPosition(Vector3 pos, LayerMask mask) { float offset = build_distance; Vector3 center = pos + Vector3.up * offset; Vector3 p0 = center; Vector3 p1 = center + Vector3.right * build_obstacle_radius; Vector3 p2 = center + Vector3.left * build_obstacle_radius; Vector3 p3 = center + Vector3.forward * build_obstacle_radius; Vector3 p4 = center + Vector3.back * build_obstacle_radius; Vector3 dir = Vector3.down * (offset + build_ground_dist); RaycastHit h0, h1, h2, h3, h4; bool f0 = PhysicsTool.RaycastCollisionLayer(p0, dir, mask, out h0); bool f1 = PhysicsTool.RaycastCollisionLayer(p1, dir, mask, out h1); bool f2 = PhysicsTool.RaycastCollisionLayer(p2, dir, mask, out h2); bool f3 = PhysicsTool.RaycastCollisionLayer(p3, dir, mask, out h3); bool f4 = PhysicsTool.RaycastCollisionLayer(p4, dir, mask, out h4); Vector3 dist_dir = Vector3.down * build_distance; if (f0 && h0.distance < dist_dir.magnitude) { dist_dir = Vector3.down * h0.distance; } if (f1 && h1.distance < dist_dir.magnitude) { dist_dir = Vector3.down * h1.distance; } if (f2 && h2.distance < dist_dir.magnitude) { dist_dir = Vector3.down * h2.distance; } if (f3 && h3.distance < dist_dir.magnitude) { dist_dir = Vector3.down * h3.distance; } if (f4 && h4.distance < dist_dir.magnitude) { dist_dir = Vector3.down * h4.distance; } return(center + dist_dir); }
//Check if its still valid floor after built, this one ignore itself and check only the layer (less strict) public bool CheckValidFloorBuilt() { Vector3 center = transform.position + Vector3.up * build_ground_dist; Vector3 p0 = center; Vector3 p1 = center + Vector3.right * build_obstacle_radius; Vector3 p2 = center + Vector3.left * build_obstacle_radius; Vector3 p3 = center + Vector3.forward * build_obstacle_radius; Vector3 p4 = center + Vector3.back * build_obstacle_radius; Vector3 dir = Vector3.down * (build_ground_dist + build_ground_dist); RaycastHit h0, h1, h2, h3, h4; bool f0 = PhysicsTool.RaycastCollisionLayer(p0, dir, floor_layer, out h0); bool f1 = PhysicsTool.RaycastCollisionLayer(p1, dir, floor_layer, out h1); bool f2 = PhysicsTool.RaycastCollisionLayer(p2, dir, floor_layer, out h2); bool f3 = PhysicsTool.RaycastCollisionLayer(p3, dir, floor_layer, out h3); bool f4 = PhysicsTool.RaycastCollisionLayer(p4, dir, floor_layer, out h4); return(f1 || f2 || f3 || f4 || f0); }
void Awake() { character = GetComponent <PlayerCharacter>(); if (swim_mesh_offset != null) { swim_mesh_tpos = swim_mesh_offset.transform.localPosition; } if (swim_ongoing_fx != null) { swimming_fx = Instantiate(swim_ongoing_fx, transform); swimming_fx.SetActive(false); } foreach (int layer in PhysicsTool.LayerMaskToLayer(water_obstacle_layer)) { Physics.IgnoreLayerCollision(gameObject.layer, layer); } }
//Check if touching the ground private void DetectGrounded() { float radius = (bounds_extent.x + bounds_extent.z) * 0.5f; float center_offset = bounds_extent.y; float hradius = center_offset + ground_detect_dist; Vector3 center = transform.position + bounds_center_offset; center.y = transform.position.y + center_offset; float gdist; Vector3 gnormal; is_grounded = PhysicsTool.DetectGround(transform, center, hradius, radius, ground_layer, out gdist, out gnormal); ground_normal = gnormal; grounded_dist = gdist; float slope_angle = Vector3.Angle(ground_normal, Vector3.up); is_grounded = is_grounded && slope_angle <= slope_angle_max; }
//Detect if there is an obstacle in front of the character private void DetectFronted() { Vector3 scale = transform.lossyScale; float hradius = collide.height * scale.y * 0.5f - 0.02f; //radius is half the height minus offset float radius = collide.radius * (scale.x + scale.y) * 0.5f + 0.5f; Vector3 center = GetColliderCenter(); Vector3 p1 = center; Vector3 p2 = center + Vector3.up * hradius; Vector3 p3 = center + Vector3.down * hradius; RaycastHit h1, h2, h3; bool f1 = PhysicsTool.RaycastCollision(p1, facing * radius, out h1); bool f2 = PhysicsTool.RaycastCollision(p2, facing * radius, out h2); bool f3 = PhysicsTool.RaycastCollision(p3, facing * radius, out h3); is_fronted = f1 || f2 || f3; //Debug.DrawRay(p1, facing * radius); //Debug.DrawRay(p2, facing * radius); //Debug.DrawRay(p3, facing * radius); }
//Make sure there is no obstacles in between the player and the building, this applies only if placing with keyboard/gamepad public bool CheckIfAccessible() { PlayerControls controls = PlayerControls.Get(building_character.player_id); bool game_pad = controls != null && controls.IsGamePad(); if (position_set || !game_pad) { return(true); //Dont check this is placing with mouse or if position already set } if (building_character != null) { Vector3 center = building_character.GetColliderCenter(); Vector3 build_center = transform.position + Vector3.up * build_ground_dist; Vector3 dir = build_center - center; RaycastHit h1; bool f1 = PhysicsTool.RaycastCollision(center, dir, out h1); return(!f1 || h1.collider.GetComponentInParent <Buildable>() == this); } return(false); }
//Check if there is a flat floor underneath (can't build a steep cliff) public bool CheckIfFlatGround() { if (!build_flat_floor) { return(true); //Dont check for flat ground } Vector3 center = transform.position + Vector3.up * build_ground_dist; Vector3 p0 = center; Vector3 p1 = center + Vector3.right * build_obstacle_radius; Vector3 p2 = center + Vector3.left * build_obstacle_radius; Vector3 p3 = center + Vector3.forward * build_obstacle_radius; Vector3 p4 = center + Vector3.back * build_obstacle_radius; Vector3 dir = Vector3.down * (build_ground_dist + build_ground_dist); RaycastHit h0, h1, h2, h3, h4; bool f0 = PhysicsTool.RaycastCollision(p0, dir, out h0); bool f1 = PhysicsTool.RaycastCollision(p1, dir, out h1); bool f2 = PhysicsTool.RaycastCollision(p2, dir, out h2); bool f3 = PhysicsTool.RaycastCollision(p3, dir, out h3); bool f4 = PhysicsTool.RaycastCollision(p4, dir, out h4); return(f0 && f1 && f2 && f3 && f4); }