private void GetNeighboursAndObstaclesViaMesh() { neighbours = new List <Neighbour>(); obstacles = new List <Vector3>(); var spaceState = GetWorld().DirectSpaceState; var perceptionShape = GetNode("perceptionMesh") as MeshInstance; if (perceptionShape == null) { return; } PhysicsShapeQueryParameters collisionShape = new PhysicsShapeQueryParameters(); collisionShape.SetTransform(perceptionShape.GetGlobalTransform());; collisionShape.SetShape(perceptionShape.Mesh.CreateConvexShape()); var result = spaceState.IntersectShape(collisionShape); foreach (Godot.Collections.Dictionary collision in result) { if (collision.ContainsKey("collider")) { if (collision["collider"] is Critter critter && critter != this) { neighbours.Add(new Neighbour(critter)); continue; } else if (collision["collider"] is StaticBody staticBody && staticBody.IsInGroup("obstacles")) { // Cast ray to object's origin to find where it hits var rayResult = spaceState.IntersectRay(this.Transform.origin, staticBody.Transform.origin); if (rayResult.Count > 0) { obstacles.Add((Vector3)rayResult["position"]); } } } }
public bool PlaceBlock(byte blockId) { var hitInfo = GetHitInfo(); if (hitInfo != null) { Vector3 pos = (Vector3)hitInfo["position"] + (Vector3)hitInfo["normal"] * 0.5f * Block.SIZE; IntVector3 blockPos = new IntVector3((int)Mathf.Round(pos.x / Block.SIZE), (int)Mathf.Round(pos.y / Block.SIZE), (int)Mathf.Round(pos.z / Block.SIZE)); Vector3 blockCollisionPos = new Vector3(blockPos.x, blockPos.y, blockPos.z) * Block.SIZE; BoxShape bs = new BoxShape(); bs.SetExtents(new Vector3(Block.SIZE, Block.SIZE, Block.SIZE) / 2); PhysicsShapeQueryParameters psqp = new PhysicsShapeQueryParameters(); psqp.SetShape(bs); Transform t = new Transform(new Vector3(1.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f), new Vector3(0.0f, 0.0f, 0.0f)).Translated(blockCollisionPos); psqp.SetTransform(t); object[] res = spaceState.IntersectShape(psqp); if (res.Length > 0) { for (int i = 0; i < res.Length; i++) { Dictionary <object, object> info = (Dictionary <object, object>)spaceState.IntersectShape(psqp)[i]; if (info["collider"] is KinematicBody) { // A moving body (player, animal etc.) is in the way return(false); } } } terrain.SetBlock(blockPos, blockId); return(true); } return(false); }