public void PointOnTerrain() { Ray ray = Camera.main.ScreenPointToRay(mousePosition); RaycastHit hitInfo; if (Physics.Raycast(ray, out hitInfo, 250f, ConstraintController.getTerrainMask())) { points[selectionStage - 1] = hitInfo.point; if (hitInfo.point.y > points[0].y) { // move first point to new height points[0].y = hitInfo.point.y; } if (selectionStage > 1) { // All points need to be at the same height points[selectionStage - 1].y = points[0].y; } UpdateSelectionCube(selectionStage); //Debug.Log("hitpoint="+hitInfo.point+", TerrainPoistion="+TerrainPosition(hitInfo.point)+" "+PositionTerrain(TerrainPosition(hitInfo.point))); testObject.transform.position = hitInfo.point; if (selectionStage == 4) { insideSelection = isInsideSelection(hitInfo.point); } } }
void Update() { if (UIController.Instance.gameMode == gameMode.build) { //All this should only happens when gameMode=build HandleNewObjectHotkey(); if (currentBC != null) { //bool wasRotated = RotateFromMouseWheel(); RotateFromMouseWheel(); //if (Input.mousePosition!=mousePosition || wasRotated) //{ // only move placeable object when mouse has moved mousePosition = Input.mousePosition; MovePlaceableObjectToMouse(); //} // Make the placeable red or green based on whether it can be placed ConstraintController.SetCanPlaceObjectColour(currentBC); Drag(); PlaceOnClic(); } } else if (currentBC != null) { // Always destroy placeable object when we leave build mode Destroy(currentBC.gameObject); Debug.Log("Going off build mode destroyed placeable object"); currentBC = null; } }
void StartDrag() { ForwardOffsetBeforeDragging = UIController.Instance.forwardOffset; if (ConstraintController.CanPlace(currentBC)) { string templateName = currentBC.template.name; string name = templateName + "_" + (nbObjectsPlaced++); // Place the first Ghost = still green, still not collidin' TemplateController.PlaceObject(currentBC, name, BC_State.Ghost); draggedBC.Add(currentBC); draggingGroup = currentBC.beyondGroup; lastGroupPosition = currentBC.groupPosition; currentBC = null; CreateNewPlaceableObject(templateName); // TODO : another hardcoded position. Not good. Yet, I must move the currentBC to where I started dragging or else I'm going to drag to some unknown place. currentBC.transform.position = draggedBC[0].transform.position; currentBC.transform.rotation = draggedBC[0].transform.rotation; // Instantiate a big bunch of placeable object based on what we are currently dragging for (int i = 0; i < MaxDraggedObjectCount; i++) { BeyondComponent bc = TemplateController.CreateObject(templateName); //TODO Better names, please name = templateName + "_Ghost" + i; bc.SetBCinGroup(draggingGroup, lastGroupPosition); TemplateController.PlaceObject(bc, name, BC_State.Ghost); bc.gameObject.SetActive(false); draggedBC.Add(bc); } } }
public static void SetCanPlaceObjectColour(BeyondComponent bc) { Renderer r = bc.gameObject.GetComponent <Renderer>(); r.material.color = (ConstraintController.CanPlace(bc) ? Color.green : Color.red); //Debug.Log("Setting can place colour on " + bc.name + " in group " + (bc.beyondGroup==null ? "null" : bc.beyondGroup.name) + " at position "+bc.groupPosition + " = "+ ConstraintController.CanSnapTo(bc, bc.beyondGroup, bc.groupPosition)); //r.material.color = (ConstraintController.CanSnapTo(bc, bc.beyondGroup , bc.groupPosition) ? Color.green : Color.red); }
private void Snap() { // Unset the group before trying to snap or weird things happen currentBC.unsetObjectGroup(); // 1 - what groups are close to currentPlaceableObject ? BeyondGroup closestGroup; findCloseGroups(currentBC, out closestGroup); if (closestGroup != null) { //Debug.Log("closestGroup"+closestGroup.name); // Find the centre where I should place the object based on the group's "root" position and the Vector3Int difference between there and here // 1 - where would the cell centre be, considering the offset of this placeable object's template Vector3 pointWithOffset = currentBC.transform.position - currentBC.template.pivotOffset; // 2 - calculate the difference between this point and the group's centre and apply the inverse rotation for the group so we can compare in a non-rotated way pointWithOffset = Utility.RotateAroundPoint(pointWithOffset, closestGroup.position, Quaternion.Inverse(closestGroup.rotation)); // 3 - Obtain the equivalent Integer Vector3, which represents how many cells the object is from the group's centre Vector3Int diffInt2 = Vector3Int.RoundToInt(pointWithOffset - closestGroup.position); UIController.Instance.positionInGroup = diffInt2; // 4 - This is the position of the centre of the cell Vector3 snappedPosition = closestGroup.position + (Vector3)diffInt2; // 5 - Rotate it by the group's rotation for final result snappedPosition = Utility.RotateAroundPoint(snappedPosition, closestGroup.position, closestGroup.rotation); // TODO : move this constraint to ConstraintController // Test to see if foundation is above groud like in GetValidPositionFromMouse //TODO: Hardcode for the time being as I tweak GetPointOnLayer //TODO : I have removed minY so don't need the code below. See if that works. CanSnapTo should ideally prevent being inside terrain anyway //Vector3 point = ConstraintController.GetPointOnLayer(currentBC , currentBC.transform.position , ConstraintController.getTerrainMask()) ; //float minY = point.y ; //minY = 0; //if (snappedPosition.y>=minY) //{ // Snap in place only if object's top is above ground // Not needed aymore-angle between the rotation of the group and the rotation of the object on the Y axis : float angle = Mathf.Abs(currentPlaceableObject.transform.rotation.eulerAngles.y - closestGroup.rotation.eulerAngles.y ); //if (ConstraintController.CanSnapToGroupHere(closestGroup , diffInt2 , currentBC.template , snappedPosition - pointWithOffset , currentBC.transform.rotation , out snapToSide)) if (ConstraintController.CanSnapTo(currentBC, closestGroup, diffInt2)) { currentBC.SetBCinGroup(closestGroup, diffInt2); } // else Debug.Log("Can't snap here because of group constraints"); //} } else { currentBC.unsetObjectGroup(); // TODO : gros caca UIController.Instance.positionInGroup = new Vector3Int(-999, -999, -999); } }
//TODO : All this is currently hardcoded but should just do CheckConstraints(bc) public static bool CanPlace(BeyondComponent bc) { // Won't work on a NULL BeyondComponent if (bc == null) { return(false); } // can't already have a the same object at the same place & position if (IsTemplatePresentHere(bc.beyondGroup, bc.groupPosition, bc.template.name, bc.side)) { return(false); } // Object can't collide with other objects in different group if (bc.collidingWithBuilding()) { return(false); } if (bc.template.name == "Foundation") { // 1 - Foundations must be partially inside terrain, but their top must not be covered by it if (!BaseInTerrain(bc)) { return(false); } if (!TopClear(bc, getTreesMask())) { return(false); } if (AllClear(bc, ConstraintController.getTreesMask())) { return(true); } } else { // 2 -All non-foundations objects must be clear of terrain and trees- return false immediately if they're not if (AllClear(bc, getTerrainAndTreesMask())) { return(true); } } //3 - All non-foundations must be snapped to another building part if (bc.template.name != "Foundation" && bc.beyondGroup == null) { // TO DO : I must check if I can snap here, but how to do that with dragged ghosts ? return(false); } return(false); //5 - Think of moveable objects later (they're not in groups, so they don't snap = constraints are easier) }
public bool collidingWithBuilding(bool checkSameGroup = true) { foreach (GameObject g in objectsTriggered) { //TODO : debug this. I need to make sure "triggers" are fine //Debug.Log("objectsTriggered= "+g.name); if (ConstraintController.layerIsInMask(g.layer, ConstraintController.getBuildingsMask())) { if (!checkSameGroup || g.GetComponent <BeyondComponent>().beyondGroup != beyondGroup) { //Debug.Log("collidingWithBuilding TRUE. Object is in group " + g.GetComponent<BeyondComponent>().beyondGroup.name + " from group " + (beyondGroup!=null ? beyondGroup.name : "NULL")); return(true); } } } //Debug.Log("collidingWithBuilding FALSE"); return(false); }
void Drag2D(Vector3Int objectGroupPosition, Vector3 objectPosition, Vector3 p1, Vector3 p2) { Plane p = new Plane(p1, p2); Vector3 dragTo = p.ClosestPointOnPlane(objectPosition); // Correct ObjectGroupPosition so we are in the plane we are dragging in objectGroupPosition = Vector3Int.RoundToInt(dragTo - draggingGroup.position); if (objectGroupPosition != lastGroupPosition) { // even after projecting on a plane, are we still in a new cell ? lastGroupPosition = objectGroupPosition; //Debug.Log("Dragging to a new position on a plane in the group: "+lastGroupPosition+" from draggedBC[0]: "+draggedBC[0].groupPosition); int Xsign = (lastGroupPosition.x >= draggedBC[0].groupPosition.x ? 1 : -1); int Zsign = (lastGroupPosition.z >= draggedBC[0].groupPosition.z ? 1 : -1); int i = 0; for (int x = 0; x <= Mathf.Abs(lastGroupPosition.x - draggedBC[0].groupPosition.x); x++) { for (int z = 0; z <= Mathf.Abs(lastGroupPosition.z - draggedBC[0].groupPosition.z); z++) { // go from the origin of the drag to the current position if (x != 0 || z != 0) { Vector3Int currentPos = new Vector3Int(draggedBC[0].groupPosition.x + x * Xsign, 0, draggedBC[0].groupPosition.z + z * Zsign); if (i++ < MaxDraggedObjectCount) { draggedBC[i].SetBCinGroup(draggingGroup, currentPos); //Debug.Log("2 dimensions dragging - calling SetBCinGroup on " + draggedBC[i].name + " group:" + draggedBC[i].beyondGroup.name); ConstraintController.SetCanPlaceObjectColour(draggedBC[i]); draggedBC[i].gameObject.SetActive(true); } } } } // Deactivate all ghosts that are not used in the area we are currently dragging if (i >= 0) { for (int j = i + 1; j <= MaxDraggedObjectCount; j++) { draggedBC[j].gameObject.SetActive(false); } } } }
private void MovePlaceableObjectToMouse() { Ray ray1 = Camera.main.ScreenPointToRay(mousePosition); RaycastHit hitInfo; // filter the raycast based on whether this template should be shown on terrain or not //LayerMask layerMask = (ConstraintController.ShowOnTerrain(currentBC.template) ? ConstraintController.getTerrainMask() : ConstraintController.getBuildingsMask()) ; Vector3 position; // 1 - If we hit a building, show the Ghost on it if (Physics.Raycast(ray1, out hitInfo, UIController.Instance.forwardOffset, ConstraintController.getBuildingsMask())) { //Debug.Log("Move to mouse: hit a BUILDING"); position = ConstraintController.PlaceGhost(currentBC, hitInfo.point, ConstraintController.getBuildingsMask()); } // 2 - If we hit terrain, show the Ghost on it else if (Physics.Raycast(ray1, out hitInfo, UIController.Instance.forwardOffset, ConstraintController.getTerrainMask())) { //Debug.Log("Move to mouse: hit TERRAIN"); position = ConstraintController.PlaceGhost(currentBC, hitInfo.point, ConstraintController.getTerrainMask()); } // 3 - If we hit nothing, just make the object float in front of us at a distance of forwardOffset else { //Debug.Log("Move to mouse: FLOAT"); Ray ray2 = Camera.main.ScreenPointToRay(mousePosition); position = Camera.main.transform.position + ray2.direction * UIController.Instance.forwardOffset; } // If I'm in a group, I'm snapped, so only move if I'm a bit far from my current position if (currentBC.beyondGroup == null || Vector3.Distance(position, currentBC.transform.position) > groupSnapTolerance) { currentBC.MoveGhost(position); } Snap(); }
private void PlaceOnClic() { if (Input.GetMouseButtonUp(0)) { //TODO : dragging stuff - make it better for (int i = 0; i < draggedBC.Count; i++) { if (draggedBC[i].gameObject.activeSelf && ConstraintController.CanPlace(draggedBC[i])) { string name = currentBC.template.name + "_" + (nbObjectsPlaced++); TemplateController.PlaceObject(draggedBC[i], name, BC_State.Blueprint); } else { Destroy(draggedBC[i].gameObject); } } Destroy(currentBC.gameObject); draggingGroup = null; draggedBC.Clear(); UIController.Instance.SetForwardOffset(ForwardOffsetBeforeDragging); // reset ForwardOffset to what it was before dragging - less annoying /* * This works for 1 clic : * * if (ConstraintController.CanPlace(currentPlaceableObject)) * { * string name = currentBC.template.name + "_" + (nbObjectsPlaced++) ; * TemplateController.PlaceObject(ref currentPlaceableObject , name , BC_State.Blueprint) ; * } * else * { * //Debug.Log("Destroyed currentPlaceableObject "+ currentPlaceableObject .GetInstanceID()+ " as I couldn't place it"); * Destroy(currentPlaceableObject); * } */ } }
// Update is called once per frame void Update() { //if (UIController.Instance.gameMode == gameMode.free) //{ timer += Time.deltaTime; if (timer > 0.2f) { // TO DO : Should I check for different masks to prevent jumping from non-jumpable objects ? // Does such a thing even exists ? isOnGround = Physics.CheckSphere(groundCheck.position, groundDistance, ConstraintController.getTerrainMask()) || Physics.CheckSphere(groundCheck.position, groundDistance, ConstraintController.getBuildingsMask()); timer = 0f; if (isOnGround && velocity.y < 0) { velocity.y = -2f; } } float x = Input.GetAxis("Horizontal"); float z = Input.GetAxis("Vertical"); running = Input.GetKey(KeyCode.LeftShift); Vector3 move = transform.right * x + transform.forward * z; cc.Move(move * speed * (running ? 2.5f : 1) * Time.deltaTime); if (Input.GetButtonDown("Jump") && isOnGround) { velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity); } velocity.y += gravity * Time.deltaTime * 5f; cc.Move(velocity * Time.deltaTime); //} }
public bool collidingWithTree() { Collider[] hitTreeColliders = Physics.OverlapBox(transform.position, template.castBox, transform.rotation, ConstraintController.getTreesMask()); return(hitTreeColliders.Length > 0); }
public bool insideTerrain() { Collider[] collidersHit = Physics.OverlapBox(transform.position, template.castBox, transform.rotation, ConstraintController.getTerrainMask()); // string debug_string="insideTerrain overlap boxes="; foreach (Collider c in collidersHit) debug_string += c.gameObject.name + ","; Debug.Log(debug_string); return(collidersHit.Length > 0); }
private void loadAllTemplates() { Constraints c, c1, c2, c3, c4, c5, c6; // FOUNDATION - TODO : Move hardcoding below to JSON c1 = Constraints.Create_NEEDSONE( new List <string>() { "Foundation" }, new List <Vector3Int>() { new Vector3Int(-1, 0, 0), new Vector3Int(1, 0, 0), new Vector3Int(0, 0, -1), new Vector3Int(0, 0, 1) }, new List <cellSide>() { cellSide.Down } ); c2 = Constraints.Create_FIRSTINGROUP(); c3 = Constraints.Create_OR(new List <Constraints>() { c1, c2 }); c4 = Constraints.Create_BASEIN(ConstraintController.FoundationInTerrainBy); c5 = Constraints.Create_TOPCLEAR(ConstraintController.getTerrainAndTreesMask()); c6 = Constraints.Create_ALLCLEAR(ConstraintController.getTreesMask()); c = Constraints.Create_AND(new List <Constraints>() { c3, c4, c5, c6 }); templates.Add("Foundation", new Template( name: "Foundation", castBox: new Vector3(0.5f, 0.55f, 0.5f), prefab_go: Resources.Load <GameObject>("Prefabs/Foundation"), pivotOffset: new Vector3(0, -0.95f, 0f), constraints: c, dragDimensions: 2, fixedSide: cellSide.Down )); // WALL c1 = Constraints.Create_NEEDSONE( new List <string>() { "Foundation" }, new List <Vector3Int>() { new Vector3Int(0, 0, 0) }, new List <cellSide>() { cellSide.Down } ); c2 = Constraints.Create_ALLCLEAR(ConstraintController.getTerrainAndTreesMask()); c = Constraints.Create_AND(new List <Constraints>() { c1, c2 }); templates.Add("Wall", new Template( name: "Wall", castBox: new Vector3(0.5f, 1.45f, 0.1f), prefab_go: Resources.Load <GameObject>("Prefabs/Wall"), pivotOffset: new Vector3(0f, 1.05f, -0.4f), cells: new List <Vector3Int>() { new Vector3Int(0, 0, 0), new Vector3Int(0, 1, 0), new Vector3Int(0, 2, 0) }, constraints: c, dragDimensions: 1 )); templates.Add("Wallhole", new Template( name: "Wallhole", castBox: new Vector3(0.5f, 1.25f, 0.1f), prefab_go: Resources.Load <GameObject>("Prefabs/Wallhole"), pivotOffset: new Vector3(0f, 1.25f, -0.4f), cells: new List <Vector3Int>() { new Vector3Int(0, 0, 0), new Vector3Int(0, 1, 0), new Vector3Int(0, 2, 0) }, constraints: c, dragDimensions: 1 )); templates.Add("Floor", new Template( name: "Floor", castBox: new Vector3(0.5f, 0.05f, 0.5f), prefab_go: Resources.Load <GameObject>("Prefabs/Floor"), pivotOffset: new Vector3(0, -0.45f, 0f), constraints: null, dragDimensions: 2, fixedSide: cellSide.Down )); //TODO - Roof //TODO - WallOpened }
private List <BeyondGroup> findCloseGroups(BeyondComponent bc, out BeyondGroup closestGroup) { List <BeyondGroup> result = new List <BeyondGroup>(); // Find the groups that are close to this BeyondComponent Collider[] collidersInGroup = Physics.OverlapBox(bc.transform.position, bc.template.castBox + new Vector3(1f, 1f, 1f) * groupSnapTolerance, bc.transform.rotation, ConstraintController.getBuildingsMask()); closestGroup = null; float minDistance = 0; foreach (Collider c in collidersInGroup) { BeyondComponent collided_bc = c.transform.GetComponent <BeyondComponent>(); if (collided_bc != null && collided_bc.beyondGroup != null) { result.Add(collided_bc.beyondGroup); float distance = Vector3.Distance(bc.transform.position, collided_bc.transform.position); if (closestGroup == null || distance < minDistance) { minDistance = distance; closestGroup = collided_bc.beyondGroup; } } } UIController.Instance.SetClosestGroup(closestGroup); return(result); }