ursina API Reference

v5.0.0

Ursina

ursina/main

Ursina(title='ursina', icon='textures/ursina.ico', borderless=True, fullscreen=False, size=None, forced_aspect_ratio=None, position=None, vsync=True, editor_ui_enabled=True, window_type='onscreen', development_mode=True, render_mode=None, show_ursina_splash=False, **kwargs)

.mouse = mouse

functions:
 input_up(key, is_raw=False) internal method for key release
 input_hold(key, is_raw=False) internal method for handling repeating input that occurs when you hold the key
 input(key, is_raw=False) internal method for handling input
 text_input(key) internal method for handling text input
 step(): # use this control the update loop yourself. call app.step() in a while loop for example, instead of app.run() use this control the update loop yourself. call app.step() in a while loop for example, instead of app.run()
 run(info=True)

example:
from ursina import * app = Ursina(use_ingame_console=True) def input(key): print(key) app.run()

Entity(, metaclass=PostInitCaller)

ursina/entity

Entity(add_to_scene_entities=True, enabled=True, **kwargs)

Entity.rotation_directions = (-1,-1,1)
.name = camel_to_snake(self.__class__.__name__)
.ignore = False if True, will not try to run code.
.ignore_paused = False if True, will still run when application is paused. useful when making a pause menu for example.
.ignore_input = False
.parent = scene default parent is scene, which means it's in 3d space. to use UI space, set the parent to camera.ui instead.
.add_to_scene_entities = add_to_scene_entities set to False to be ignored by the engine, but still get rendered.
.scripts = [] add with add_script(class_instance). will assign an 'entity' variable to the script.
.animations = []
.hovered = False will return True if mouse hovers entity.
.line_definition = None returns a Traceback(filename, lineno, function, code_context, index).
.enabled = enabled

properties:
.enabled# disabled entities will not be visible nor run code.
.model# set model with model='model_name' (without file type extension)
.color
.eternal# eternal entities does not get destroyed on scene.clear()
.double_sided
.render_queue# for custom sorting in case of conflict. To sort things in 2d, set .z instead of using this.
.parent
.loose_parent
.world_parent# change the parent, but keep position, rotation and scale
.types# get all class names including those this inhertits from.
.visible
.visible_self# set visibility of self, without affecting children.
.collider# set to 'box'/'sphere'/'capsule'/'mesh' for auto fitted collider.
.collision# toggle collision without changing collider.
.on_click
.origin
.origin_x
.origin_y
.origin_z
.world_position
.world_x
.world_y
.world_z
.position# right, up, forward. can also set self.x, self.y, self.z
.x
.y
.z
.X# shortcut for int(entity.x)
.Y# shortcut for int(entity.y)
.Z# shortcut for int(entity.z)
.world_rotation
.world_rotation_x
.world_rotation_y
.world_rotation_z
.rotation# can also set self.rotation_x, self.rotation_y, self.rotation_z
.rotation_x
.rotation_y
.rotation_z
.quaternion
.world_scale
.world_scale_x
.world_scale_y
.world_scale_z
.scale# can also set self.scale_x, self.scale_y, self.scale_z
.scale_x
.scale_y
.scale_z
.transform# get/set position, rotation and scale
.world_transform# get/set world_position, world_rotation and world_scale
.forward# get forward direction.
.back# get backwards direction.
.right# get right direction.
.left# get left direction.
.up# get up direction.
.down# get down direction.
.screen_position# get screen position(ui space) from world space.
.shader
.shader_input
.material# a way to set shader, texture, texture_scale, texture_offset and shader inputs in one go
.texture# set model with texture='texture_name'. requires a model to be set beforehand.
.texture_scale# how many times the texture should repeat, eg. texture_scale=(8,8).
.texture_offset
.tileset_size# if the texture is a tileset, say how many tiles there are so it only use one tile of the texture, e.g. tileset_size=[8,4]
.tile_coordinate# set the tile coordinate, starts in the lower left.
.alpha# shortcut for setting color's transparency/opacity
.always_on_top
.unlit# set to True to ignore light and not cast shadows
.billboard# set to True to make this Entity always face the camera.
.wireframe# set to True to render model as wireframe
.model_bounds
.bounds
.flipped_faces
.children
.loose_children
.attributes# attribute names. used by duplicate().

functions:
 enable() same as .enabled = True
 disable() same as .enabled = False
 get_shader_input(name)
 set_shader_input(name, value)
 generate_sphere_map(size=512, name=f'sphere_map_{len(scene.entities)}')
 generate_cube_map(size=512, name=f'cube_map_{len(scene.entities)}')
 get_position(relative_to=scene) get position relative to on other Entity. In most cases, use .position instead.
 set_position(value, relative_to=scene) set position relative to on other Entity. In most cases, use .position instead.
 rotate(value, relative_to=None) rotate around local axis.
 add_script(class_instance)
 combine(analyze=False, auto_destroy=True, ignore=[])
 look_at(target, axis='forward', up=None) up defaults to self.up
 look_at_2d(target, axis='z')
 look_at_xy(target)
 look_at_xz(target)
 has_ancestor(possible_ancestor)
 has_disabled_ancestor()
 get_changes(target_class=None) returns a dict of all the changes
 animate(name, value, duration=.1, delay=0, curve=curve.in_expo, loop=False, resolution=None, interrupt='kill', time_step=None, unscaled=False, auto_play=True, auto_destroy=True)
 animate_position(value, duration=.1, **kwargs)
 animate_rotation(value, duration=.1, **kwargs)
 animate_scale(value, duration=.1, **kwargs)
 animate_{e}(value, duration=.1, delay=0, unscaled=False, **kwargs)
 shake(duration=.2, magnitude=1, speed=.05, direction=(1,1), delay=0, attr_name='position', interrupt='finish', unscaled=False)
 animate_color(value, duration=.1, interrupt='finish', unscaled=False, **kwargs)
 fade_out(value=0, duration=.5, unscaled=False, **kwargs)
 fade_in(value=1, duration=.5, **kwargs)
 blink(value=ursina.color.clear, duration=.1, delay=0, curve=curve.in_expo_boomerang, interrupt='finish', **kwargs)
 intersects(traverse_target=scene, ignore:list=None, debug=False)

example:
e = Entity(model='quad', color=color.orange, position=(0,0,1), scale=1.5, rotation=(0,0,45), texture='brick') '''example of inheriting Entity''' class Player(Entity): def __init__(self, **kwargs): super().__init__() self.model='cube' self.color = color.red self.scale_y = 2 for key, value in kwargs.items(): setattr(self, key, value) def input(self, key): if key == 'space': self.animate_x(2, duration=1) def update(self): self.x += held_keys['d'] * time.dt * 10 self.x -= held_keys['a'] * time.dt * 10 player = Player(x=-1)

Button(Entity)

ursina/prefabs/button

Button(text='', parent=camera.ui, model=Default, radius=.1, origin=(0,0), text_origin=(0,0), text_size=1, color=Default, collider='box', highlight_scale=1, pressed_scale=1, disabled=False, **kwargs)

.origin = origin
.color = color
.highlight_color = self.color.tint(.2)
.pressed_color = self.color.tint(-.2)
.highlight_scale = highlight_scale multiplier
.pressed_scale = pressed_scale multiplier
.highlight_sound = None
.pressed_sound = None
.collider = collider
.disabled = disabled
.text_entity = None
.text_origin = text_origin

properties:
.text
.text_origin
.text_color
.icon
.icon_world_scale
.text_size
.origin

functions:
 input(key)
 on_mouse_enter()
 on_mouse_exit()
 fit_to_text(radius=.1, padding=Vec2(Text.size*1.5, Text.size))

example:
Button.default_color = color.red b = Button(model='quad', scale=.05, x=-.5, color=color.lime, text='text scale\ntest', text_size=.5, text_color=color.black) b.text_size = .5 b.on_click = Sequence(Wait(.5), Func(print, 'aaaaaa'), ) b = Button(parent=camera.ui, text='hello world!', scale=.25) Button.default_color = color.blue b = Button(text='hello world!', icon='sword', scale=.25, text_origin=(-.5,0), x=.5) b.on_click = application.quit # assign a function to the button. b.tooltip = Tooltip('exit') par = Entity(parent=camera.ui, scale=.2, y=-.2) b = Button(parent=par, text='test', scale_x=1, origin=(-.5,.5)) b.text ='new text' print(b.text_entity) Button(text='sound', scale=.2, position=(-.25,-.2), color=color.pink, highlight_sound='blip_1', pressed_sound=Audio('coin_1', autoplay=False)) Text('Text size\nreference', x=.15) def input(key): if key == 'd': scene.clear() if key == 'space': b.text = 'updated text'

Sprite(Entity)

ursina/prefabs/sprite

Sprite(texture=None, **kwargs)

Sprite.ppu = 100
.model = 'quad'
.texture = texture
.ppu = Sprite.ppu
.aspect_ratio = self.texture.width / self.texture.height
.scale_x = self.scale_y * self.aspect_ratio


example:
camera.orthographic = True camera.fov = 1 Sprite.ppu = 16 Texture.default_filtering = None s = Sprite('brick', filtering=False)

Text(Entity)

ursina/text

Text(text='', start_tag=start_tag, end_tag=end_tag, ignore=True, **kwargs)

Text.size = .025
.size = Text.size
.parent = camera.ui
.shader = None
.text_nodes = []
.images = []
.origin = (-.5, .5)
.font = Text.default_font
.resolution = Text.default_resolution
.use_tags = True
.line_height = 1
.start_tag = start_tag
.end_tag = end_tag
.text_colors = {'default' : color.text_color}
.tag = Text.start_tag+'default'+Text.end_tag
.current_color = self.text_colors['default']
.scale_override = 1
.appear_sequence = None gets created when calling appear()

properties:
.text
.font
.color# sets the default color.
.line_height
.width# gets the width of the widest line.
.height# gets the height of the text
.lines
.resolution
.wordwrap# set this to make the text wrap after a certain number of characters.
.origin
.background

functions:
 text(text)
 create_text_section(text, tag='', x=0, y=0)
 align()
 create_background(padding=size*2, radius=size, color=ursina.color.black66)
 appear(speed=.025)
 get_width(string, font=None)

example:
from ursina import * from ursina import Ursina, dedent, window app = Ursina() descr = dedent(''' <red>Rainstorm<default> <red>Rainstorm<default> Summon a rain storm to deal 5 <blue>water<default> damage to everyone, test including yourself. 1234 1234 1234 1234 1234 1234 2134 1234 1234 1234 1234 1234 2134 2134 1234 1234 1234 1234 Lasts for 4 rounds.''').strip() Text.default_resolution = 1080 * Text.size test = Text(text=descr, wordwrap=30) def input(key): if key == 'a': print('a') test.text = '<default><image:file_icon> <red><image:file_icon> test ' print('by', test.text) if key == 'c': test.text = '' window.fps_counter.enabled = False print('....', Text.get_width('yolo')) app.run()

Audio(Entity)

ursina/audio

Audio(sound_file_name='', volume=1, pitch=1, balance=0, loop=False, loops=1, autoplay=True, auto_destroy=False, **kwargs)

Audio.volume_multiplier = .5 #
.clip = sound_file_name
.volume = volume
.pitch = pitch
.balance = balance
.loop = loop
.autoplay = autoplay
.auto_destroy = auto_destroy

properties:
.volume
.pitch
.loop
.loops
.clip
.length# get the duration of the audio clip.
.status
.ready
.playing
.time
.balance# pan the audio. should be a value between -.5 and .5. default: 0

functions:
 play(start=0)
 pause()
 resume()
 stop(destroy=True)
 fade(value, duration=.5, delay=0, curve=curve.in_expo, resolution=None, interrupt=True)
 fade_in(value=1, duration=.5, delay=0, curve=curve.in_expo, resolution=None, interrupt='finish',)
 fade_out(value=0, duration=.5, delay=0, curve=curve.in_expo, resolution=None, interrupt='finish',)

example:
from ursina import Ursina import random a = Audio('sine', loop=True, autoplay=True) a.volume = .5 print('---', a.volume) def input(key): if key == 'space': a = Audio('sine', pitch=random.uniform(.5,1), loop=True)

camera

ursina/camera

.parent = scene
.name = 'camera'
.eternal = True
.ui_size = 40
.perspective_lens_node = None
.orthographic_lens_node = None
.ui = Entity(eternal=True, name='ui', scale=(self.ui_size*.5, self.ui_size*.5), add_to_scene_entities=False)
.overlay = Entity(parent=self.ui, model='quad', scale=99, color=color.clear, eternal=True, z=-99, add_to_scene_entities=False)

functions:
 set_up()
 orthographic_getter()
 orthographic_setter(value)
 fov_getter()
 fov_setter(value)
 clip_plane_near_getter()
 clip_plane_near_setter(value)
 clip_plane_far_getter()
 clip_plane_far_setter(value)
 aspect_ratio_getter()
 shader_setter(value)
 set_shader_input(name, value)

example:
from ursina import Ursina, camera, Entity, EditorCamera camera.orthographic = True e = Entity() e.model = 'quad' e.color = color.random_color() e.position = (-2, 0, 10) e = Entity() e.model = 'quad' e.color = color.random_color() e.position = (2, 0, 10) e = Entity() e.model = 'quad' e.color = color.random_color() e.position = (0, 0, 40) EditorCamera() from ursina.shaders import camera_grayscale_shader camera.shader = camera_grayscale_shader

mouse

ursina/mouse

.enabled = False
.visible = True
.locked = False
.position = Vec3(0,0,0)
.delta = Vec3(0,0,0) movement since you pressed a mouse button.
.prev_x = 0
.prev_y = 0
.start_x = 0
.start_y = 0
.velocity = Vec3(0,0,0)
.moving = False
.prev_click_time = time.time()
.prev_click_pos = None
.double_click_distance = .5
.double_click_movement_limit = .01
.hovered_entity = None returns the closest hovered entity with a collider.
.left = False
.right = False
.middle = False
.delta_drag = Vec3(0,0,0) movement between left mouse down and left mouse up.
.update_step = 1
.traverse_target = scene set this to None to disable collision with scene, which might be a good idea if you have lots of colliders.
.raycast = True
.collision = None
.collisions = []
.enabled = True

functions:
 x()
 x(value)
 y()
 y(value)
 position()
 position(value)
 locked()
 locked(value)
 visible()
 visible(value)
 input(key)
 update()
 normal() returns the normal of the polygon, in local space.
 world_normal() returns the normal of the polygon, in world space.
 point() returns the point hit, in local space
 world_point() returns the point hit, in world space
 is_outside()
 find_collision()
 unhover_everything_not_hit()

example:
from ursina import Ursina, Button, mouse Button(parent=scene, text='a') def input(key): if key == 'space': mouse.locked = not mouse.locked print(mouse.velocity) Cursor()

window

ursina/window

