Friday, December 9, 2022
HomeGame Developmentpython - The right way to snap positioned blocks to closest snap...

python – The right way to snap positioned blocks to closest snap level?


I’m making a snapping constructing system in Ursina Engine (Python3).

  1. Create an the world (floor, a and b entities)
  2. Add a FirstPersonController
  3. Detect if left mouse button was pressed and if that’s the case begin Place class
  4. On Place class, create self.block and drag it to the place the mouse is pointing (raycast) or if raycast == None (it means the raycast did not collide with something), father or mother self.block to the digicam and put it in entrance of the participant’s digicam with a distance of 5 meters.
  5. Detect if self.block is at a distance of 1 meter of any snap level
  • They’re within the Dice’s class, in 1 meter away from every face from the dice’s mannequin.
  • The snap detection works by getting the gap between self.block and each snap level on this planet. If the gap between a sure snap level and self.block, then it is going to set the self.block’s place to the snap level

The snapping detection is just not very optimized and it’s not detecting the closest snapping level.

If you can also make the code higher and/or clear up the snapping downside, please put up your evaluation. Any assistance is welcome.

from ursina import *
from ursina.prefabs import *
from ursina.shaders import *


from direct.process import Process

from FPC import *

app = Ursina()

participant = FirstPersonController()
mouse.locked = False

Entity.default_shader = lit_with_shadows_shader
pivot = Entity()
direc_light = DirectionalLight(father or mother=pivot, y=2, z=3, shadows=True, rotation=(45, -45, 45), shadow_map_resolution = Vec2(4024, 4024))

amb_light = AmbientLight(father or mother=pivot, coloration = coloration.rgb(100, 100, 100), shadows = True)



world = Entity(mannequin="dice", scale=(20,.5,20), collider="mesh", coloration = coloration.white, everlasting = True)
participant.place = world.place
participant.y = 20


'''
Class Dice with a mannequin and eight snap items

UPDATE. Put a snapper in every face of the dice

'''

can_place_another_block = True


class Dice(Entity):
    def __init__(self, father or mother = None, identify="main_cube", conn_name="connectors", color = coloration.blue, place = (0,0,0), collider="mesh"):
        tremendous().__init__(
            father or mother=father or mother,
            identify=identify,
            mannequin="dice",
            place = place,
            coloration=color,
            collider=collider, 
            )

        self.level = checklist()


        self.snap_points = [
            (0, 1, 0),
            (0, -1, 0),
            (1, 0, 0),
            (-1, 0, 0),
            (0, 0, 1),
            (0, 0, -1),
            
            ]


        for i in vary(len(self.snap_points)):
            snap_point = Entity(father or mother = self,
                                identify = conn_name,
                                mannequin="dice",
                                world_x=self.x+self.snap_points[i][0],
                                world_y=self.y+self.snap_points[i][1],
                                world_z=self.z+self.snap_points[i][2],
                                scale=.1,
                                coloration=coloration.crimson,
                                collider="field"
                                )

            self.level.append(snap_point)


a = Dice(collider="field", place=(0,0,0))

b = Dice(collider="field", place=(2,0,0))


class Place(Entity):
    def __init__(self):
        tremendous().__init__()

        self.block = Dice(father or mother = None, identify="second_cube", conn_name="invalid_connector", color = coloration.inexperienced, place = mouse.world_point, collider = None)

        self.connectors_list = checklist()


        # Loop via all entities on this planet
        for entity in scene.entities:

            # If an entity is of sort connectors, them
            if(entity.identify == "connectors"):
                entity.coloration = coloration.yellow
                self.connectors_list.append(entity)



    ## BUG IN CLOSEST ##
    '''
    get all entities to test and the principle entity
    test the closest

    '''


    def closest(self, entity, iterable):

        distances = []
        for i in iterable:
            i.coloration = coloration.black

        for calculate_entity in iterable:
            nearest = distance(calculate_entity, entity)
            distances.append(nearest)


        min_index = 0
        list_len = len(distances)
        for index in vary(list_len):
            if distances[index] < distances[min_index]:
                min_index = index

        print(distances, "nn")
        print(distance(self.block, iterable[min_index]))
        #iterable[min_index].scale = 1.5
        return iterable[min_index]


            

    def replace(self):

            



        
        closest = self.closest(self.block, self.connectors_list)

        if distance(self.block, closest) < 1:
            self.block.place = closest.world_position
            closest.coloration = coloration.inexperienced
            if held_keys['left mouse down']:
                destroy(closest)
        else:
                
            strive:
                cube_position = raycast(digicam.world_position, course=digicam.ahead, distance=5, traverse_target=scene, ignore=(participant, ), debug=False)
                
                
                print(cube_position.world_point)
                
                if cube_position.world_point == None:
                    self.block.father or mother = digicam
                    self.block.x = 0
                    self.block.y = 0
                    self.block.z = 5
                    self.block.world_rotation_x = 0
                else:
                    self.block.father or mother = None
                    self.block.world_position = cube_position.world_point
                    self.block.x = 0
                    self.block.y = 0

                    #print(self.block.screen_position + self.block.world_position)

            besides Exception as e:
                print(e)

            
##
##        for i, level in enumerate(self.block.level):
##            level.x=self.x+self.block.snap_points[i][0],
##            level.y=self.y+self.block.snap_points[i][1],
##            level.z=self.z+self.block.snap_points[i][2],        
##

            
    
    def enter(self, key):
        international can_place_another_block
        if key == 'left mouse down':
            print("HI")
            Dice(place=self.block.world_position, collider="field")
            
            destroy(self.block)
            can_place_another_block = True
            destroy(self)
            


        
def enter(key):
    international can_place_another_block
    if key == 'proper mouse down' and can_place_another_block == True:
        can_place_another_block = False
        Place()

    if key == 'escape':
        mouse.locked = False

    if key == 'p':
        destroy(mouse.hovered_entity)
        
    if key == 'l':
        mouse.locked = True

app.run()
```

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments