Reputation: 37
I am trying to make an rpg-style game with ursina. I want to have the camera always follow the back of the character. I tried using camera.look_at(player) but I couldn't get the camera to rotate to the back of the character when it rotated.
app = Ursina()
class character(Entity):
def __init__(self):
super().__init__(
model = load_model('cube'),
color = color.red,
position = (-0, -3, -8)
)
player = character()
print(player.forward)
print(player.forward)
camera.look_at(player)
player.rotation_y =180
def update():
if held_keys['a']:
player.rotation_y -= 2
if held_keys['d']:
player.rotation_y += 2
app.run()```
Upvotes: 2
Views: 4212
Reputation: 146
If anyone wants to use FirstPersonController
, I found out how to move the camera away from the player, while keeping all physics interactions!
After creating the FirstPersonController
, modify the position of its camera_pivot
(default is (0,2,0)
).
player = FirstPersonController(model="cube", color=color.orange, origin_y=-.5,z=-10)
# the default camera_pivot is (0,2,0)
player.camera_pivot.z = -3.5 # move the camera behind the player model
player.camera_pivot.y = 2.5 # move the camera a little higher
Full example (q to quit)
from ursina import *
from ursina.prefabs.first_person_controller import FirstPersonController
from ursina.shaders import lit_with_shadows_shader
app = Ursina()
Entity.default_shader = lit_with_shadows_shader
ground = Entity(model='plane', collider='box', scale=64, color=color.green)
player = FirstPersonController(model="cube", color=color.orange, origin_y=-.5,z=-10)
# the default camera_pivot is (0,2,0)
player.camera_pivot.z = -3.5 # move the camera behind the player model
player.camera_pivot.y = 2.5 # move the camera a little higher
# setting collider and making it visible for debugging
player.collider = BoxCollider(player, Vec3(0,1,0), Vec3(1,2,1))
player.collider.visible=True
# adding some objects to collide with
for i in range(16):
Entity(model='cube', origin_y=-.5, scale=2, texture='brick', texture_scale=(1,2),
x=random.uniform(-8,8),
z=random.uniform(-8,8) + 8,
collider='box',
scale_y = random.uniform(2,3),
color=color.hsv(0, 0, random.uniform(.9, 1))
)
sun = DirectionalLight()
sun.look_at(Vec3(1,-1,-1))
Sky()
def input(key):
if key == 'q':
exit()
app.run()
Upvotes: 3
Reputation: 1
I have a better solution, because when using the FirstPersonController, the physics are applied to the controller and not to the player, my solution is to create a camera:
camera= EditorCamera()
this will create a camera that will allow us to see the game, the next thing we must do is we must create the player and the floor:
terrain_width= 50
player= Entity(model="cube", color= color.orange)
player.x= 0
floor= Entity(model="plane", texture="grass", scale= terrain_width)
Now that this is done, we will stick the camera to the player, and adjust some parameters to see the player from above-back:
camera.parent= player
camera.y= 5
camera.z= -10
camera.rotation_x= 9.15
now we can make our player move and we will see that the camera also moves:
def input(key):
if key == "a":
player.x-= 1
if key == "d":
player.x+= 1
if key == "w":
player.z+= 1
if key == "s":
player.z-= 1
this would be the complete code:
from ursina import *
app= Ursina()
camera= EditorCamera()
terrain_width= 50
player= Entity(model="cube", color= color.orange)
player.x= 0
floor= Entity(model="plane", texture="grass", scale= terrain_width)
camera.parent= player
camera.y= 5
camera.z= -10
camera.rotation_x= 9.15
def input(key):
if key == "a":
player.x-= 1
if key == "d":
player.x+= 1
if key == "w":
player.z+= 1
if key == "s":
player.z-= 1
app.run()
I hope this will be useful to you :)
Upvotes: 0
Reputation: 1185
You may want to change the origin
. Also using parents
. I'll explain what this means in a moment.
To change the origin
(the point at which an entity is moved and rotated) to a point behind it.
e.g.
from ursina import * # import urisna
app = Ursina() # make app
player = Entity(model='cube', # this creates an entity of a cube
origin = (0, 0, -2)) #now you have a origin behind the entity
app.run() #run app
But what about the camera, I hear you ask!
I'd recommend the ursina.prefabs.first_person_controller
It may be designed for 1st person control, but you can use it for your purpose.
# start by doing the normal thing
from ursina import *
# but also import the first person prefab
from ursina.prefabs.first_person_controller import FirstPersonController
app = Ursina()
# create camera and player graphic
cam = FirstPersonController()
player = Entity(model='cube',
origin = (0, 0, -2),
parent = cam)
# run
app.run()
You will need to create a floor entity
.
That is ALL YOU NEED for the 3rd person controller. The parents and origins ensure that. It has built in WASD and Arrow Key control, with mouse control too.
@Cyber-Yosh recently asked a question for this post on how to use it without the 1st person controller. Here's how. I have commented on the changes.
from ursina import * # import as usual
app = Ursina() # create app as usual
window.fps_counter.enabled = False # this is just to remove the fps counter
box = Entity(model='cube', # create cube as before (you can make your own class)
origin=(0,0.7,-5), # set origin to behind the player and above a little
parent=camera, # make it orientate around the camera
color=color.red, # change the color
texture='shore') # choose a nice texture
def update(): # define the auto-called update function
if held_keys['a']:
camera.rotation_y -= 10 * time.dt # the time.dt thing makes it adapt to the fps so its smooth
elif held_keys['d']:
camera.rotation_y += 10 * time.dt
Sky() # just a textured sky to make sure you can see that you are both rotating
app.run() # run
You'll notice that I've not created a class (adapting this for it is easy enough), but I did not use load_model
. This is because even if you are using your own model, you don't need to use load_model
. Simply put the name of the file (without the file extension) as a string
. This works, I've tried it.
If you have any more questions, don't hesitate to ask. I am more than happy to help. If this worked, be sure to upvote
and approve
.
Upvotes: 5
Reputation: 1489
Parent the camera to the player and move it back. That way it will rotate along with the player entity.
camera.parent = player
camera.z = -10
Upvotes: 1