예제 #1
0
    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"]);
                    }
                }
            }
        }
예제 #2
0
    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);
    }
예제 #3
0
        public override void _PhysicsProcess(float delta)
        {
            if (State == DoorState.Opened)
            {
                var space = _cellBody.GetWorld().DirectSpaceState;

                using (var query = new PhysicsShapeQueryParameters())
                {
                    query.SetShape(_cellShape.Shape);
                    query.CollisionMask     = (int)Level.CollisionLayers.Characters;
                    query.CollideWithBodies = true;
                    query.CollideWithAreas  = false;
                    query.Transform         = _cellShape.GlobalTransform;

                    using (var results = space.IntersectShape(query))
                    {
                        _canClose = (results == null || results.Count < 1);
                    }
                }
            }

            base._PhysicsProcess(delta);
        }