Based on the recent discussion here Contribution ideas - more GAME samples! I have created a compact FPS sample program using Bullet Physics, .gltf exports, blend2bam Actor animation exports, Hardware Skinning with panda3d-complexpbr, a first-person camera handler, a movement timing system, an animated handgun model, and more.
06/25/23 PBR IBL update:
I have updated the Arena FPS Sample Program to utilize complexpbr for PBR IBL rendering of the scene and for actor hardware skinning support (skeletal animations). I believe that this update increases the quality of the program significantly, and demonstrates how to use complexpbr in a practical program. As always, if you run into any issues using this new setup procedure, post a comment below and I will get back to you. PBR IBL screenshots below.
Comparison between last major update and the 06/25/23 update:
Please discuss enhancements and changes to this sample program here. I am willing to take it further based on suggestions, or if you feel capable go ahead and start hacking on it. The amount of detail and logic in this sample program may be deceptive. Itās not exactly simple.
Full code and assets here:
Features:
First person shooter basic environment
First person camera handling system
Interactive target dot reticule system
Gamepad support
Armature with āwalkingā and ādeathā animations
Very cool Simulan! I went ahead and pulled the repo, and tested things out as Iāve been looking to hack on some very similar types of things for Panda. Until now Iāve been tweaking āRoaming Ralphā to work out bugs.
First off, thanks for doing this. Being new to Panda myself, just reading your code really helped me get ideas on some ways to do things that would have probably taken me hours/days/weeks of trial and error to try to figure out on my own. This is a great example of how sample code like this can really help other folks new to Panda really get up to speed quickly.
I also like how youāve already gone above/beyond, and decided to add support for things I didnāt even know existed till I saw your code (simplepbr, gltf support). Maybe experienced Panda3d folks know about these things but I had no clue! Another great reason to have such nice (up to date) samples, the cumulative experience of experienced Panda3d usersā knowledge gets condensed into some working code that others can learn from.
Anyhow, thanks for all your efforts here. Iād definitely like to read through this code much more deeply and see if I can help flesh things out more.
Iāve been play-testing this a bit, and lots of ideas came to mind on things Iād like to try my hand at.
It only took a few seconds of google-ing, but for total newbies like myself a blurb in the README on what to āpip installā might help others. Once I did that, ran perfectly
Definitely would like to take a bunch of free media assets I have lying around and see if I can get it to work with your foundation, I have a lot of animated character, textures, meshes for the level and the like. Also the physics library you started with (bullet) I know is super capable - so some objects to collide with might help to show itās capability.
I few bugs that popped up for me: - the NPC seems to dart around super quickly, then dash to a far wall and fall through the floor and disappear. I couldnāt really catch it. Iām sure super easy to tweak, but just to mention. Also colliding with the walls seems to teleport my camera on top of the wall immediately, collision definitely works but my guess is collision response just needs a little configuration. Other minor little things, like movement was hard to perceive without a floor texture or some obstacles, but this is likely by design - for a first version this is a really great foundation.
Thanks again for this. Iāll drop a blurb if/when I can get any useful results building off of what youāve started!!
Great, but you forgot to mention the dependency gltf
Traceback (most recent call last):
File "main.py", line 54, in <module>
import gltf
ModuleNotFoundError: No module named 'gltf'
In view of the fact that Iām a bore, I think itās worth noting that this example is related to python. It is impossible to repeat this in C++.
I have another message .
:display:gsg:glgsg(warning): Shader created-shader produced the following warnings:
WARNING: Too many temp register is used in Fragment shader, it may cause slow execution.
As a minor nitpick, one thing Iād like to suggest is to only use the snake_case variant of the Panda method names, since there was talk of deprecating the use of the camelCase names at some point.
You can change the NPC movement speed by changing the increments which are applied to the position, making the NPC slow or fast. I made it fast by default to give some challenge to the player in shooting the head. The NPC movement implementation is bad, but this is because I didnāt want to go way above an entry level userās head with AI techniques. I have written code that avoids all above floor collision meshes but it is rather more sophisticated than Iād want an entry level user to deal with.
Yep, there are some bugs and suboptimal choices in this sample program. All fixable I believe.
Thanks for the supportive comment and feel free to share your demos with the community. Itās nice to have another seasoned dev here, even if your specialty is the big name engines. I have used Unreal 4 to some extent for VR development so Iām about as familiar with it as you are Panda3D.
I made a quick āfixā for this, which is to make the npc_1 movements more normalized. It should at least take longer to escape the arena this way.
The real solution is to add some ray testing logic to the character, or do something like apply Bullet forces to the character node. Either of these is getting into complexity I donāt think is appropriate, but Iām open to solutions other people may suggest. I think the existing NPC timer could be used to apply Bullet forces equally as well, which may prevent most cases of the NPC passing through the arena wall. After all Iām manually applying a graph transformation on the character with the Task system even though itās being actively collision modeled, which may not be the best (general) solution.
One fairly simple way to implement future collision detection is to have, I believe, a Bullet Ghost node Box some multiple the size of the NPC character, and check wall intersections on that. This would require some more logic to implement, but might be fairly compact code-wise.
The updated NPC timer cycle:
# npc movement timer
def npc_1_move_gen():
while not self.npc_1_is_dead:
m_incs = []
for x in range(0, 2):
m_incs.append(random.uniform(0.03, 0.08))
print('NPC_1 movement increments this cycle: ' + str(m_incs))
self.npc_1_move_increment[0] = m_incs[0]
self.npc_1_move_increment[1] = m_incs[1]
time.sleep(3)
self.npc_1_move_increment[0] = m_incs[0]
self.npc_1_move_increment[1] = m_incs[1]
time.sleep(3)
self.npc_1_move_increment[0] = (-1 * m_incs[0]) * 2
self.npc_1_move_increment[1] = (-1 * m_incs[1]) * 2
time.sleep(3)
self.npc_1_move_increment[0] = 0
self.npc_1_move_increment[1] = 0
For the record, you donāt need a separate DirectObject at all: āShowBaseā inherits from āDirectObjectā, and thus you can register your events with your āappā class. Something like this:
class Game(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.accept("space", self.someMethod)
I would suggest, in place of āsleepā-timers, that you apply a delta-time value to your movements. That should normalise for potentially-variable frame-rates, at the least!
If the NPCs still move too fastāor if the frame-rate drops too lowāthen you can perhaps implement either sub-division of physics updates or ācontinuous collision detectionā.
The variable frame rate issue is limited to some extent with calling clock-frame-rate 60 in the prc file. But yes, enhancing the NPC handler is important.
CCD was already enabled upon the first posting, at least on some objects.
I hope we can somehow combine these different styles in a productive way, but I do not yet see a truly idiomatic way of writing Panda3D. I similarly have a difficult time reading your examples, and I apologize for a lack of communication in that regard.