.title = title
.icon = icon
.monitors = []
.main_monitor = None
.monitor_index = 0
.windowed_position = None gets set when entering fullscreen so position will be correct when going back to windowed mode
.show_ursina_splash = False
.top = Vec2(0, .5)
.bottom = Vec2(0, -.5)
.center = Vec2(0, 0)
.forced_aspect_ratio = None example: window.forced_aspect_ratio
.always_on_top = False
.vsync = True can't be set during play
.color = color.dark_gray
.render_modes = ('default', 'wireframe', 'colliders', 'normals')
.render_mode = 'default'
.editor_ui = None
.position = Vec2(x,y)
.editor_ui = Entity(parent=camera.ui, eternal=True, enabled=bool(application.development_mode))
.input_entity = Entity(name
.exit_button = Button(parent=self.editor_ui, text='x', eternal=True, ignore_paused=True, origin=(.5, .5), enabled=self.borderless, position=self.top_right, z=-999, scale=(.05, .025), color=color.red.tint(-.2), on_click=application.quit, name='exit_button')
.fps_counter = Text(parent=self.editor_ui, eternal=True, text='60', ignore=False, i=0, ignore_paused=True, position=((.5*self.aspect_ratio)-self.exit_button.scale_x, .47+(.02*(not self.exit_button.enabled)), -999))
.entity_counter = Text(parent=self.editor_ui, eternal=True, origin=(-.5,.5), text='00', ignore=False, t=0, position=((.5*self.aspect_ratio)-self.exit_button.scale_x, .425+(.02*(not self.exit_button.enabled)), -999))
.collider_counter = Text(parent=self.editor_ui, eternal=True, origin=(-.5,.5), text='00', ignore=False, t=.1, position=((.5*self.aspect_ratio)-self.exit_button.scale_x, .38+(.02*(not self.exit_button.enabled)), -999))
.cog_menu = ButtonList({ 'Build' : Func(print, ' '), 'API Reference' : Func(webbrowser.open, 'https://www.ursinaengine.org/api_reference.html'), # 'Asset Store' : Func(webbrowser.open, 'https://itch.io/tools/tag-ursina'), 'ursfx (Sound Effect Maker)' : lambda: exec('from ursina.prefabs import ursfx; ursfx.open_gui()'), # 'Open Scene Editor' : Func(print, ' '), 'Change Render Mode <gray>[F10]<default>' : self.next_render_mode, 'Reset Render Mode <gray>[Shift+F10]<default>' : Func(setattr, self, 'render_mode', 'default'), 'Toggle Hotreloading <gray>[F9]<default>' : application.hot_reloader.toggle_hotreloading, 'Reload Shaders <gray>[F7]<default>' : application.hot_reloader.reload_shaders, 'Reload Models <gray>[F7]<default>' : application.hot_reloader.reload_models, 'Reload Textures <gray>[F6]<default>' : application.hot_reloader.reload_textures, 'Reload Code <gray>[F5]<default>' : application.hot_reloader.reload_code,
.cog_button = Button(parent=self.editor_ui, eternal=True, model='quad', texture='cog', scale=.015, origin=(1,-1), position=self.bottom_right, ignore_paused=True, name='cog_button')
.prev_size = self.size
.size = self.size
.render_mode = self.render_modes[i]

functions:
 ready(title, icon, borderless, fullscreen, size, forced_aspect_ratio, position, vsync, editor_ui_enabled, window_type, render_mode)
 apply_settings()
 left()
 right()
 top_left()
 top_right()
 bottom_left()
 bottom_right()
 center_on_screen()
 make_editor_gui() called by main after setting up camera and application.development_mode
 window_input(key)
 update_aspect_ratio()
 position()
 position(value)
 size()
 size(value)
 aspect_ratio()
 forced_aspect_ratio()
 forced_aspect_ratio(value)
 render_mode()
 render_mode(value)
 next_render_mode()
 title()
 title(value)
 icon()
 icon(value)
 borderless()
 borderless(value)
 fullscreen()
 fullscreen(value)
 color()
 color(value)
 vsync()
 vsync(value)

example:
app = Ursina( title='Ursina', ) button_list = ButtonList( { 'widow.position = Vec2(0,0)': Func(setattr, window, 'position', Vec2(0,0)), 'widow.size = Vec2(512,512)': Func(setattr, window, 'size', Vec2(512,512)), 'widow.center_on_screen()': window.center_on_screen, 'widow.borderless = True': Func(setattr, window, 'borderless', True), 'widow.borderless = False': Func(setattr, window, 'borderless', False), 'widow.fullscreen = True': Func(setattr, window, 'fullscreen', True), 'widow.fullscreen = False': Func(setattr, window, 'fullscreen', False), 'widow.vsync = True': Func(setattr, window, 'vsync', True), 'widow.vsync = False': Func(setattr, window, 'vsync', False), 'application.base.win.request_properties(self)': Func(application.base.win.request_properties, window), }, y=0 ) startup_value = Text(y=.5,x=-.5) startup_value.text = f''' position: {window.position} size: {window.size} aspect_ratio: {window.aspect_ratio} window.main_monitor.width: {window.main_monitor.width} window.main_monitor.height: {window.main_monitor.height} ''' position_text = Text(y=.5,) def input(key): if key == 'space': window.center_on_screen()

application

ursina/application

.paused = False
.time_scale = 1
.calculate_dt = True
.sequences = []
.trace_entity_definition = False enable to set entity.line_definition
.package_folder = Path(__file__).parent
.blender_paths = dict()
.development_mode = True
.window_type = 'onscreen'
.show_ursina_splash = False
.ursina_splash = None
.gltf_no_srgb = True
.scenes_folder = asset_folder / 'scenes/'
.scripts_folder = asset_folder / 'scripts/'
.fonts_folder = asset_folder / 'fonts/'
.compressed_textures_folder = asset_folder / 'textures_compressed/'
.compressed_models_folder = asset_folder / 'models_compressed/'
.base = None this will be set once the Ursina() is created
.hot_reloader = None will be set my main if development_mode

functions:
 pause()
 resume()
 quit()
 load_settings(path=asset_folder / 'settings.py')


scene

ursina/scene

.entities = []
.collidables = set()

functions:
 set_up()
 clear()
 fog_color()
 fog_color(value)
 fog_density()
 fog_density(value)
 children()
 children(value)

example:
e = Entity(model='plane', color=color.black, scale=100) EditorCamera() s = Sky() def input(key): if key == 'l': for e in scene.entities: print(e.name) if key == 'd': scene.clear() Entity(model='cube') scene.fog_density = .1 # sets exponential density scene.fog_density = (50, 200) # sets linear density start and end

color

ursina/color

.@deprecated("Use hsv(...) instead of color(...)")
.white = hsv(0, 0, 1)
.smoke = hsv(0, 0, 0.96)
.light_gray = hsv(0, 0, 0.75)
.gray = hsv(0, 0, 0.5)
.dark_gray = hsv(0, 0, 0.25)
.black = hsv(0, 0, 0)
.red = hsv(0, 1, 1)
.yellow = hsv(60, 1, 1)
.lime = hsv(90, 1, 1)
.green = hsv(120, 1, 1)
.turquoise = hsv(150, 1, 1)
.cyan = hsv(180, 1, 1)
.azure = hsv(210, 1, 1)
.blue = hsv(240, 1, 1)
.violet = hsv(270, 1, 1)
.magenta = hsv(300, 1, 1)
.pink = hsv(330, 1, 1)
.brown = rgb32(165, 42, 42)
.olive = rgb32(128, 128, 0)
.peach = rgb32(255, 218, 185)
.gold = rgb32(255, 215, 0)
.salmon = rgb32(250, 128, 114)
.clear = rgba(0, 0, 0, 0)
.white10 = rgba(1,1,1, 0.10)
.white33 = rgba(1,1,1, 0.33)
.white50 = rgba(1,1,1, 0.50)
.white66 = rgba(1,1,1, 0.66)
.black10 = rgba(0,0,0, 0.10)
.black33 = rgba(0,0,0, 0.33)
.black50 = rgba(0,0,0, 0.50)
.black66 = rgba(0,0,0, 0.66)
.black90 = rgba(0,0,0, 0.90)
.text = smoke
.light_text = smoke
.dark_text = hsv(0, 0, .1)
.text_color = light_text
.color_names = ('white', 'smoke', 'light_gray', 'gray', 'dark_gray', 'black',
.colors = dict()

functions:
 color(h,s,v,a=1)
 hsv(h, s, v, a=1)
 rgba32(r, g, b, a=255)
 rgb32(r, g, b)
 rgba(r, g, b, a)
 rgb(r, g, b)
 to_hsv(color)
 hex(value)
 rgb_to_hex(r, g, b, a=1)
 brightness(color)
 inverse(color)
 random_color()
 tint(color, amount=.2)

example:
from ursina import Ursina, Entity, Button, Quad, grid_layout, color print(color.brightness(color.blue)) p = Entity(x=-2) for key in color.colors: print(key) b = Button(parent=p, model=Quad(0), color=color.colors[key], text=key) b.text_entity.scale *= .5 grid_layout(p.children, max_x=8) for name in ('r', 'g', 'b', 'h', 's', 'v', 'brightness'): print(name + ':', getattr(color.random_color(), name)) e = Entity(model='cube', color=color.lime) print(e.color.name) print('rgb to hex:', color.rgb_to_hex(*color.blue)) e.color = color.color(1,2,3)

Mesh(p3d.)

ursina/mesh

Mesh(vertices=None, triangles=None, colors=None, uvs=None, normals=None, static=True, mode='triangle', thickness=1, render_points_in_3d=True, vertex_buffer=None, vertex_buffer_length=None, vertex_buffer_format=None)

Mesh.'triangle' : p3d.GeomTriangles,
Mesh.'tristrip' : p3d.GeomTristrips,
Mesh.'ngon' : p3d.GeomTrifans,
Mesh.'line' : p3d.GeomLinestrips,
Mesh.'point' : p3d.GeomPoints,
Mesh.}
.vertices = vertices
.triangles = triangles
.colors = colors
.uvs = uvs
.normals = normals
.static = static
.mode = mode
.thickness = thickness
.render_points_in_3d = render_points_in_3d
.vertex_buffer = vertex_buffer
.vertex_buffer_length = vertex_buffer_length
.vertex_buffer_format = vertex_buffer_format

properties:
.indices
.generated_vertices
.recipe
.render_points_in_3d
.thickness

functions:
 generate()
 generate_normals(smooth=True, regenerate=True)
 colorize(left=color.white, right=color.blue, down=color.red, up=color.green, back=color.white, forward=color.white, smooth=True, world_space=True, strength=1)
 project_uvs(aspect_ratio=1, direction='forward')
 clear(regenerate=True)
 save(name='', folder:Path=Func(getattr, application, 'compressed_models_folder'), flip_faces=False, max_decimals=16)

example:
e = Entity(position=(0,0), model=Mesh(vertices=[(-.5,0,0), (.5,0,0), (0, 1, 0)])) e = Entity(position=(1,0), model=Mesh(vertices=((-.5,0,0), (.5,0,0), (0, 1, 0)))) Text(parent=e, text='triangle mesh\nwith verts as tuple of tuples', y=1, scale=5, origin=(0,-.5)) e = Entity(position=(0,-2), model=Mesh(vertices=[[-.5,0,0], [.5,0,0], [0, 1, 0]])) Text(parent=e, text='triangle mesh\nwith verts as list of lists', y=1, scale=5, origin=(0,-.5)) e = Entity(position=(1,-2), model=Mesh( vertices=([-.5,0,0], [.5,0,0], [0, 1, 0]) )) Text(parent=e, text='triangle mesh\nwith verts as tuple of lists', y=1, scale=5, origin=(0,-.5)) e = Entity(position=(0,-4), model=Mesh( vertices=[Vec3(-.5,0,0), Vec3(.5,0,0), Vec3(0, 1, 0)], )) Text(parent=e, text='triangle mesh\nwith verts as list Vec3', y=1, scale=5, origin=(0,-.5)) e = Entity(position=(1,-4), model=Mesh( vertices=[Vec3(-.5,0,0), Vec3(.5,0,0), Vec3(0, 1, 0)], triangles = [0,1,2], )) Text(parent=e, text='triangle mesh\nwith tris as flat list', y=1, scale=5, origin=(0,-.5)) e = Entity(position=(2.5,0), model=Mesh( vertices=[Vec3(-.5,0,0), Vec3(.5,0,0), Vec3(0, 1, 0)], triangles = [(0,1,2), (2,1,0)], # should be double sided )) Text(parent=e, text='triangle mesh\nwith tris as list of triangles', y=1, scale=5, origin=(0,-.5)) continious_line = Entity(position=(4,0), model=Mesh( vertices=(Vec3(0,0,0), Vec3(.6,.3,0), Vec3(1,1,0), Vec3(.6,1.7,0), Vec3(0,2,0)), mode='line', thickness=4, ), color=color.cyan) Text(parent=continious_line, text='continious_line', y=1, scale=5) line_segments = Entity(position=(4,-2), model=Mesh( vertices=(Vec3(0,0,0), Vec3(.6,.3,0), Vec3(1,1,0), Vec3(.6,1.7,0), Vec3(0,2,0)), triangles= ((0,1), (3,4)), mode='line', thickness=4, ), color=color.magenta) Text(parent=line_segments, text='line_segments', y=1, scale=5) points = Entity(position=(6,0), model=Mesh(vertices=(Vec3(0,0,0), Vec3(.6,.3,0), Vec3(1,1,0), Vec3(.6,1.7,0), Vec3(0,2,0)), mode='point', thickness=.05), color=color.red) Text(parent=points, text='points', y=1, scale=5) points_2d = Entity(position=(6,-2), model=Mesh(vertices=(Vec3(0,0,0), Vec3(.6,.3,0), Vec3(1,1,0), Vec3(.6,1.7,0), Vec3(0,2,0)), mode='point', thickness=10, render_points_in_3d=False), color=color.red) Text(parent=points_2d, text='points_2d', y=1, scale=5) quad = Entity( position=(8,0), model=Mesh( vertices=((0.5, 0.5, 0.0), (-0.5, 0.5, 0.0), (-0.5, -0.5, 0.0), (0.5, -0.5, 0.0), (0.5, 0.5, 0.0), (-0.5, -0.5, 0.0)), uvs=((1, 1), (0, 1), (0, 0), (1, 0), (1, 1), (0, 0)), mode='triangle'), texture='shore' ) Text(parent=quad, text='quad_with_uvs', y=1, scale=5, origin=(0,-.5)) quad = Entity( position=(8,-2), model=Mesh( vertices=((0.5, 0.5, 0.0), (-0.5, 0.5, 0.0), (-0.5, -0.5, 0.0), (0.5, -0.5, 0.0), (0.5, 0.5, 0.0), (-0.5, -0.5, 0.0)), uvs=((1, 1), (0, 1), (0, 0), (1, 0), (1, 1), (0, 0)), normals=[(-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0)], mode='triangle'), ) Text(parent=quad, text='quad_with_normals', y=1, scale=5, origin=(0,-.5)) quad = Entity( position=(8,-4), model=Mesh( vertices=((0.5, 0.5, 0.0), (-0.5, 0.5, 0.0), (-0.5, -0.5, 0.0), (0.5, -0.5, 0.0), (0.5, 0.5, 0.0), (-0.5, -0.5, 0.0)), uvs=((1, 1), (0, 1), (0, 0), (1, 0), (1, 1), (0, 0)), normals=[(-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0)], mode='triangle'), ) Text(parent=quad, text='quad_with_usv_and_normals', y=1, scale=5, origin=(0,-.5)) quad = Entity( position=(8,-6), model=Mesh( vertices=((0.5, 0.5, 0.0), (-0.5, 0.5, 0.0), (-0.5, -0.5, 0.0), (0.5, -0.5, 0.0), (0.5, 0.5, 0.0), (-0.5, -0.5, 0.0)), uvs=((1, 1), (0, 1), (0, 0), (1, 0), (1, 1), (0, 0)), normals=[(-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0), (-0.0, 0.0, -1.0)], colors=[color.red, color.yellow, color.green, color.cyan, color.blue, color.magenta], mode='triangle'), ) Text(parent=quad, text='quad_with_usv_and_normals_and_vertex_colors', y=1, scale=5, origin=(0,-.5)) quad = Entity( position=(10,0), model=Mesh( vertices=((-0.5, -0.5, 0.0), (0.5, -0.5, 0.0), (0.5, 0.5, 0.0), (-0.5, 0.5, 0.0)), triangles=(0,1,2, 2,3,0), mode='triangle'), ) Text(parent=quad, text='triangles flat', y=1, scale=5, origin=(0,-.5)) quad = Entity( position=(10,-2), model=Mesh( vertices=((-0.5, -0.5, 0.0), (0.5, -0.5, 0.0), (0.5, 0.5, 0.0), (-0.5, 0.5, 0.0)), triangles=((0,1,2), (2,3,0)), mode='triangle'), ) Text(parent=quad, text='triangles triplets', y=1, scale=5, origin=(0,-.5)) quad = Entity( position=(10,-4), model=Mesh( vertices=((-0.5, -0.5, 0.0), (0.5, -0.5, 0.0), (0.5, 0.5, 0.0), (-0.5, 0.5, 0.0)), triangles=((0,1,2,3), (0,3,2)), mode='triangle'), ) Text(parent=quad, text='triangles quad + tri', y=1, scale=5, origin=(0,-.5)) copy_test = Entity(position=(12,0), model=copy(quad.model)) Text(parent=copy_test, text='copy_test', y=1, scale=5, origin=(0,-.5)) deepcopy_test = Entity(position=(12,-2), model=deepcopy(quad.model)) Text(parent=deepcopy_test, text='deepcopy_test', y=1, scale=5, origin=(0,-.5)) clear_test = Entity(position=(12,-4), model=deepcopy(quad.model)) clear_test.model.clear() Text(parent=clear_test, text='.clear() test', y=1, scale=5, origin=(0,-.5)) recipe_test = Entity(position=(12,-6), model=eval(quad.model.recipe)) Text(parent=recipe_test, text='.recipe test', y=1, scale=5, origin=(0,-.5)) window.color = color.black EditorCamera()

Shader

ursina/shader

Shader(name='untitled_shader', language=Panda3dShader.SL_GLSL, vertex=default_vertex_shader, fragment=default_fragment_shader, geometry='', **kwargs)

Shader.CG = Panda3dShader.SL_Cg
Shader.GLSL = Panda3dShader.SL_GLSL
Shader.HLSL = Panda3dShader.SL_HLSL
Shader.SPIR_V = Panda3dShader.SL_SPIR_V
.path = Path(_caller.filename)
.name = name
.language = language
.vertex = vertex
.fragment = fragment
.geometry = geometry
.entity = None
.default_input = dict()
.compiled = False

functions:
 compile(shader_includes=True)
 load(cls, language=Panda3dShader.SL_GLSL, vertex=None, fragment=None, geometry=None, **kwargs)

example:
from time import perf_counter t = perf_counter() from ursina import Ursina, Entity, held_keys, scene, EditorCamera Entity(model='cube', shader=Shader()) EditorCamera() print('ttttttttttttt', perf_counter() - t) def input(key): if held_keys['control'] and key == 'r': reload_shaders() def reload_shaders(): for e in scene.entities: if hasattr(e, '_shader'): print('-------', e.shader)

Texture

ursina/texture

Texture(value, filtering='default')

.filtering = filtering

properties:
.name
.size
.width
.height
.pixels
.filtering
.repeat

functions:
 new(size, color=(255,255,255))
 get_pixel(x, y)
 get_pixels(start, end)
 set_pixel(x, y, color)
 apply()
 save(path)

example:
from ursina import texture_importer ''' The Texture class rarely used manually but usually instantiated when assigning a texture to an Entity texture = Texture(path / PIL.Image / panda3d.core.Texture) A texture file can be a .png, .jpg or .psd. If it's a .psd it and no compressed version exists, it will compress it automatically. ''' e = Entity(model='quad', texture='brick') e.texture.set_pixel(0, 2, color.blue) e.texture.apply()

Light(Entity)

ursina/lights

Light(**kwargs)


properties:
.color


example:
from ursina import Ursina, EditorCamera, color, Vec3 from ursina.shaders import lit_with_shadows_shader # you have to apply this shader to enties for them to receive shadows. EditorCamera() Entity(model='plane', scale=10, color=color.gray, shader=lit_with_shadows_shader) Entity(model='cube', y=1, shader=lit_with_shadows_shader, color=color.light_gray) light = DirectionalLight(shadows=True) light.look_at(Vec3(1,-1,1)) dont_cast_shadow = Entity(model='cube', y=1, shader=lit_with_shadows_shader, x=2, color=color.light_gray) dont_cast_shadow.hide(0b0001) unlit_entity = Entity(model='cube', y=1,x=-2, unlit=True, color=color.light_gray) bar = Entity(model='cube', position=(0,3,-2), shader=lit_with_shadows_shader, scale=(10,.2,.2), color=color.light_gray)

DirectionalLight(Light)

ursina/lights

DirectionalLight(shadows=True, **kwargs)

.shadow_map_resolution = Vec2(1024, 1024)

properties:
.shadows

functions:
 update_bounds(entity=scene) update the shadow area to fit the bounds of target entity, defaulted to scene.

example:
from ursina import Ursina, EditorCamera, color, Vec3 from ursina.shaders import lit_with_shadows_shader # you have to apply this shader to enties for them to receive shadows. EditorCamera() Entity(model='plane', scale=10, color=color.gray, shader=lit_with_shadows_shader) Entity(model='cube', y=1, shader=lit_with_shadows_shader, color=color.light_gray) light = DirectionalLight(shadows=True) light.look_at(Vec3(1,-1,1)) dont_cast_shadow = Entity(model='cube', y=1, shader=lit_with_shadows_shader, x=2, color=color.light_gray) dont_cast_shadow.hide(0b0001) unlit_entity = Entity(model='cube', y=1,x=-2, unlit=True, color=color.light_gray) bar = Entity(model='cube', position=(0,3,-2), shader=lit_with_shadows_shader, scale=(10,.2,.2), color=color.light_gray)

PointLight(Light)

ursina/lights

PointLight(**kwargs)



example:
from ursina import Ursina, EditorCamera, color, Vec3 from ursina.shaders import lit_with_shadows_shader # you have to apply this shader to enties for them to receive shadows. EditorCamera() Entity(model='plane', scale=10, color=color.gray, shader=lit_with_shadows_shader) Entity(model='cube', y=1, shader=lit_with_shadows_shader, color=color.light_gray) light = DirectionalLight(shadows=True) light.look_at(Vec3(1,-1,1)) dont_cast_shadow = Entity(model='cube', y=1, shader=lit_with_shadows_shader, x=2, color=color.light_gray) dont_cast_shadow.hide(0b0001) unlit_entity = Entity(model='cube', y=1,x=-2, unlit=True, color=color.light_gray) bar = Entity(model='cube', position=(0,3,-2), shader=lit_with_shadows_shader, scale=(10,.2,.2), color=color.light_gray)

AmbientLight(Light)

ursina/lights

AmbientLight(**kwargs)



example:
from ursina import Ursina, EditorCamera, color, Vec3 from ursina.shaders import lit_with_shadows_shader # you have to apply this shader to enties for them to receive shadows. EditorCamera() Entity(model='plane', scale=10, color=color.gray, shader=lit_with_shadows_shader) Entity(model='cube', y=1, shader=lit_with_shadows_shader, color=color.light_gray) light = DirectionalLight(shadows=True) light.look_at(Vec3(1,-1,1)) dont_cast_shadow = Entity(model='cube', y=1, shader=lit_with_shadows_shader, x=2, color=color.light_gray) dont_cast_shadow.hide(0b0001) unlit_entity = Entity(model='cube', y=1,x=-2, unlit=True, color=color.light_gray) bar = Entity(model='cube', position=(0,3,-2), shader=lit_with_shadows_shader, scale=(10,.2,.2), color=color.light_gray)

SpotLight(Light)

ursina/lights

SpotLight(**kwargs)



example:
from ursina import Ursina, EditorCamera, color, Vec3 from ursina.shaders import lit_with_shadows_shader # you have to apply this shader to enties for them to receive shadows. EditorCamera() Entity(model='plane', scale=10, color=color.gray, shader=lit_with_shadows_shader) Entity(model='cube', y=1, shader=lit_with_shadows_shader, color=color.light_gray) light = DirectionalLight(shadows=True) light.look_at(Vec3(1,-1,1)) dont_cast_shadow = Entity(model='cube', y=1, shader=lit_with_shadows_shader, x=2, color=color.light_gray) dont_cast_shadow.hide(0b0001) unlit_entity = Entity(model='cube', y=1,x=-2, unlit=True, color=color.light_gray) bar = Entity(model='cube', position=(0,3,-2), shader=lit_with_shadows_shader, scale=(10,.2,.2), color=color.light_gray)

Quad(Mesh)

ursina/models/procedural/quad_2

Quad(radius=.1, segments=8, aspect=1, scale=(1,1), mode='ngon', **kwargs)

.vertices = [Vec2(0,0), Vec2(1,0), Vec2(1,1), Vec2(0,1)]
.radius = radius
.mode = mode
.uvs = list()
.vertices = [Vec3(v[0]-offset[0], v[1]-offset[1], 0) for v in self.vertices]


example:
from time import perf_counter t = perf_counter() Entity(model=Quad(scale=(3,1), thickness=3, segments=3, mode='line'), color = color.hsv(0,1,1,.7)) Entity(scale=(3,1), model=Quad(aspect=3), color = color.hsv(60,1,1,.3)) print('-------', (perf_counter() - t)*100) origin = Entity(model='quad', color=color.orange, scale=(.05, .05)) camera.z = -5

Circle(Mesh)

ursina/models/procedural/circle

Circle(resolution=16, radius=.5, mode='ngon', **kwargs)

.vertices = list()


example:
e = Entity(model=Circle(8, mode='line', thickness=10), color=color.hsv(60,1,1,.3)) print(e.model) origin = Entity(model='quad', color=color.orange, scale=(.05, .05)) ed = EditorCamera(rotation_speed = 200, panning_speed=200)

Plane(Mesh)

ursina/models/procedural/plane

Plane(subdivisions=(1,1), mode='triangle', **kwargs)

.vertices, self.triangles = list(), list()
.uvs = list()


example:
front = Entity(model=Plane(subdivisions=(3,6)), texture='brick', rotation_x=-90) _ed = EditorCamera() Entity(model='cube', color=color.green, scale=.05)

Grid(Mesh)

ursina/models/procedural/grid

Grid(width, height, mode='line', thickness=1, **kwargs)

.width = width
.height = height


example:
Entity(model=Grid(2, 6))

Cone(Mesh)

ursina/models/procedural/cone

Cone(resolution=4, radius=.5, height=1, add_bottom=True, mode='triangle', **kwargs)



example:
from ursina import Ursina, Entity, color, EditorCamera e = Entity(model=Cone(3), texture='brick') origin = Entity(model='quad', color=color.orange, scale=(.05, .05)) ed = EditorCamera()

Cylinder(Pipe)

ursina/models/procedural/cylinder

Cylinder(resolution=8, radius=.5, start=0, height=1, direction=(0,1,0), mode='triangle', **kwargs)



example:
Entity(model=Cylinder(6, start=-.5), color=color.hsv(60,1,1,.3)) origin = Entity(model='quad', color=color.orange, scale=(5, .05)) ed = EditorCamera(rotation_speed = 200, panning_speed=200)

Pipe(Mesh)

ursina/models/procedural/pipe

Pipe(base_shape=Quad, origin=(0,0), path=((0,0,0),(0,1,0)), thicknesses=((1,1),), color_gradient=None, look_at=True, cap_ends=True, mode='triangle', **kwargs)

.base_shape = base_shape
.origin = origin
.path = path
.thicknesses = thicknesses
.look_at = look_at
.cap_ends = cap_ends
.mode = mode
.color_gradient = color_gradient
.prev = None
.curr = None

functions:
 generate()

example:
path = [e*5 for e in Circle().vertices] path.append(path[0]) e = Entity(model=Pipe(path=path, cap_ends=False)) print(len(e.model.vertices), len(e.model.colors)) EditorCamera() origin = Entity(model='cube', color=color.magenta) origin.scale *= .25

Terrain(Mesh)

ursina/models/procedural/terrain

Terrain(heightmap='', height_values=None, gradient=None, skip=1, **kwargs)

.width = len(self.height_values)
.depth = len(self.height_values[0])
.aspect_ratio = self.width / self.depth
.gradient = gradient

functions:
 generate()

example:
'''Terrain using an RGB texture as input''' terrain_from_heightmap_texture = Entity(model=Terrain('heightmap_1', skip=8), scale=(40,5,20), texture='heightmap_1') ''' I'm just getting the height values from the previous terrain as an example, but you can provide your own. It should be a list of lists, where each value is between 0 and 255. ''' hv = terrain_from_heightmap_texture.model.height_values.tolist() terrain_from_list = Entity(model=Terrain(height_values=hv), scale=(40,5,20), texture='heightmap_1', x=40) terrain_bounds = Entity(model='wireframe_cube', origin_y=-.5, scale=(40,5,20), color=color.lime) def input(key): if key == 'space': # randomize the terrain terrain_from_list.model.height_values = [[random.uniform(0,255) for a in column] for column in terrain_from_list.model.height_values] terrain_from_list.model.generate() EditorCamera(rotation_x=90) camera.orthographic = True Sky() player = Entity(model='sphere', color=color.azure, scale=.2, origin_y=-.5) def update(): direction = Vec3(held_keys['d'] - held_keys['a'], 0, held_keys['w'] - held_keys['s']).normalized() player.position += direction * time.dt * 8 y = terraincast(player.world_position, terrain_from_list, terrain_from_list.model.height_values) if y is not None: player.y = y

input_handler

ursina/input_handler

.held_keys = defaultdict(lambda: 0)
.rebinds = dict()

functions:
 bind(original_key, alternative_key)
 unbind(key)
 rebind(to_key, from_key)
 input(key)
 get_combined_key(key)

example:
from ursina import Ursina, input_handler app = Ursina(borderless=False) input_handler.bind('z', 'w') # 'z'-key will now be registered as 'w'-key input_handler.bind('left mouse down', 'attack') # 'left mouse down'-key will now send 'attack'to input functions input_handler.bind('gamepad b', 'attack') # 'gamepad b'-key will now be registered as 'attack'-key def input(key): print('got key:', key) if key == 'attack': destroy(Entity(model='cube', color=color.blue), delay=.2)

mesh_importer

ursina/mesh_importer

.blender_scenes = dict()

functions:
 load_model(name, path=Func(getattr, application, 'asset_folder'), file_types=('.bam', '.ursinamesh', '.obj', '.glb', '.gltf', '.blend'), use_deepcopy=False, gltf_no_srgb=Func(getattr, application, 'gltf_no_srgb'))
 load_blender_scene(name, path=Func(getattr, application, 'asset_folder'), reload=False, skip_hidden=True, models_only=False, uvs=True, vertex_colors=True, normals=True, triangulate=True, decimals=4)
 get_blender(blend_file) try to get a matching blender version in case we have multiple blender version installed
 compress_models(path=None, out_path=Func(getattr, application, 'compressed_models_folder'), name='*')
 obj_to_ursinamesh(path=Func(getattr, application, 'compressed_models_folder'), out_path=Func(getattr, application, 'compressed_models_folder'), name='*', return_mesh=True, save_to_file=False, delete_obj=False)
 compress_models_fast(model_name=None, write_to_disk=False)
 ursina_mesh_to_obj(mesh, name='', out_path=Func(getattr, application, 'compressed_models_folder'), max_decimals=5, flip_faces=True)
 compress_internal()

example:
from ursina import Ursina, Entity, EditorCamera, Sky application.asset_folder = Path(r'''C:\Users\Petter\Downloads''') t = perf_counter() Entity(model='untitled') print('-------', perf_counter() - t) m = load_model('cube', use_deepcopy=True) EditorCamera() Sky(texture='sky_sunset')

texture_importer

ursina/texture_importer

.file_types = ('.tif', '.jpg', '.jpeg', '.png', '.gif')
.folders = [ folder search order
.textureless = False

functions:
 load_texture(name, path=None, use_cache=True, filtering='default')
 compress_textures(name='')

example:
Entity(model='quad', texture='white_cube')

string_utilities

ursina/string_utilities


functions:
 camel_to_snake(value)
 snake_to_camel(value)
 multireplace(string, replacements, ignore_case=False)
 printvar(var)
 print_info(str, *args)
 print_warning(str, *args)

example:
print(camel_to_snake('CamelToSnake')) print(snake_to_camel('snake_to_camel')) printvar('test')

Animation(Sprite)

ursina/prefabs/animation

Animation(name, fps=12, loop=True, autoplay=True, frame_times=None, **kwargs)

.sequence = Sequence(loop=loop, auto_destroy=False)
.frame_times = frame_times
.is_playing = False
.autoplay = autoplay

properties:
.duration# get the duration of the animation. you can't set it. to do so, change the fps instead.

functions:
 start()
 pause()
 resume()
 finish()

example:
app = Ursina() ''' Loads an image sequence as a frame animation. Consider using SpriteSheetAnimation instead if possible. So if you have some frames named image_000.png, image_001.png, image_002.png and so on, you can load it like this: Animation('image') You can also load a .gif by including the file type: Animation('image.gif') ''' a = Animation('ursina_wink') app.run()

FrameAnimation3d(Entity)

ursina/prefabs/frame_animation_3d

FrameAnimation3d(name, fps=12, loop=True, autoplay=True, frame_times=None, **kwargs)

.frames = [Entity(parent=self, model=e.stem, enabled=False, add_to_scene_entities=False) for e in model_names]
.sequence = Sequence(loop=loop, auto_destroy=False)
.autoplay = autoplay

properties:
.duration
.current_frame

functions:
 start()
 pause()
 resume()
 finish()
 on_destroy()

example:
application.asset_folder = application.asset_folder.parent.parent / 'samples' ''' Loads an obj sequence as a frame animation. So if you have some frames named run_cycle_000.obj, run_cycle_001.obj, run_cycle_002.obj and so on, you can load it like this: FrameAnimation3d('run_cycle_') ''' FrameAnimation3d('blob_animation_')

SpriteSheetAnimation(Entity)

ursina/prefabs/sprite_sheet_animation

SpriteSheetAnimation(texture, animations, tileset_size=[4,1], fps=12, model='quad', autoplay=True, **kwargs)

.animations = animations should be a dict

functions:
 play_animation(animation_name)

example:
''' Sprite sheet coordinate system: (0,3) (1,3) (2,3) (3,3) (0,2) (1,2) (2,2) (3,2) (0,1) (1,1) (2,1) (3,1) (0,0) (1,0) (2,0) (3,0) ''' from ursina import Ursina player_graphics = SpriteSheetAnimation('sprite_sheet', tileset_size=(4,4), fps=6, animations={ 'idle' : ((0,0), (0,0)), # makes an animation from (0,0) to (0,0), a single frame 'walk_up' : ((0,0), (3,0)), # makes an animation from (0,0) to (3,0), the bottom row 'walk_right' : ((0,1), (3,1)), 'walk_left' : ((0,2), (3,2)), 'walk_down' : ((0,3), (3,3)), } ) def input(key): if key == 'w': player_graphics.play_animation('walk_up') elif key == 's': player_graphics.play_animation('walk_down') elif key == 'd': player_graphics.play_animation('walk_right') elif key == 'a': player_graphics.play_animation('walk_left') Entity(model='quad', texture='sprite_sheet', x=-1)

Animator

ursina/prefabs/animator

Animator(animations=None, start_state='', pause_disabled=True)

.animations = animations dict
.pause_disabled = pause_disabled
.start_state = start_state
.state = start_state

properties:
.state


example:
anim = Animation('ursina_wink', loop=True, autoplay=False) a = Animator( animations = { 'lol' : Entity(model='cube', color=color.red), 'yo' : Entity(model='cube', color=color.green, x=1), 'help' : anim, } ) a.state = 'yo' Text('press <red>1<default>, <green>2<default> or <violet>3<default> to toggle different animator states', origin=(0,-.5), y=-.4) def input(key): if key == '1': a.state = 'lol' if key == '2': a.state = 'yo' if key == '3': a.state = 'help' print(anim.enabled)

TrailRenderer(Entity)

ursina/prefabs/trail_renderer

TrailRenderer(size=[1,.01], segments=8, min_spacing=.05, fade_speed=0, color_gradient=[color.white, color.clear], **kwargs)

.renderer = Entity( model = Pipe( base_shape = Quad(segments=0, scale=size), path=[Vec3(0,0,i) for i in range(2)], color_gradient=color_gradient, static=False, cap_ends=False, ),
.segments = segments
.update_step = .05
.min_spacing = min_spacing
.fade_speed = fade_speed
.on_enable = self.renderer.enable
.on_disable = self.renderer.disable

functions:
 update()
 on_destroy()

example:
app = Ursina(vsync=False) window.color = color.black mouse.visible = False player = Entity(z=1) player.graphics = Entity(parent=player, scale=.1, model='circle') pivot = Entity() trail_renderers = [] for i in range(1): tr = TrailRenderer(size=[1,1], segments=8, min_spacing=.05, fade_speed=0, parent=player, color_gradient=[color.magenta, color.cyan.tint(-.5), color.clear]) trail_renderers.append(tr) def update(): player.position = lerp(player.position, mouse.position*10, time.dt*4) def input(key): if key == 'escape': for e in trail_renderers: e.enabled = not e.enabled if key == 'space': destroy(pivot) EditorCamera() Entity(model=Grid(8,8), rotation_x=90, color=color.gray, y=-3, scale=8)

curve

ursina/curve


functions:
 linear(t)
 in_sine(t)
 out_sine(t)
 in_out_sine(t)
 in_quad(t)
 out_quad(t)
 in_out_quad(t)
 in_cubic(t)
 out_cubic(t)
 in_out_cubic(t)
 in_quart(t)
 out_quart(t)
 in_out_quart(t)
 in_quint(t)
 out_quint(t)
 in_out_quint(t)
 in_expo(t)
 out_expo(t)
 in_out_expo(t)
 in_circ(t)
 out_circ(t)
 in_out_circ(t)
 in_back(t, magnitude=1.70158)
 out_back(t, magnitude=1.70158)
 in_out_back(t, magnitude=1.70158)
 in_elastic(t, magnitude=.7)
 out_elastic(t, magnitude=.7)
 in_out_elastic(t, magnitude=0.65)
 out_bounce(t)
 in_bounce(t)
 in_out_bounce(t)
 {e}_boomerang(t)

example:
'''Draws a sheet with every curve and its name''' from ursina import Ursina, camera, window, curve, Entity, Mesh, Text, color camera.orthographic = True camera.fov = 16 camera.position = (9, 6) window.color = color.black i = 0 for e in dir(curve): try: item = getattr(curve, e) print(item.__name__, ':', item(.75)) curve_renderer = Entity( model=Mesh(vertices=[Vec3(i / 31, item(i / 31), 0) for i in range(32)], mode='line', thickness=2), color=color.light_gray) row = floor(i / 8) curve_renderer.x = (i % 8) * 2.5 curve_renderer.y = row * 1.75 label = Text(parent=curve_renderer, text=item.__name__, scale=8, color=color.gray, y=-.1) i += 1 except: pass c = CubicBezier(0, .5, 1, .5) print('-----------', c.calculate(.23)) window.exit_button.visible = False window.fps_counter.enabled = False ''' These are used by Entity when animating, like this: e = Entity() e.animate_y(1, curve=curve.in_expo) e2 = Entity(x=1.5) e2.animate_y(1, curve=curve.CubicBezier(0,.7,1,.3)) '''

ursinamath

ursinamath


functions:
 distance(a, b)
 distance_2d(a, b)
 distance_xz(a, b)
 lerp(a, b, t)
 inverselerp(a, b, t)
 lerp_angle(start_angle, end_angle, t)
 slerp(q1, q2, t)
 clamp(value, floor, ceiling)
 round_to_closest(value, step=0)
 rotate_around_point_2d(point, origin, deg)
 world_position_to_screen_position(point): # get screen position(ui space) get screen position(ui space) from world space.
 sum(l)
 make_gradient(index_color_dict) returns a list of 256 colors
 sample_gradient(list_of_values, t): # distribute list_of_values equally on a line and get the interpolated value at t (0-1) distribute list_of_values equally on a line and get the interpolated value at t (0-1).

example:
e1 = Entity(position = (0,0,0)) e2 = Entity(position = (0,1,1)) distance(e1, e2) distance_xz(e1, e2.position) between_color = lerp(color.lime, color.magenta, .5) print(between_color) print(lerp((0,0), (0,1), .5)) print(lerp(Vec2(0,0), Vec2(0,1), .5)) print(lerp([0,0], [0,1], .5)) print(round(Vec3(.38, .1351, 353.26), 2)) p = (1,0) print(p, 'rotated ->', rotate_around_point_2d(p, (0,0), 90))

Vec2(PandaVec2)

ursina/vec2


properties:
.x
.y
.X
.Y
.yx


example:
a = Vec2(1,1) print(a) print(round(a))

Vec3(PandaVec3)

ursina/vec3


properties:
.x
.y
.z
.xy
.yx
.xz
.yz
.X
.Y
.Z


example:
a = Vec3(1,0,0) * 2 a = Vec3(1,0,1) * Vec3(2,1,2) b = Vec3(1.252352324,0,1) b += Vec3(0,1)

Vec4(PandaVec4)

ursina/vec4



example:
a = Vec4(1,0,0,0) * 2 a = Vec4(1,0,1,1) * Vec4(2,1,2,3) b = Vec4(1.252352324,0,1,.2) b += Vec4(0,1)

CubicBezier

ursina/curve

CubicBezier(a, b, c, d)

.a = a
.b = b
.c = c
.d = d
.cx = 3.0 * a
.bx = 3.0 * (c - a) - self.cx
.ax = 1.0 - self.cx - self.bx
.cy = 3.0 * b
.by = 3.0 * (d - b) - self.cy
.ay = 1.0 - self.cy - self.by

functions:
 sample_curve_x(t)
 sample_curve_y(t)
 sample_curve_derivative_x(t)
 calculate(x, epsilon=.0001)
 solve_curve_x(t, epsilon=.0001)

example:
'''Draws a sheet with every curve and its name''' from ursina import Ursina, camera, window, curve, Entity, Mesh, Text, color camera.orthographic = True camera.fov = 16 camera.position = (9, 6) window.color = color.black i = 0 for e in dir(curve): try: item = getattr(curve, e) print(item.__name__, ':', item(.75)) curve_renderer = Entity( model=Mesh(vertices=[Vec3(i / 31, item(i / 31), 0) for i in range(32)], mode='line', thickness=2), color=color.light_gray) row = floor(i / 8) curve_renderer.x = (i % 8) * 2.5 curve_renderer.y = row * 1.75 label = Text(parent=curve_renderer, text=item.__name__, scale=8, color=color.gray, y=-.1) i += 1 except: pass c = CubicBezier(0, .5, 1, .5) print('-----------', c.calculate(.23)) window.exit_button.visible = False window.fps_counter.enabled = False ''' These are used by Entity when animating, like this: e = Entity() e.animate_y(1, curve=curve.in_expo) e2 = Entity(x=1.5) e2.animate_y(1, curve=curve.CubicBezier(0,.7,1,.3)) '''

ursinastuff

ursinastuff


functions:
 invoke(function, *args, **kwargs) reserved keywords: 'delay', 'unscaled'
 after(delay, unscaled=True)
 reset_cooldown()
 decorator(func)
 wrapper(*args, **kwargs)
 destroy(entity, delay=0)
 chunk_list(target_list, chunk_size)
 flatten_list(target_list)
 flatten_completely(container)
 enumerate_2d(array)
 size_list() eturn a list of current python objects sorted by size
 find_sequence(name, file_types, folders) find frame_0, frame_1, frame_2 and so on
 import_all_classes(path=application.asset_folder, debug=False)
 print_on_screen(text, position=(0,0), origin=(-.5,.5), scale=1, duration=1)


Sequence

ursina/sequence

Sequence(*args, **kwargs)

.args = list(args)
.t = 0
.time_step = Sequence.default_time_step
.unscaled = False
.duration = 0
.funcs = []
.started = False
.paused = False
.ignore_paused = False
.loop = False
.auto_destroy = False
.entity = None you can assign this to make the sequence pause when the entity is disabled or .ignore is True

properties:
.finished

functions:
 generate()
 append(arg)
 extend(list)
 start()
 pause()
 resume()
 finish()
 kill()
 update()

example:
from ursina import Ursina, Entity e = Entity(model='quad') s = Sequence( 1, Func(print, 'one'), Func(e.fade_out, duration=1), 1, Func(print, 'two'), Func(e.fade_in, duration=1), loop=True ) s.append( Func(print, 'appended to sequence') ) def input(key): actions = {'s' : s.start, 'f' : s.finish, 'p' : s.pause, 'r' : s.resume} if key in actions: actions[key]()

Func

ursina/sequence

Func(func, *args, **kwargs)

.func = func
.args = args
.kwargs = kwargs
.delay = 0
.finished = False


example:
from ursina import Ursina, Entity e = Entity(model='quad') s = Sequence( 1, Func(print, 'one'), Func(e.fade_out, duration=1), 1, Func(print, 'two'), Func(e.fade_in, duration=1), loop=True ) s.append( Func(print, 'appended to sequence') ) def input(key): actions = {'s' : s.start, 'f' : s.finish, 'p' : s.pause, 'r' : s.resume} if key in actions: actions[key]()

Keys(Enum)

ursina/input_handler

Keys.left_mouse_down = 'left mouse down'
Keys.left_mouse_up = 'left mouse up'
Keys.middle_mouse_down = 'middle mouse down'
Keys.middle_mouse_up = 'middle mouse up'
Keys.right_mouse_down = 'right mouse down'
Keys.right_mouse_up = 'right mouse up'
Keys.double_click = 'double click'
Keys.scroll_up = 'scroll up'
Keys.scroll_down = 'scroll down'
Keys.left_arrow = 'left arrow'
Keys.left_arrow_up = 'left arrow up'
Keys.up_arrow = 'up arrow'
Keys.up_arrow_up = 'up arrow up'
Keys.down_arrow = 'down arrow'
Keys.down_arrow_up = 'down arrow up'
Keys.right_arrow = 'right arrow'
Keys.right_arrow_up = 'right arrow up'
Keys.left_control = 'left control'
Keys.right_control = 'right control'
Keys.left_shift = 'left shift'
Keys.right_shift = 'right shift'
Keys.left_alt = 'left alt'
Keys.right_alt = 'right alt'
Keys.left_control_up = 'left control up'
Keys.right_control_up = 'right control up'
Keys.left_shift_up = 'left shift up'
Keys.right_shift_up = 'right shift up'
Keys.left_alt_up = 'left alt up'
Keys.right_alt_up = 'right alt up'
Keys.page_down = 'page down'
Keys.page_down_up = 'page down up'
Keys.page_up = 'page up'
Keys.page_up_up = 'page up up'
Keys.enter = 'enter'
Keys.backspace = 'backspace'
Keys.escape = 'escape'
Keys.tab = 'tab'
Keys.gamepad_left_stick_x = 'gamepad left stick x' # held_keys only
Keys.gamepad_left_stick_y = 'gamepad left stick y' # held_keys only
Keys.gamepad_right_stick_x = 'gamepad right stick x' # held_keys only
Keys.gamepad_right_stick_y = 'gamepad right stick y' # held_keys only
Keys.gamepad_left_trigger = 'gamepad left trigger' # held_keys only
Keys.gamepad_right_trigger = 'gamepad right trigger' # held_keys only
Keys.gamepad_a = 'gamepad a'
Keys.gamepad_a_up = 'gamepad a up'
Keys.gamepad_b = 'gamepad b'
Keys.gamepad_b_up = 'gamepad b up'
Keys.gamepad_x = 'gamepad x'
Keys.gamepad_x_up = 'gamepad x up'
Keys.gamepad_y = 'gamepad y'
Keys.gamepad_y_up = 'gamepad y up'
Keys.gamepad_left_stick = 'gamepad left stick'
Keys.gamepad_left_stick_up = 'gamepad left stick up'
Keys.gamepad_right_stick = 'gamepad right stick'
Keys.gamepad_right_stick_up = 'gamepad right stick up'
Keys.gamepad_back = 'gamepad back'
Keys.gamepad_back_up = 'gamepad back up'
Keys.gamepad_start = 'gamepad start'
Keys.gamepad_dpad_down = 'gamepad dpad down'
Keys.gamepad_dpad_down_up = 'gamepad dpad down up'
Keys.gamepad_dpad_up = 'gamepad dpad up'
Keys.gamepad_dpad_up_up = 'gamepad dpad up up'
Keys.gamepad_dpad_left = 'gamepad dpad left'
Keys.gamepad_dpad_left_up = 'gamepad dpad left up'
Keys.gamepad_dpad_right = 'gamepad dpad right'
Keys.gamepad_dpad_right_up = 'gamepad dpad right up'
Keys.gamepad_left_shoulder = 'gamepad left shoulder'
Keys.gamepad_left_shoulder_up = 'gamepad left shoulder up'
Keys.gamepad_right_shoulder = 'gamepad right shoulder'
Keys.gamepad_right_shoulder_up = 'gamepad right shoulder up'

functions:
 bind(original_key, alternative_key)
 unbind(key)
 rebind(to_key, from_key)
 input(key)
 get_combined_key(key)

example:
from ursina import Ursina, input_handler app = Ursina(borderless=False) input_handler.bind('z', 'w') # 'z'-key will now be registered as 'w'-key input_handler.bind('left mouse down', 'attack') # 'left mouse down'-key will now send 'attack'to input functions input_handler.bind('gamepad b', 'attack') # 'gamepad b'-key will now be registered as 'attack'-key def input(key): print('got key:', key) if key == 'attack': destroy(Entity(model='cube', color=color.blue), delay=.2)

raycast

ursina/raycast


functions:
 raycast(origin, direction:Vec3=(0,0,1), distance=9999, traverse_target:Entity=scene, ignore:list=None, debug=False, color=color.white)

example:
from ursina import Ursina, Entity, held_keys, time, duplicate, camera, EditorCamera ''' Casts a ray from *origin*, in *direction*, with length *distance* and returns a HitInfo containing information about what it hit. This ray will only hit entities with a collider. Use optional *traverse_target* to only be able to hit a specific entity and its children/descendants. Use optional *ignore* list to ignore certain entities. Setting debug to True will draw the line on screen. Example where we only move if a wall is not hit: ''' class Player(Entity): def update(self): self.direction = Vec3( self.forward * (held_keys['w'] - held_keys['s']) + self.right * (held_keys['d'] - held_keys['a']) ).normalized() # get the direction we're trying to walk in. origin = self.world_position + (self.up*.5) # the ray should start slightly up from the ground so we can walk up slopes or walk over small objects. hit_info = raycast(origin , self.direction, ignore=(self,), distance=.5, debug=False) if not hit_info.hit: self.position += self.direction * 5 * time.dt else: print(hit_info.entity) Player(model='cube', origin_y=-.5, color=color.orange) wall_left = Entity(model='cube', collider='box', scale_y=3, origin_y=-.5, color=color.azure, x=-4) wall_right = duplicate(wall_left, x=4) camera.y = 2

terraincast

ursina/terraincast


functions:
 terraincast(world_position, terrain_entity, height_values=None, return_normals=False) uses x and z to return y on terrain.

example:
terrain_entity = Entity(model=Terrain('heightmap_1', skip=8), scale=(40, 5, 20), texture='heightmap_1') player = Entity(model='sphere', color=color.azure, scale=.2, origin_y=-.5) hv = terrain_entity.model.height_values def update(): direction = Vec3(held_keys['d'] - held_keys['a'], 0, held_keys['w'] - held_keys['s']).normalized() player.position += direction * time.dt * 4 y = terraincast(player.world_position, terrain_entity, hv) if y is not None: player.y = y EditorCamera() from ursina.shaders import ssao_shader camera.shader = ssao_shader Sky()

boxcast

ursina/boxcast


functions:
 boxcast(origin, direction=(0,0,1), distance=9999, thickness=(1,1), traverse_target=scene, ignore:list=None, debug=False) similar to raycast, but with width and height

example:
from ursina import Ursina, held_keys, camera, duplicate, raycast, time, EditorCamera ''' Casts a ray from *origin*, in *direction*, with length *distance* and returns a HitInfo containing information about what it hit. This ray will only hit entities with a collider. Use optional *traverse_target* to only be able to hit a specific entity and its children/descendants. Use optional *ignore* list to ignore certain entities. Setting debug to True will draw the line on screen. Example where we only move if a wall is not hit: ''' class Player(Entity): def update(self): self.direction = Vec3( self.forward * (held_keys['w'] - held_keys['s']) + self.right * (held_keys['d'] - held_keys['a']) ).normalized() # get the direction we're trying to walk in. origin = self.world_position + (self.up*.5) # the ray should start slightly up from the ground so we can walk up slopes or walk over small objects. hit_info = raycast(origin , self.direction, ignore=(self,), distance=.5, debug=False) if not hit_info.hit: self.position += self.direction * 5 * time.dt Player(model='cube', origin_y=-.5, color=color.orange) wall_left = Entity(model='cube', collider='box', scale_y=3, origin_y=-.5, color=color.azure, x=-4) wall_right = duplicate(wall_left, x=4) camera.y = 2

Collider

ursina/collider

Collider(entity, shape)

.collision_node = CollisionNode('CollisionNode')
.shape = shape
.node_path = entity.attachNewNode(self.collision_node)

properties:
.visible

functions:
 remove()

example:
from ursina import Ursina, Entity, Pipe, Circle, Button, scene, EditorCamera, color e = Button(parent=scene, model='sphere', x=2) e.collider = 'box' # add BoxCollider based on entity's bounds. e.collider = 'sphere' # add SphereCollider based on entity's bounds. e.collider = 'capsule' # add CapsuleCollider based on entity's bounds. e.collider = 'mesh' # add MeshCollider matching the entity's model. e.collider = 'file_name' # load a model and us it as MeshCollider. e.collider = e.model # copy target model/Mesh and use it as MeshCollider. e.collider = BoxCollider(e, center=Vec3(0,0,0), size=Vec3(1,1,1)) # add BoxCollider at custom positions and size. e.collider = SphereCollider(e, center=Vec3(0,0,0), radius=.75) # add SphereCollider at custom positions and size. e.collider = CapsuleCollider(e, center=Vec3(0,0,0), height=3, radius=.75) # add CapsuleCollider at custom positions and size. e.collider = MeshCollider(e, mesh=e.model, center=Vec3(0,0,0)) # add MeshCollider with custom shape and center. m = Pipe(base_shape=Circle(6), thicknesses=(1, .5)) e = Button(parent=scene, model='cube', collider='mesh', color=color.red, highlight_color=color.yellow) sphere = Button(parent=scene, model='icosphere', collider='mesh', color=color.red, highlight_color=color.yellow, x=4) EditorCamera() def input(key): if key == 'c': e.collider = None

BoxCollider(Collider)

ursina/collider

BoxCollider(entity, center=(0,0,0), size=(1,1,1))

.center = center
.size = size


example:
from ursina import Ursina, Entity, Pipe, Circle, Button, scene, EditorCamera, color e = Button(parent=scene, model='sphere', x=2) e.collider = 'box' # add BoxCollider based on entity's bounds. e.collider = 'sphere' # add SphereCollider based on entity's bounds. e.collider = 'capsule' # add CapsuleCollider based on entity's bounds. e.collider = 'mesh' # add MeshCollider matching the entity's model. e.collider = 'file_name' # load a model and us it as MeshCollider. e.collider = e.model # copy target model/Mesh and use it as MeshCollider. e.collider = BoxCollider(e, center=Vec3(0,0,0), size=Vec3(1,1,1)) # add BoxCollider at custom positions and size. e.collider = SphereCollider(e, center=Vec3(0,0,0), radius=.75) # add SphereCollider at custom positions and size. e.collider = CapsuleCollider(e, center=Vec3(0,0,0), height=3, radius=.75) # add CapsuleCollider at custom positions and size. e.collider = MeshCollider(e, mesh=e.model, center=Vec3(0,0,0)) # add MeshCollider with custom shape and center. m = Pipe(base_shape=Circle(6), thicknesses=(1, .5)) e = Button(parent=scene, model='cube', collider='mesh', color=color.red, highlight_color=color.yellow) sphere = Button(parent=scene, model='icosphere', collider='mesh', color=color.red, highlight_color=color.yellow, x=4) EditorCamera() def input(key): if key == 'c': e.collider = None

SphereCollider(Collider)

ursina/collider

SphereCollider(entity, center=(0,0,0), radius=.5)

.center = center
.radius = radius


example:
from ursina import Ursina, Entity, Pipe, Circle, Button, scene, EditorCamera, color e = Button(parent=scene, model='sphere', x=2) e.collider = 'box' # add BoxCollider based on entity's bounds. e.collider = 'sphere' # add SphereCollider based on entity's bounds. e.collider = 'capsule' # add CapsuleCollider based on entity's bounds. e.collider = 'mesh' # add MeshCollider matching the entity's model. e.collider = 'file_name' # load a model and us it as MeshCollider. e.collider = e.model # copy target model/Mesh and use it as MeshCollider. e.collider = BoxCollider(e, center=Vec3(0,0,0), size=Vec3(1,1,1)) # add BoxCollider at custom positions and size. e.collider = SphereCollider(e, center=Vec3(0,0,0), radius=.75) # add SphereCollider at custom positions and size. e.collider = CapsuleCollider(e, center=Vec3(0,0,0), height=3, radius=.75) # add CapsuleCollider at custom positions and size. e.collider = MeshCollider(e, mesh=e.model, center=Vec3(0,0,0)) # add MeshCollider with custom shape and center. m = Pipe(base_shape=Circle(6), thicknesses=(1, .5)) e = Button(parent=scene, model='cube', collider='mesh', color=color.red, highlight_color=color.yellow) sphere = Button(parent=scene, model='icosphere', collider='mesh', color=color.red, highlight_color=color.yellow, x=4) EditorCamera() def input(key): if key == 'c': e.collider = None

MeshCollider(Collider)

ursina/collider

MeshCollider(entity, mesh=None, center=(0,0,0))

.center = center
.collision_polygons = []

functions:
 remove()

example:
from ursina import Ursina, Entity, Pipe, Circle, Button, scene, EditorCamera, color e = Button(parent=scene, model='sphere', x=2) e.collider = 'box' # add BoxCollider based on entity's bounds. e.collider = 'sphere' # add SphereCollider based on entity's bounds. e.collider = 'capsule' # add CapsuleCollider based on entity's bounds. e.collider = 'mesh' # add MeshCollider matching the entity's model. e.collider = 'file_name' # load a model and us it as MeshCollider. e.collider = e.model # copy target model/Mesh and use it as MeshCollider. e.collider = BoxCollider(e, center=Vec3(0,0,0), size=Vec3(1,1,1)) # add BoxCollider at custom positions and size. e.collider = SphereCollider(e, center=Vec3(0,0,0), radius=.75) # add SphereCollider at custom positions and size. e.collider = CapsuleCollider(e, center=Vec3(0,0,0), height=3, radius=.75) # add CapsuleCollider at custom positions and size. e.collider = MeshCollider(e, mesh=e.model, center=Vec3(0,0,0)) # add MeshCollider with custom shape and center. m = Pipe(base_shape=Circle(6), thicknesses=(1, .5)) e = Button(parent=scene, model='cube', collider='mesh', color=color.red, highlight_color=color.yellow) sphere = Button(parent=scene, model='icosphere', collider='mesh', color=color.red, highlight_color=color.yellow, x=4) EditorCamera() def input(key): if key == 'c': e.collider = None

Sky(Entity)

ursina/prefabs/sky

Sky(**kwargs)

Sky.instances = []

functions:
 update()
 input(key)


EditorCamera(Entity)

ursina/prefabs/editor_camera

EditorCamera(**kwargs)

.rotation_speed = 200
.pan_speed = Vec2(5, 5)
.move_speed = 10
.target_fov = camera.fov
.zoom_speed = 1.25
.zoom_smoothing = 8
.rotate_around_mouse_hit = False
.ignore_scroll_on_ui = True
.smoothing_helper = Entity(add_to_scene_entities=False)
.rotation_smoothing = 0
.look_at = self.smoothing_helper.look_at
.look_at_2d = self.smoothing_helper.look_at_2d
.rotate_key = 'right mouse'
.start_position = self.position
.perspective_fov = camera.fov
.orthographic_fov = camera.fov
.on_destroy = self.on_disable
.shortcuts = {'toggle_orthographic':'shift+p', 'focus':'shift+f', 'reset_center':'alt+f'}

functions:
 on_enable()
 on_disable()
 on_destroy()
 input(key)
 update()

example:
from ursina import Ursina, Sky, load_model, color, Text, window, Button app = Ursina(vsync=False, use_ingame_console=True) ''' Simple camera for debugging. Hold right click and move the mouse to rotate around point. ''' sky = Sky() e = Entity(model=load_model('cube', use_deepcopy=True), color=color.white, collider='box') e.model.colorize() ground = Entity(model='plane', scale=32, texture='white_cube', texture_scale=(32,32), collider='box') box = Entity(model='cube', collider='box', texture='white_cube', scale=(10,2,2), position=(2,1,5), color=color.light_gray) b = Button(position=window.top_left, scale=.05) ec = EditorCamera(ignore_scroll_on_ui=True) rotation_info = Text(position=window.top_left) def update(): rotation_info.text = str(int(ec.rotation_y)) + '\n' + str(int(ec.rotation_x))

Tilemap(GridEditor)

ursina/prefabs/tilemap

Tilemap(tilemap='', tileset='', tileset_size=(8,8), **kwargs)

.grid = [[self.tilemap.get_pixel(x,y) for y in range(self.tilemap.height)] for x in range(self.tilemap.width)]
.tileset = tileset
.tileset_size = tileset_size
.model = Mesh()
.texture = tileset
.colliders = list()
.auto_render = False
.outline = Entity(parent=self, model=Quad(segments=0, mode='line', thickness=1), color=color.cyan, z=.01, origin=(-.5,-.5), enabled=self.edit_mode)
.uv_dict = { '11111111' : [(4,1), (5,1), (6,1), (7,1)], fill
.single_block_coordinates = [(4,0), (5,0), (6,0), (7,0)]
.variation_chance = [0,0,0,0,1,1,1,2,2,3]
.uv_margin = .002

functions:
 update()
 draw_temp(position)
 input(key)
 render()
 save()

example:
EditorCamera() tilemap = Tilemap('tilemap_test_level', tileset='test_tileset', tileset_size=(8,4), parent=scene) tilemap.canvas.texture = 'tilemap_test_level' camera.orthographic = True camera.position = tilemap.tilemap.size / 2 camera.fov = tilemap.tilemap.height Text('press tab to toggle edit mode', origin=(.5,0), position=(-.55,.4))

FirstPersonController(Entity)

ursina/prefabs/first_person_controller

FirstPersonController(**kwargs)

.cursor = Entity(parent=camera.ui, model='quad', color=color.pink, scale=.008, rotation_z=45)
.speed = 5
.height = 2
.camera_pivot = Entity(parent=self, y=self.height)
.mouse_sensitivity = Vec2(40, 40)
.gravity = 1
.grounded = False
.jump_height = 2
.jump_up_duration = .5
.fall_after = .35 will interrupt jump up
.jumping = False
.air_time = 0
.traverse_target = scene by default, it will collide with everything. change this to change the raycasts' traverse targets.
.ignore_list = [self, ]
.on_destroy = self.on_disable

functions:
 update()
 input(key)
 jump()
 start_fall()
 land()
 on_enable()
 on_disable()

example:
from ursina.prefabs.first_person_controller import FirstPersonController window.vsync = False ground = Entity(model='plane', scale=(100,1,100), color=color.yellow.tint(-.2), texture='white_cube', texture_scale=(100,100), collider='box') e = Entity(model='cube', scale=(1,5,10), x=2, y=.01, rotation_y=45, collider='box', texture='white_cube') e.texture_scale = (e.scale_z, e.scale_y) e = Entity(model='cube', scale=(1,5,10), x=-2, y=.01, collider='box', texture='white_cube') e.texture_scale = (e.scale_z, e.scale_y) player = FirstPersonController(y=2, origin_y=-.5) player.gun = None gun = Button(parent=scene, model='cube', color=color.blue, origin_y=-.5, position=(3,0,3), collider='box', scale=(.2,.2,1)) def get_gun(): gun.parent = camera gun.position = Vec3(.5,0,.5) player.gun = gun gun.on_click = get_gun gun_2 = duplicate(gun, z=7, x=8) slope = Entity(model='cube', collider='box', position=(0,0,8), scale=6, rotation=(45,0,0), texture='brick', texture_scale=(8,8)) slope = Entity(model='cube', collider='box', position=(5,0,10), scale=6, rotation=(80,0,0), texture='brick', texture_scale=(8,8)) hookshot_target = Button(parent=scene, model='cube', color=color.brown, position=(4,5,5)) hookshot_target.on_click = Func(player.animate_position, hookshot_target.position, duration=.5, curve=curve.linear) def input(key): if key == 'left mouse down' and player.gun: gun.blink(color.orange) bullet = Entity(parent=gun, model='cube', scale=.1, color=color.black) bullet.world_parent = scene bullet.animate_position(bullet.position+(bullet.forward*50), curve=curve.linear, duration=1) destroy(bullet, delay=1)

PlatformerController2d(Entity)

ursina/prefabs/platformer_controller_2d

PlatformerController2d(**kwargs)

.model = 'cube'
.origin_y = -.5
.scale_y = 2
.color = color.orange
.collider = 'box'
.animator = Animator({'idle' : None, 'walk' : None, 'jump' : None})
.walk_speed = 8
.walking = False
.velocity = 0 the walk direction is stored here. -1 for left and 1 for right.
.jump_height = 4
.jump_duration = .5
.jumping = False
.max_jumps = 1
.jumps_left = self.max_jumps
.gravity = 1
.grounded = True
.air_time = 0 this increase while we're falling and used when calculating the distance we fall so we fall faster and faster instead of linearly.
.traverse_target = scene by default, it will collide with everything except itself. you can change this to change the boxcast traverse target.
.ignore_list = [self, ]
.gravity = 0
.min_x = -99999
.max_x = 99999

functions:
 update()
 input(key)
 jump()
 start_fall()
 land()

example:
camera.orthographic = True camera.fov = 10 ground = Entity(model='cube', color=color.white33, origin_y=.5, scale=(20, 1, 1), collider='box', y=-1) wall = Entity(model='cube', color=color.azure, origin=(-.5,.5), scale=(5,10), x=10, y=.5, collider='box') wall_2 = Entity(model='cube', color=color.white33, origin=(-.5,.5), scale=(5,10), x=10, y=0, collider='box') ceiling = Entity(model='cube', color=color.white33, origin_y=-.5, scale=(1, 1, 1), y=1, collider='box') ceiling = Entity(model='cube', color=color.white33, origin_y=-.5, scale=(5, 5, 1), y=2, collider='box') ground = Entity(model='cube', color=color.white33, origin_y=.5, scale=(20, 3, 1), collider='box', y=-1, rotation_z=45, x=-5) def input(key): if key == 'c': wall.collision = not wall.collision print(wall.collision) player_controller = PlatformerController2d(scale_y=2, jump_height=4, x=3, y=20, max_jumps=2) ec = EditorCamera() ec.add_script(SmoothFollow(target=player_controller, offset=[0,1,0], speed=4))

Conversation(Entity)

ursina/prefabs/conversation

Conversation(variables_object=None, **kwargs)

.question = Button(parent=self, text_origin=(-.5,0), scale=(1,.1), model=Quad(radius=.5,aspect=1/.1), text='Question')
.more_indicator = Entity(parent=self.question, model=Circle(3), position=(.45,-.4,-1), rotation_z=180, color=color.azure, world_scale=.5, z=-1, enabled=False)
.spacing = 4 * .02
.wordwrap = 65
.button_model = Quad(radius=.5, aspect=1/.075)
.variables_object = variables_object
.answer_0 = Button(parent=self, text='answer_0', y=self.question.y-self.spacing-.025, scale=(1,.075), text_origin=(-.5,0), model=copy(self.button_model))
.answer_1 = Button(parent=self, text='answer_1', y=self.answer_0.y-self.spacing, scale=(1,.075), text_origin=(-.5,0), model=copy(self.button_model))
.answer_2 = Button(parent=self, text='answer_2', y=self.answer_1.y-self.spacing, scale=(1,.075), text_origin=(-.5,0), model=copy(self.button_model))
.buttons = (self.answer_0, self.answer_1, self.answer_2)
.question_appear_sequence = None
.button_appear_sequence = None
.started = False

functions:
 ask(node, question_part=0)
 on_click(node=child)
 input(key)
 next()
 start_conversation(conversation)
 parse_conversation(convo)

example:
variables = Empty( evil=0, chaos=0, bar_mission_solved=False, ) conversation = Conversation(variables_object=variables) convo = dedent(''' I'm looking for my sister. Can you help me find her, please? I haven't seen her in days! Who know what could've happened!? I'm worried. Will you help me? * Yes, of course. This can be a dangerous city. Oh no! Do you think something happened to her? What should I do?! * She's probably fine. She can handle herself. You're right. I'm still worried though. * Don't worry, I'll look for her. * Maybe. (stats.chaos += 1) Help me look for her, please! *runs off* * I'm sorry, but I don't have time right now. (evil += 1) A true friend wouldn't say that. * I know where she is! (if bar_mission_solved) Really? Where? * I saw her on a ship by the docks, it looked like they were ready to set off. Thank you! *runs off* ''') conversation.start_conversation(convo) def input(key): if key == 'space': print(variables.evil) Sprite('shore', z=1)

Node

ursina/prefabs/conversation



example:
variables = Empty( evil=0, chaos=0, bar_mission_solved=False, ) conversation = Conversation(variables_object=variables) convo = dedent(''' I'm looking for my sister. Can you help me find her, please? I haven't seen her in days! Who know what could've happened!? I'm worried. Will you help me? * Yes, of course. This can be a dangerous city. Oh no! Do you think something happened to her? What should I do?! * She's probably fine. She can handle herself. You're right. I'm still worried though. * Don't worry, I'll look for her. * Maybe. (stats.chaos += 1) Help me look for her, please! *runs off* * I'm sorry, but I don't have time right now. (evil += 1) A true friend wouldn't say that. * I know where she is! (if bar_mission_solved) Really? Where? * I saw her on a ship by the docks, it looked like they were ready to set off. Thank you! *runs off* ''') conversation.start_conversation(convo) def input(key): if key == 'space': print(variables.evil) Sprite('shore', z=1)

Button(Entity)

ursina/prefabs/button

Button(text='', parent=camera.ui, model=Default, radius=.1, origin=(0,0), text_origin=(0,0), text_size=1, color=Default, collider='box', highlight_scale=1, pressed_scale=1, disabled=False, **kwargs)

.origin = origin
.color = color
.highlight_color = self.color.tint(.2)
.pressed_color = self.color.tint(-.2)
.highlight_scale = highlight_scale multiplier
.pressed_scale = pressed_scale multiplier
.highlight_sound = None
.pressed_sound = None
.collider = collider
.disabled = disabled
.text_entity = None
.text_origin = text_origin

properties:
.text
.text_origin
.text_color
.icon
.icon_world_scale
.text_size
.origin

functions:
 input(key)
 on_mouse_enter()
 on_mouse_exit()
 fit_to_text(radius=.1, padding=Vec2(Text.size*1.5, Text.size))

example:
Button.default_color = color.red b = Button(model='quad', scale=.05, x=-.5, color=color.lime, text='text scale\ntest', text_size=.5, text_color=color.black) b.text_size = .5 b.on_click = Sequence(Wait(.5), Func(print, 'aaaaaa'), ) b = Button(parent=camera.ui, text='hello world!', scale=.25) Button.default_color = color.blue b = Button(text='hello world!', icon='sword', scale=.25, text_origin=(-.5,0), x=.5) b.on_click = application.quit # assign a function to the button. b.tooltip = Tooltip('exit') par = Entity(parent=camera.ui, scale=.2, y=-.2) b = Button(parent=par, text='test', scale_x=1, origin=(-.5,.5)) b.text ='new text' print(b.text_entity) Button(text='sound', scale=.2, position=(-.25,-.2), color=color.pink, highlight_sound='blip_1', pressed_sound=Audio('coin_1', autoplay=False)) Text('Text size\nreference', x=.15) def input(key): if key == 'd': scene.clear() if key == 'space': b.text = 'updated text'

Draggable(Button)

ursina/prefabs/draggable

Draggable(**kwargs)

.require_key = None
.dragging = False
.delta_drag = 0
.start_pos = self.world_position
.start_offset = (0,0,0)
.step = (0,0,0)
.plane_direction = (0,0,1)
.lock = Vec3(0,0,0) set to 1 to lock movement on any of x, y and z axes
.min_x, self.min_y, self.min_z = -inf, -inf, -inf
.max_x, self.max_y, self.max_z = inf, inf, inf

properties:
.step

functions:
 input(key)
 start_dragging()
 stop_dragging()
 update()

example:
Entity(model='plane', scale=8, texture='white_cube', texture_scale=(8,8)) draggable_button = Draggable(scale=.1, text='drag me', position=(-.5, 0)) world_space_draggable = Draggable(parent=scene, model='cube', color=color.azure, plane_direction=(0,1,0), lock=(1,0,0)) EditorCamera(rotation=(30,10,0)) world_space_draggable.drop = Func(print, 'dropped cube')

Tooltip(Text)

ursina/prefabs/tooltip

Tooltip(text='', wordwrap=40, background_color=color.black66, **kwargs)


functions:
 update()

example:
app = Ursina() tooltip_test = Tooltip( '<scale:1.5><pink>' + 'Rainstorm' + '<scale:1> \n \n' + '''Summon a <blue>rain storm <default>to deal 5 <blue>water damage <default>to <red>everyone, <default>including <orange>yourself. <default> Lasts for 4 rounds.'''.replace('\n', ' '), background_color=color.violet, font='VeraMono.ttf', wordwrap=50, ) tooltip_test.enabled = True app.run()

Slider(Entity)

ursina/prefabs/slider

Slider(min=0, max=1, default=None, height=Text.size, text='', dynamic=False, radius=Text.size/2, bar_color=color.black66, **kwargs)

.parent = camera.ui
.vertical = False
.min = min
.max = max
.default = default
.step = 0
.height = height
.on_value_changed = None set this to a function you want to be called when the slider changes
.setattr = None set this to (object, 'attrname') to set that value when the slider changes
.label = Text(parent=self, origin=(0.5, 0), x=-0.025, text=text)
.bg = Entity(parent=self, model=Quad(scale=(.525, height), radius=radius, segments=3), origin_x=-0.25, collider='box', color=bar_color)
.knob = Draggable(parent=self, min_x=0, max_x=.5, min_y=0, max_y=.5, step=self.step, model=Quad(radius=Text.size/2, scale=(Text.size, height)), collider='box', color=color.light_gray, text='0', text_origin=(0, -.55), z=-.1)
.value = self.default
.dynamic = dynamic if set to True, will call on_value_changed() while dragging. if set to False, will only call on_value_changed() after dragging.

properties:
.value
.step

functions:
 bg_click()
 drop()
 update()
 slide()

example:
box = Entity(model='cube', origin_y=-.5, scale=1, color=color.orange) def scale_box(): box.scale_y = slider.value print(thin_slider.value) slider = Slider(0, 20, default=10, height=Text.size*3, y=-.4, step=1, on_value_changed=scale_box, vertical=True) thin_slider = ThinSlider(text='height', dynamic=True, on_value_changed=scale_box) thin_slider.label.origin = (0,0) thin_slider.label.position = (.25, -.1)

ThinSlider(Slider)

ursina/prefabs/slider

ThinSlider(*args, **kwargs)



example:
box = Entity(model='cube', origin_y=-.5, scale=1, color=color.orange) def scale_box(): box.scale_y = slider.value print(thin_slider.value) slider = Slider(0, 20, default=10, height=Text.size*3, y=-.4, step=1, on_value_changed=scale_box, vertical=True) thin_slider = ThinSlider(text='height', dynamic=True, on_value_changed=scale_box) thin_slider.label.origin = (0,0) thin_slider.label.position = (.25, -.1)

TextField(Entity)

ursina/prefabs/text_field

TextField(max_lines=64, line_height=1.1, character_limit=None, **kwargs)

.font = 'VeraMono.ttf'
.line_height = line_height
.max_lines = max_lines
.character_limit = character_limit
.scroll_parent = Entity(parent=self)
.text_entity = Text(parent=self.scroll_parent, start_tag='☾', end_tag='☽', font=self.font, text='', line_height=self.line_height, origin=(-.5, .5))
.line_numbers = Text(parent=self.scroll_parent, font=self.font, line_height=line_height, text='0', origin=(.5,.5), x=-.04, color=color.gray, enabled=False)
.character_width = Text.get_width('a', font=self.font)
.cursor_parent = Entity(parent=self.scroll_parent, scale=(self.character_width, -1*Text.size*self.line_height))
.cursor = Entity(name='text_field_cursor', parent=self.cursor_parent, model='cube', color=color.cyan, origin=(-.5, -.5), scale=(.1, 1, 0), enabled=False)
.bg = Entity(name='text_field_bg', parent=self, model='quad', double_sided=True, color=color.dark_gray, origin=(-.5,.5), z=0.005, scale=(120, Text.size*self.max_lines*self.line_height), collider='box', visible=True)
.selection = [Vec2(0,0), Vec2(0,0)]
.selection_parent = Entity(name='text_field_selection_parent', parent=self.cursor_parent, scale=(1,1,0))
.register_mouse_input = False
.world_space_mouse = False
.triple_click_delay = 0.3
.scroll = 0
.scroll_amount = 2
.active = True
.highlight_color = color.hsv(120,1,1,.1)
.text = ''
.delimiters = ' .,!?;:(){}[]<>\'\"@#$%^&*+=-\\|/`~'
.replacements = dict()
.on_undo = []
.on_redo = []
.on_value_changed = None
.shortcuts = { 'newline': ('enter', 'enter hold'), 'erase': ('backspace', 'backspace hold'), 'erase_word': ('ctrl+backspace', 'ctrl+backspace hold'), 'delete_line': ('ctrl+shift+k',), 'duplicate_line': ('ctrl+shift+d',), 'undo': ('ctrl+z', 'ctrl+z hold'), 'redo': ('ctrl+y', 'ctrl+y hold', 'ctrl+shift+z', 'ctrl+shift+z hold'), 'save': ('ctrl+s',), # 'save_as': ('ctrl+shift+s',), 'indent': ('tab',), 'dedent': ('shift+tab',), 'move_line_down': ('ctrl+down arrow', 'ctrl+down arrow hold'), 'move_line_up': ('ctrl+up arrow', 'ctrl+up arrow hold'), 'scroll_up': ('scroll up',), 'scroll_down': ('scroll down',), 'cut': ('ctrl+x',), 'copy': ('ctrl+c',), 'paste': ('ctrl+v',), 'select_all': ('ctrl+a',), 'select_word': ('double click',), 'select_line': ('triple click',), 'scroll_to_bottom': ('shift+alt+e',), # 'toggle_comment': ('ctrl+alt+c',), # 'find': ('ctrl+f',), 'move_operations' : { 'move_left': ('left arrow', 'left arrow hold', 'shift+left arrow', 'shift+left arrow hold'), 'move_right': ('right arrow', 'right arrow hold', 'shift+right arrow', 'shift+right arrow hold'), 'move_up': ('up arrow', 'up arrow hold', 'shift+up arrow', 'shift+up arrow hold'), 'move_down': ('down arrow', 'down arrow hold', 'shift+down arrow', 'shift+down arrow hold'), 'move_to_end_of_word' : ('ctrl+right arrow', 'ctrl+right arrow hold', 'ctrl+shift+right arrow', 'ctrl+shift+right arrow hold'), 'move_to_start_of_word' : ('ctrl+left arrow', 'ctrl+left arrow hold', 'ctrl+shift+left arrow', 'ctrl+shift+left arrow hold'), },
.middle_click_scroller = Entity(parent=self, start_y=None, input=middle_click_input, update=middle_click_update, t=0, update_rate=.05)

properties:
.active

functions:
 middle_click_input(key)
 middle_click_update()
 add_text(s, move_cursor=True, rerender=True)
 move_line(line_index, delta, move_cursor=True)
 erase(rerender=True)
 delete_selected()
 get_selected()
 get_mouse_position_unclamped()
 get_mouse_position()
 set_scroll(value, render=True)
 input(key)
 move_to_start_of_word()
 move_to_end_of_word()
 scroll_to_bottom(blank_lines_at_bottom=0)
 text_input(key)
 render()
 update()
 select_all()
 draw_selection()

example:
from ursina import Ursina, window, Button app = Ursina(vsync=60) window.color = color.hsv(0, 0, .1) Button.default_color = color._20 window.color = color._25 te = TextField(max_lines=30, scale=1, register_mouse_input = True, text='1234') from textwrap import dedent te.text = dedent(''' Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam sapien tellus, venenatis sit amet ante et, malesuada porta risus. Etiam et mi luctus, viverra urna at, maximus eros. Sed dictum faucibus purus, nec rutrum ipsum condimentum in. Mauris iaculis arcu nec justo rutrum euismod. Suspendisse dolor tortor, congue id erat sit amet, sollicitudin facilisis velit. Aliquam sapien tellus, venenatis sit amet ante et, malesuada porta risus. Etiam et mi luctus, viverra urna at, maximus eros. Sed dictum faucibus purus, nec rutrum ipsum condimentum in. Mauris iaculis arcu nec justo rutrum euismod. Suspendisse dolor tortor, congue id erat sit amet, sollicitudin facilisis velit. '''*30 )[1:] te.render() def input(key): if key == '3': te.input('scroll down')

Cursor(Entity)

ursina/prefabs/cursor

Cursor(**kwargs)

.parent = camera.ui
.texture = 'cursor'
.model = 'quad'
.color = color.light_gray
.render_queue = 1

functions:
 update()

example:
from ursina import Ursina, Button, scene, Panel, Mesh Button('button').fit_to_text() camera.orthographic = True camera.fov = 100 Cursor() mouse.visible = False

InputField(Button)

ursina/prefabs/input_field

InputField(default_value='', label='', max_lines=1, character_limit=24, text='', active=False, **kwargs)

.default_value = default_value
.limit_content_to = None
.hide_content = False if set to True, will display content as '*'. can also be set to character instead of True.
.next_field = None
.submit_on = [] for example: self.submit_on
.on_submit = None function to be called when you press self.submit_on.
.on_value_changed = None
.text_field = TextField(world_parent=self, x=-.45, y=.25, z=-.1, max_lines=max_lines, character_limit=character_limit, text=text, register_mouse_input=True)
.active = active

properties:
.text
.text_color
.active

functions:
 render()
 input(key)

example:
gradient = Entity(model='quad', texture='vertical_gradient', parent=camera.ui, scale=(camera.aspect_ratio,1), color=color.hsv(240,.6,.1,.75)) username_field = InputField(y=-.12, limit_content_to='0123456789', default_value='11', active=True) username_field.text = '0929468098' password_field = InputField(y=-.18, hide_content=True) username_field.next_field = password_field def submit(): print('ursername:', username_field.text) print('password:', password_field.text) Button(text='Login', scale=.1, color=color.cyan.tint(-.4), y=-.26, on_click=submit).fit_to_text() username_field.on_value_changed = submit

ContentTypes

ursina/prefabs/input_field

ContentTypes.int = '0123456789'
ContentTypes.float = int + '.,'
ContentTypes.int_math = int + '+-*/'
ContentTypes.math = float + '+-*/'


example:
gradient = Entity(model='quad', texture='vertical_gradient', parent=camera.ui, scale=(camera.aspect_ratio,1), color=color.hsv(240,.6,.1,.75)) username_field = InputField(y=-.12, limit_content_to='0123456789', default_value='11', active=True) username_field.text = '0929468098' password_field = InputField(y=-.18, hide_content=True) username_field.next_field = password_field def submit(): print('ursername:', username_field.text) print('password:', password_field.text) Button(text='Login', scale=.1, color=color.cyan.tint(-.4), y=-.26, on_click=submit).fit_to_text() username_field.on_value_changed = submit

ButtonList(Entity)

ursina/prefabs/button_list

ButtonList(button_dict, button_height=1.1, width=.5, popup=False, color=Button.default_color, highlight_color=color.white33, selected_color=color.azure, font=Text.default_font, clear_selected_on_enable=True, **kwargs)

.clear_selected_on_enable = clear_selected_on_enable
.button_height = button_height
.width = width
.text_entity = Text(parent=self, font=font, origin=(-.5,.5), text='empty', world_scale=20, z=-.1, x=.01, y=-(button_height*.25*Text.size), line_height=button_height)
.bg = Entity(parent=self, model='quad', origin=(-.5,.5), scale=width, color=color, collider='box')
.highlight = Entity(parent=self.bg, model='quad', color=highlight_color, scale=(1,self.button_height), origin=(-.5,.5), z=-.01, add_to_scene_entities=False)
.selection_marker = Entity(parent=self.bg, model='quad', color=selected_color, scale=(1,self.button_height), origin=(-.5,.5), z=-.02, enabled=False, add_to_scene_entities=False)
.button_dict = button_dict
.popup = popup

properties:
.button_dict
.selected

functions:
 input(key)
 update()
 on_disable()
 on_enable()

example:
from ursina import Ursina, Func default = Func(print, 'not yet implemented') def test(a=1, b=2): print('------:', a, b) button_dict = {} for i in range(6, 20): button_dict[f'button {i}'] = Func(print, i) bl = ButtonList(button_dict, font='VeraMono.ttf', button_height=1.5, popup=0, clear_selected_on_enable=False) def input(key): if key == 'space': bl.button_dict = { 'one' : None, 'two' : default, 'tree' : Func(test, 3, 4), 'four' : Func(test, b=3, a=4), } if key == 'o': bl.enabled = True bl.selected = 'button 7' bl.button_dict = {}

ButtonGroup(Entity)

ursina/prefabs/button_group

ButtonGroup(options, default='', min_selection=1, max_selection=1, origin=(-.5,.5,0), spacing=(0.025,0,0), **kwargs)

.deselected_color = Button.default_color
.selected_color = ButtonGroup.default_selected_color
.min_selection = min_selection
.max_selection = max(min_selection, max_selection)
.origin = origin
.spacing = spacing
.buttons = []
.selected = []
.options = options
.parent = camera.ui
.scale = Text.size * 2

properties:
.options
.value

functions:
 layout()
 input(key)
 select(b)
 on_value_changed()

example:
center = Entity(parent=camera.ui, model='circle', scale=.005, color=color.red, z=-1) gender_selection = ButtonGroup(('man', 'woman', 'other'), origin=(-.5,0)) def on_value_changed(): print('set gender:', gender_selection.value) gender_selection.on_value_changed = on_value_changed window.color = color._32

WindowPanel(Draggable)

ursina/prefabs/window_panel

WindowPanel(title='', content=[], **kwargs)

.content = content
.popup = False
.panel = Entity(parent=self, model='quad', origin=(0,.5), z=.1, color=self.color.tint(.1), collider='box')

functions:
 layout()

example:
''' WindowPanel is an easy way to create UI. It will automatically layout the content. ''' from ursina import Ursina, ButtonGroup wp = WindowPanel( title='Custom Window', content=( Text('Name:'), InputField(name='name_field'), Button(text='Submit', color=color.azure), Slider(), Slider(), ButtonGroup(('test', 'eslk', 'skffk')) ), popup=True ) wp.y = wp.panel.scale_y / 2 * wp.scale_y # center the window panel wp.layout() def input(key): if key == 'space': wp.enabled = True

Space

ursina/prefabs/window_panel

Space(height=1)

.height = height


example:
''' WindowPanel is an easy way to create UI. It will automatically layout the content. ''' from ursina import Ursina, ButtonGroup wp = WindowPanel( title='Custom Window', content=( Text('Name:'), InputField(name='name_field'), Button(text='Submit', color=color.azure), Slider(), Slider(), ButtonGroup(('test', 'eslk', 'skffk')) ), popup=True ) wp.y = wp.panel.scale_y / 2 * wp.scale_y # center the window panel wp.layout() def input(key): if key == 'space': wp.enabled = True

FileBrowser(Entity)

ursina/prefabs/file_browser

FileBrowser(file_button_class=FileButton, selection_limit=1, start_path=None, **kwargs)

.file_types = ['.*', ]
.start_path = start_path
.file_button_class = file_button_class
.return_files = True
.return_folders = False
.selection_limit = selection_limit
.max_buttons = 24
.title_bar = Button(parent=self, scale=(.9,.035), text='<gray>Open', color=color.dark_gray, highlight_color=color.dark_gray)
.address_bar = Button(parent=self, scale=(.8,.035), text='//', text_origin=(-.5,0), y=-.05, highlight_color=color.black)
.folder_up_button = Button(parent=self, scale=(.035,.035), texture='arrow_down', rotation_z=180, position=(-.42,-.05,-1), color=color.white, highlight_color=color.azure, on_click=self.folder_up)
.button_parent = Entity(parent=self)
.back_panel = Entity(parent=self, model='quad', collider='box', origin_y=.5, scale=(.9,(self.max_buttons*.025)+.19), color=color._32, z=.1)
.bg = Button(parent=self, z=1, scale=(999,999), color=color.black66, highlight_color=color.black66, pressed_color=color.black66)
.cancel_button = Button(parent=self, scale=(.875*.24, .05), y=(-self.max_buttons*.025)-.15, origin_x=-.5, x=-.875/2, text='Cancel', on_click=self.close)
.open_button = Button(parent=self, scale=(.875*.74, .05), y=(-self.max_buttons*.025)-.15, origin_x=.5, x=.875/2, text='Open', color=color.dark_gray, on_click=self.open)
.cancel_button_2 = Button(parent=self.title_bar, model=Circle(), world_scale=self.title_bar.world_scale_y*.75, origin_x=.5, x=.495, z=-.1, text='<gray>x', on_click=self.close)
.can_scroll_up_indicator = Entity(parent=self, model='quad', texture='arrow_down', rotation_z=180, scale=(.05,.05), y=-.0765, z=-.1, color=color.dark_gray, enabled=False, add_to_scene_entities=False)
.can_scroll_down_indicator = Entity(parent=self, model='quad', texture='arrow_down', scale=(.05,.05), y=(-self.max_buttons*.025)-.104, z=-.1, color=color.dark_gray, enabled=False, add_to_scene_entities=False)

properties:
.scroll
.path
.selection

functions:
 input(key)
 on_enable()
 close()
 folder_up()
 open(path=None)

example:
fb = FileBrowser(file_types=('.*'), enabled=False) def on_submit(paths): print('--------', paths) for p in paths: print('---', p) fb.on_submit = on_submit def input(key): if key == 'tab': fb.enabled = not fb.enabled

FileButton(Button)

ursina/prefabs/file_browser

FileButton(load_menu, path, **kwargs)

.load_menu = load_menu
.path = path
.original_color = self.color
.selected = False

properties:
.selected

functions:
 on_click()
 on_double_click()

example:
fb = FileBrowser(file_types=('.*'), enabled=False) def on_submit(paths): print('--------', paths) for p in paths: print('---', p) fb.on_submit = on_submit def input(key): if key == 'tab': fb.enabled = not fb.enabled

FileBrowserSave(FileBrowser)

ursina/prefabs/file_browser_save

FileBrowserSave(**kwargs)

.save_button = self.open_button
.file_name_field = InputField(parent=self, scale_x=.75, scale_y=self.save_button.scale_y, y=self.save_button.y)
.file_type = '' to save as
.last_saved_file = None gets set when you save a file
.overwrite_prompt = WindowPanel( content=( Text('Overwrite?'), Button('Yes', color=color.azure, on_click=self._save), Button('Cancel') ), z=-1, popup=True, enabled=False)

properties:
.file_type

functions:
 on_enable()
 on_disable()
 on_submit(path) implement .on_submit to handle saving

example:
from ursina.prefabs.file_browser_save import FileBrowserSave wp = FileBrowserSave(file_type = '.*') import json save_data = {'level': 4, 'name':'Link'} wp.data = json.dumps(save_data) wp.enabled = False def input(key): if key == 'tab': wp.enabled = not wp.enabled



RadialMenu(Entity)

ursina/prefabs/radial_menu

RadialMenu(buttons=list(), **kwargs)

.parent = camera.ui
.buttons = buttons
.open_at_cursor = True
.open_duration = .1
.bg = Panel(parent=self, model='quad', z=99, scale=999, collider='box', color=color.hsv(0,0,0,.1), enabled=False)
.z = -99
.scale = .075

functions:
 on_enable()
 input(key)

example:
rm = RadialMenu( buttons = ( RadialMenuButton(text='1'), RadialMenuButton(text='2'), RadialMenuButton(text='3'), RadialMenuButton(text='4'), RadialMenuButton(text='5', scale=.5), RadialMenuButton(text='6', color=color.red), ), enabled = False ) RadialMenuButton(text='6', color=color.red,x =-.5, scale=.06), def enable_radial_menu(): rm.enabled = True cube = Button(parent=scene, model='cube', color=color.orange, highlight_color=color.azure, on_click=enable_radial_menu) EditorCamera()

RadialMenuButton(Button)

ursina/prefabs/radial_menu

RadialMenuButton(**kwargs)



example:
rm = RadialMenu( buttons = ( RadialMenuButton(text='1'), RadialMenuButton(text='2'), RadialMenuButton(text='3'), RadialMenuButton(text='4'), RadialMenuButton(text='5', scale=.5), RadialMenuButton(text='6', color=color.red), ), enabled = False ) RadialMenuButton(text='6', color=color.red,x =-.5, scale=.06), def enable_radial_menu(): rm.enabled = True cube = Button(parent=scene, model='cube', color=color.orange, highlight_color=color.azure, on_click=enable_radial_menu) EditorCamera()

HealthBar(Button)

ursina/prefabs/health_bar

HealthBar(max_value=100, value=Default, roundness=.25, animation_duration=.1, show_text=True, show_lines=False, text_size=.7, origin=(-.5,.5), **kwargs)

.bar = Entity(parent=self, model=Quad(radius=roundness), origin=origin, z=-.005, color=color.red.tint(-.2), ignore=True)
.lines = Entity(parent=self.bar, y=-1, color=color.black33, ignore=True, enabled=show_lines, z=-.05)
.max_value = max_value
.clamp = True
.roundness = roundness
.animation_duration = animation_duration
.show_lines = show_lines
.show_text = show_text
.value = self.max_value if value == Default else value

properties:
.value
.show_text
.show_lines
.bar_color


example:
health_bar_1 = HealthBar(bar_color=color.lime.tint(-.25), roundness=.5, max_value=100, value=50) print(health_bar_1.text_entity.enabled, health_bar_1.text_entity.text) def input(key): if key == '+' or key == '+ hold': health_bar_1.value += 10 if key == '-' or key == '- hold': health_bar_1.value -= 10 print('ow')

ColorPicker(Entity)

ursina/prefabs/color_picker

ColorPicker(dynamic=True, **kwargs)

.bg = Entity(parent=self, z=.01, model=Quad(aspect=.5/.2), scale=[.5,.225], origin=[0,.5], color=color.black66)
.h_slider = Slider(parent=self, max=360, step=1, dynamic=dynamic, on_value_changed=self._calculate_color)
.s_slider = Slider(parent=self, max=100, step=1, dynamic=dynamic, on_value_changed=self._calculate_color)
.v_slider = Slider(parent=self, max=100, step=1, dynamic=dynamic, on_value_changed=self._calculate_color)
.a_slider = Slider(parent=self, max=100, default=100, step=1, dynamic=dynamic, on_value_changed=self._calculate_color)
.on_value_changed = None assign a function here
.preview = Button(parent=self, scale=(.5*.84,.05), origin=[0,.5], y=slider.y-.02, color=color.white)


example:
from ursina import Ursina ColorPicker()

HotReloader(Entity)

ursina/prefabs/hot_reloader

HotReloader(path=__file__, **kwargs)

.path = path
.path = Path(self.path)
.hotreload = False toggle with f9
.hotkeys = { 'ctrl+r' : self.reload_code, 'f5' : self.reload_code, 'f6' : self.reload_textures, 'f7' : self.reload_models, 'f8' : self.reload_shaders, 'f9' : self.toggle_hotreloading, }

functions:
 input(key)
 update()
 get_source_code()
 toggle_hotreloading()
 reload_code(reset_camera=True)
 reload_textures()
 reload_models()
 reload_shaders()

example:
application.hot_reloader.path = application.asset_folder.parent.parent / 'samples' / 'platformer.py' ''' By default you can press F5 to reload the starting script, F6 to reimport textures and F7 to reload models. '''

GridEditor(Entity)

ursina/prefabs/grid_editor

GridEditor(size=(32,32), palette=(' ', '#', '|', 'o'), canvas_color=color.white, edit_mode=True, **kwargs)

.w, self.h = int(size[0]), int(size[1])
.canvas = Entity(parent=self, model='quad', origin=(-.5,-.5), shader=unlit_shader, scale=(self.w/self.h, 1), color=canvas_color)
.canvas_collider = Entity(parent=self.canvas, model='wireframe_quad', origin=self.canvas.origin, color=color.blue, scale=2, position=(-.5,-.5), collider='box', visible=False)
.brush_size = 1
.auto_render = True
.cursor = Entity(parent=self.canvas, model=Quad(segments=0, mode='line', thickness=2), origin=(-.5,-.5), scale=(1/self.w, 1/self.h), color=color.hsv(120,1,1,.5), z=-.2, shader=unlit_shader)
.selected_char = palette[1]
.palette = palette
.start_pos = None
.prev_draw = None
.lock_axis = None
.outline = Entity(parent=self.canvas, model=Quad(segments=0, mode='line', thickness=2), color=color.cyan, z=.01, origin=(-.5,-.5))
.rect_selection = [Vec2(0,0), Vec2(0,0)]
.selection_renderer = Entity(parent=self.canvas, model=Mesh(mode='line', thickness=2), color=color.lime, alpha=.5, z=-.01, origin=(-.5,-.5), scale=(1/self.w,1/self.h))
.rect_tool = Entity(parent=self.canvas, model=Quad(0, mode='line', thickness=2), color=color.lime, z=-.01, origin=(-.5,-.5), start=Vec2(0,0), end=Vec2(0,0))
.selection_matrix = [[0 for y in range(self.h)] for x in range(self.w)]
.temp_paste_layer = Entity(parent=self.cursor, model='quad', origin=(-.5,-.5), z=-.02, enabled=False)
.is_in_paste_mode = False
.undo_stack = []
.undo_index = 0
.help_icon = Button(parent=self.canvas, scale=.025, model='circle', origin=(-.5,-.5), position=(-.0,1.005,-1), text='?', target_scale=.025)
.edit_mode = edit_mode

properties:
.palette
.edit_mode

functions:
 update()
 get_cursor_position()
 draw(x, y)
 input(key)
 record_undo()
 floodfill(matrix, x, y, first=True)
 copy()
 enter_paste_mode()
 exit_paste_mode(discard=False)
 clear_selection()
 render_selection()

example:
app = Ursina(borderless=False) ''' pixel editor example, it's basically a drawing tool. can be useful for level editors and such here we create a new texture, but can also give it an existing texture to modify. ''' from PIL import Image t = Texture(Image.new(mode='RGBA', size=(32,32), color=(0,0,0,1))) from ursina.prefabs.grid_editor import PixelEditor editor = PixelEditor(parent=scene, texture=load_texture('brick'), scale=10) camera.orthographic = True camera.fov = 15 EditorCamera(rotation_speed=0) from ursina.prefabs.grid_editor import ASCIIEditor ASCIIEditor(x=0, scale=.1)

PixelEditor(GridEditor)

ursina/prefabs/grid_editor

PixelEditor(texture, palette=(color.black, color.white, color.light_gray, color.gray, color.red, color.orange, color.yellow, color.lime, color.green, color.turquoise, color.cyan, color.azure, color.blue, color.violet, color.magenta, color.pink), **kwargs)


properties:
.texture

functions:
 set_texture(texture, render=True, clear_undo_stack=True)
 draw(x, y)
 render()
 save()

example:
app = Ursina(borderless=False) ''' pixel editor example, it's basically a drawing tool. can be useful for level editors and such here we create a new texture, but can also give it an existing texture to modify. ''' from PIL import Image t = Texture(Image.new(mode='RGBA', size=(32,32), color=(0,0,0,1))) from ursina.prefabs.grid_editor import PixelEditor editor = PixelEditor(parent=scene, texture=load_texture('brick'), scale=10) camera.orthographic = True camera.fov = 15 EditorCamera(rotation_speed=0) from ursina.prefabs.grid_editor import ASCIIEditor ASCIIEditor(x=0, scale=.1)

ASCIIEditor(GridEditor)

ursina/prefabs/grid_editor

ASCIIEditor(size=(61,28), palette=(' ', '#', '|', 'A', '/', '\\', 'o', '_', '-', 'i', 'M', '.'), font='VeraMono.ttf', canvas_color=color.black, line_height=1.1, **kwargs)

.text_entity = Text(parent=self.parent, text=text, x=-.0, y=.5, line_height=line_height, font=font)
.scale = (self.text_entity.width, self.text_entity.height)

functions:
 render()
 input(key)

example:
app = Ursina(borderless=False) ''' pixel editor example, it's basically a drawing tool. can be useful for level editors and such here we create a new texture, but can also give it an existing texture to modify. ''' from PIL import Image t = Texture(Image.new(mode='RGBA', size=(32,32), color=(0,0,0,1))) from ursina.prefabs.grid_editor import PixelEditor editor = PixelEditor(parent=scene, texture=load_texture('brick'), scale=10) camera.orthographic = True camera.fov = 15 EditorCamera(rotation_speed=0) from ursina.prefabs.grid_editor import ASCIIEditor ASCIIEditor(x=0, scale=.1)

grid_layout

ursina/scripts/grid_layout


functions:
 grid_layout(l, max_x=8, max_y=8, spacing=(0,0,0), origin=(-.5,.5,0), offset=(0,0,0))

example:
center = Entity(model='quad', scale=.1, color=color.red) p = Entity() for i in range(4*5): b = Button(parent=p, model='quad', scale=Vec2(.2,.1), text=str(i), color=color.tint(color.random_color(),-.6)) b.text_entity.scale=1 t = time.time() grid_layout(p.children, max_x=7, max_y=10, origin=(0, .5), spacing=(.15, 0)) center = Entity(parent=camera.ui, model=Circle(), scale=.005, color=color.lime) EditorCamera() print(time.time() - t)

duplicate

ursina/duplicate


functions:
 duplicate(entity, copy_children=True, *args, **kwargs): # use a for loop instead of duplicate() use a for loop instead of duplicate() if you can.

example:
from ursina import Ursina, Button, scene, EditorCamera e = Button(parent=scene, scale=1, text='yolo') e2 = duplicate(e, x=1.25) EditorCamera()

SmoothFollow

ursina/scripts/smooth_follow

SmoothFollow(target=None, offset=(0,0,0), speed=8, rotation_speed=0, rotation_offset=(0,0,0))

.target = target
.offset = offset
.speed = speed
.rotation_speed = rotation_speed
.rotation_offset = rotation_offset

functions:
 update()

example:
player = Entity(model='cube', color=color.orange) def update(): player.x += held_keys['d'] * .1 player.x -= held_keys['a'] * .1 e = Entity(model='cube') sf = e.add_script(SmoothFollow(target=player, offset=(0,2,0))) def input(key): global sf if key == '1' and sf in e.scripts: e.scripts.remove(sf) EditorCamera()

Scrollable

ursina/scripts/scrollable

Scrollable(**kwargs)

.max = inf
.min = -inf
.scroll_speed = .05
.scroll_smoothing = 16
.axis = 'y'
.target_value = None

functions:
 update()
 input(key)

example:
''' This will make target entity move up or down when you hover the entity/its children while scrolling the scroll wheel. ''' p = Button(model='quad', scale=(.4, .8), collider='box') for i in range(8): Button(parent=p , scale_y=.05, text=f'giopwjoigjwr{i}', origin_y=.5, y=.5-(i*.05)) p.add_script(Scrollable())

NoclipMode

ursina/scripts/noclip_mode

NoclipMode(speed=10, require_key='shift')

.speed = speed
.require_key = require_key
.ignore_paused = True

functions:
 input(key)
 update()

example:
player = Entity(model='cube', color=color.orange) Entity(model='plane', scale=10) EditorCamera() player.add_script(NoclipMode2d())

NoclipMode2d

ursina/scripts/noclip_mode

NoclipMode2d(speed=10, require_key='shift')

.speed = speed
.require_key = require_key
.ignore_paused = True

functions:
 input(key)
 update()

example:
player = Entity(model='cube', color=color.orange) Entity(model='plane', scale=10) EditorCamera() player.add_script(NoclipMode2d())

build

ursina/build

.project_folder = Path.cwd()
.project_name = project_folder.stem
.build_folder = Path(project_folder / f'build_{platform.system()}')
.build_folder.mkdir(exist_ok=True)
.ignore_folders = []
.ignore_filetypes = []
.compressed_textures = []
.compressed_textures_folder = Path(project_folder/'textures_compressed')
.python_dest = Path(build_folder / 'python')
.python_dlls_dest = Path(build_folder / 'python/DLLs')
.python_lib_dest = Path(build_folder / 'python/Lib')
.src_dest = Path(build_folder / 'src')
.build_engine = True
.build_game = True
.entry_point = 'main.py'
.start_time = time.time()

functions:
 copytree(src, dst, symlinks=False, ignore_patterns=[], ignore_filetypes=[])


models

quad
wireframe_cube
plane
circle
diamond
wireframe_quad
sphere
cube
icosphere
cube_uv_top
arrow
sky_dome



textures

noise
grass
vignette
arrow_right
test_tileset
tilemap_test_level
shore
file_icon
sky_sunset
radial_gradient
circle
perlin_noise
brick
grass_tintable
circle_outlined
ursina_logo
arrow_down
cog
vertical_gradient
white_cube
horizontal_gradient
folder
rainbow
heightmap_1
sky_default



shaders

colored_lights_shader
fresnel_shader
projector_shader
instancing_shader
texture_blend_shader
matcap_shader
triplanar_shader
unlit_shader
geom_shader
normals_shader
transition_shader
noise_fog_shader
lit_with_shadows_shader
fxaa
camera_empty
ssao
camera_outline_shader
pixelation_shader
camera_contrast
camera_vertical_blur
camera_grayscale