Jump to content

Search the Community

Showing results for tags 'Sound'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Blogs

  • Development Blog
  • Canardian's Blog
  • Beyond Civilization Blog Ext
  • Tyler's Blog
  • macklebee's Blog
  • B-Byrnes' Blog
  • Marleys Ghost's Blog
  • omid3098's Blog
  • Richardsimpo123456's Blog
  • DJDD's Blog
  • Rick's Blog
  • --
  • xtreampb's Blog
  • Economically Disadvantaged
  • klepto2's Blog
  • Old Blog
  • Chris Paulson's Blog
  • Davaris' Blog
  • nil
  • Rekindled Phoenix's Blog
  • Flexman's Blog
  • Kattemaksu Online
  • Marcousik's Creations Blog
  • EVE LBS Studio
  • Rendering puzzles
  • Screen Size Utility
  • Niosop's Blog
  • 1299 RTS Game Project
  • Blitzbat's Blog
  • gordonramp's Blog
  • Andy Gilbert's Blog
  • Marcus' Blog
  • JornAggror Blog
  • diedir's Blog
  • wayneg's Blog
  • Masterxilo's Blog
  • Dave Lee's Blog
  • peubuy's blog
  • OD Arts -Leadwerks Blog
  • The progression......
  • Leadwerks News
  • The Progression
  • Pancake's Blog
  • Test Blog
  • BLaBZ Blog
  • Pure³d's Blog
  • dreamhead Blog
  • RVL's Blog
  • DB's Blog
  • Toxin Games Development Blog
  • CombatHelo Blog (RSS Import)
  • Foolish's Blog
  • ZioRed's Corner
  • Toxin Games Twitter
  • Shard - Third Initiative
  • Shard's Blog
  • Soamp's Blog
  • Soamp's Blog
  • Laurens' Blog
  • JT`s warehouse district
  • Kennar's Blog
  • KiteFuchs' Blog
  • KiteFuchs' Blog
  • Rachel's Dev-Blog
  • Eagle's Blog
  • zaphos' Blog
  • please delete this blog
  • Afke's Blog
  • Richard Simpson
  • knowledgegranted's Blog
  • EdzUp(GD)'s Blog
  • aGameLife's Kelasel MMORPG Blog
  • tournamentdan's Blog
  • Beyond Civilization Blog
  • smashthewindow
  • AnniXa's Blog
  • AnniXa's Blog
  • Elemental Development
  • DigitalHax Blog
  • Aria's Blog
  • Strogg76's Blog
  • Clackdor's Blog
  • Leadwerks Project Status
  • simpleprogrammer's Blog
  • Pathfinding in LE.2.x
  • Naughty Alien's Blog
  • smashthewindow's Blog
  • Ali Salehi's Blog
  • Jardar's Blog
  • Chris Vossen's Development Blog
  • Scarlet Thread Studios' Blog
  • Kronos' Blog
  • Benton's Blog
  • ChrisV's Blog
  • tjheldna's Blog
  • shadmar's Blog
  • 3D Masons, LLC
  • Andy Gilbert's Enviro Models
  • ParaToxic's Blog
  • NarkLord's Blog
  • ChrisMAN's Blog
  • ChrisMAN's Blog
  • CGMan's Blog
  • The Game
  • Chris Tutorials
  • Leadwerks 3 Experience
  • An Alien Saga
  • klepto2 & Leadwerks 3
  • Inside the mind of eternal insomniac
  • josk's Blog
  • Shader Development in Leadwerks 3.1
  • 3D Coat : Column game making of
  • Einlander's Blog
  • Ginger George's Blog
  • I have a problem
  • Michael_J's Blog
  • nasamydifol's Blog
  • Digman's Blog
  • noesisGUI
  • SavageDogg38's Blog
  • Built from Ruins
  • Remaining Days
  • test_external_blog
  • The Hunt For Food Blog
  • Crazy Minnow Studio
  • CrazyMinnowStudio
  • Guppy's Blog
  • Playing Online
  • Evayr's Blog
  • DerRidda's Blog
  • Karl's Blog
  • whiterabbit's Blog
  • Tinyboss Games
  • abendkleider's Blog
  • sacguccireplica's Blog
  • Arena
  • Imchasinyou's Blog
  • xtom's Blog
  • Lua is better than you think.
  • mdgunn's Blog
  • Crime Closer
  • lxFirebal69xl's Blog
  • Wedmer's Blog
  • Lockdown, going forward.
  • Pump-Action Captain
  • Igor's Blog
  • Dead Anyway
  • Runenrise and more
  • reepblue's Blog
  • Slippy's Corner
  • LUA Musings
  • severjack's Blog
  • mikeporter's Blog
  • miko93's Blog
  • Megalocerous' Blog
  • lxFirebal69xl's Blog
  • aiaf's Blog
  • Lostghbear's Blog
  • echo $BLOG_NAME > blog_title.tmpl
  • johnadam111's Blog
  • Dwarf Beard
  • burgelkat's Blog
  • Charrua's Blog
  • peterpaul's Blog
  • joshmathews' Blog
  • Martin Kearl's Blog
  • Brutile's blog
  • tipforeveryone's Blog
  • Glushchenko Blog
  • Express Lab Games Blog
  • Blueapples' Blog
  • DooMAGE's Blog
  • Structura devblog
  • UltraEngine - Experiences, add-ons and other Stuff
  • martyj's Blog
  • Dragonfreak's Blog
  • Brutile's Blog
  • assigmenthelp
  • Case Study Assignment Help
  • How to deal with bad grade ?
  • How to deal with bad grade ?
  • GameDev Blog
  • devcjohnson's Blog
  • devcjohnson's Blog
  • THE WHAT? Blog
  • The Demurian Scribe
  • GUI Editor
  • GUI Tutorial
  • noob_shaders
  • The Seventh World
  • Phodex Games Blog
  • Leadwerks VS Source 2
  • Work in Progress - Scifi PBR Media
  • [C++] First Player game start
  • The Blog of Yue
  • Snowboarding Development Blog
  • Ocean: Rendering in Leadwerks 4
  • Game Ready Maps
  • Ultra App Kit (Advanced Custom Widgets)
  • Poking around
  • Blender tutorials
  • Usefull Scripts & Components
  • Thirsty Panther
  • Ultimate Action Game Controller
  • Ultra Tutorials
  • SCP Dev Blog

Forums

  • Software
    • General Discussion
    • Programming
    • Addon Development
    • Game Artwork
    • Showcase
    • Suggestion Box
    • Bug Reports
  • Addons

Categories

  • Streams and Events
  • Tutorials
  • Games
  • Work in Progress

Categories

  • Components
  • Effects
  • Extensions
  • Materials
    • Asphalt
    • Brick
    • Concrete
    • Debris
    • Effects
    • Fabric
    • Ground
    • Marble
    • Metal
    • Organic
    • Plaster
    • Rock
    • Roof
    • Sand
    • Snow
    • Surface Imperfections
    • Tile
    • Wood
  • Models
    • Animals & Creatures
    • Architecture
    • Food
    • Machinery
    • Plants and Vegetation
    • Props
    • Vehicles
    • Tools
  • Scenes
  • Skyboxes
  • Sound
  • Tools

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Location

Found 15 results

  1. In this tutorial we will add features to real-time tactic/strategy game in Ultra Engine fro prev tutorial: Plan: 1. Add flag model to use when pointing where to go for units 2. Make save/load system with quick save 3. Make blood particle emitter which will be used on hits and use it in Unit::Methood 4. Make blood decals which will be on the ground after death and spawn it in Unit::Kill 5. Download and use sounds for units getting damage. In this tutorial used 2117 Build from Steam Beta branch (Dev in Standalone version). In 0.9.8 version Component::Load/Save are protected. Build number can be found in the Editor Help->About Flag Flag will represent a place that player units will try to reach. Model can be found here: https://sketchfab.com/3d-models/triangle-flag-adadd59fd56d44f7b0354d1caba38f95 Download .glb version and put it to new folder "triangle_flag" in Models. Convert to mdl in the Editor. By default this model is too small. Set Scale 5.0 in Transform tab and in Tools click Reset Transform (works properly atm only for non-animated models) to save new size for good. Also click on Collapse in Tools to unite all meshes so it would be shown like single entity in a scene (otherwise this entity will have some kids which is not critical, but it's better to make it simpler). triangle_flag.zip Flag prefab: 1. Put triangle_flag model to scene 2. In Physics Collision type - None and Pick Mode - None 3. Attach WayPoint component 4. In Appearance tab in add "Save" to tags - it will be needed eventually for game save/load system 5. Save as prefab called FlagWayPoint in Prefabs folder FlagWayPoint.zip Updating classes Let's update Unit class for using getting an entity as target point and save system later. Add new method to Unit.h: void goTo(shared_ptr<Entity> targetPointEntity, bool isForced = false); In Unit.cpp method implementation: void Unit::goTo(shared_ptr<Entity> targetPointEntity, bool isForced) { if (targetPointEntity) { isForcedMovement = isForced; targetPoint = targetPointEntity; goTo(); } } Add to Start() a new tag: entity->AddTag("Save"); And also in Start() after that: if (seq != -1) { //to disable pain state at end of pain animation model->skeleton->AddHook(seq, count - 1, EndPainHook, Self()); } Add this: if (health <= 0) { seq = model->FindAnimation(deathName); int count = model->CountAnimationFrames(seq); model->Animate(deathName, 1.0f, 250, ANIMATION_ONCE, count - 1); } It's needed to make Unit make lie down in death animation if it was killed when game was save. Add a little bit below after healthBar initialization nex tline: healthBar->SetScale((float)health / (float)maxHealth, 1, 1); So health bar would have correct size after a game loading. We also want to save selected state after a loading so add first line to Load and second to Save: if (properties["isSelected"].is_boolean()) isSelected = properties["isSelected"]; properties["isSelected"] = isSelected; After line this line in Kill method: ListenEvent(EVENT_TIMERTICK, removeEntityTimer, RemoveEntityCallback, Self()); Add this: //not saving if supposed to be deleted anyway entity->RemoveTag("Save"); Current Unit: Unit.zip First version of TopDownCamera had an issue that would appear after game load: Update init() method to make it update pivot after game load: if (gameCamera && !targetPivot.lock()) { gameCamera->Listen();//for positional sound gameCamera->SetSweptCollision(true);//for removing pop up effect after quick move/turn gameCamera->SetRotation(CAMERA_PITCH, gameCamera->GetRotation(true).y, gameCamera->GetRotation(true).z); auto targetPivotShared = CreatePivot(gameCamera->GetWorld()); targetPivotShared->SetPickMode(PICK_NONE); sceneWeak.lock()->AddEntity(targetPivotShared); targetPivot = targetPivotShared; } //setting position and rotation here in case of game load gameCamera->SetParent(nullptr); auto targetPivotShared = targetPivot.lock(); auto targetPosition = getCirleCenter(gameCamera->GetPosition(true), gameCamera->GetRotation(true)); targetPosition.y = 0; targetPivotShared->SetPosition(targetPosition); targetPivotShared->SetRotation(0, gameCamera->GetRotation(true).y, gameCamera->GetRotation(true).z); gameCamera->SetParent(targetPivotShared); return true; TopDownCamera.zip In StrategyController.cpp update Start to add tag for Save next to another tag line entity->AddTag("Save"); To Save method add saving selected units: properties["selectedUnits"] = {}; int index = 0; for (auto const& selectedUnitWeak : selectedUnits) { auto selectedUnit = selectedUnitWeak.lock(); if (selectedUnit) { properties["selectedUnits"][index] = selectedUnit->GetUuid(); index++; } } Add their loading to Load: selectedUnits.clear(); if (properties["selectedUnits"].is_array()) { for (int i = 0; i < properties["selectedUnits"].size(); i++) { auto unit = scene->GetEntity(properties["selectedUnits"][i]); if (unit) { selectedUnits.push_back(unit); } } } Find this line for (auto const& entityWeak : selectedUnits) { Replace a code from starting from line above this line and ended 8 lines lower with this snippet: } else if (!selectedUnits.empty()) { auto flag = LoadPrefab(camera->GetWorld(), "Prefabs/FlagWayPoint.pfb"); if (flag) { flag->SetPosition(pick.position); } for (auto const& entityWeak : selectedUnits) { auto entityUnit = entityWeak.lock(); if (entityUnit && entityUnit->GetComponent<Unit>()) { if (flag) { entityUnit->GetComponent<Unit>()->goTo(flag, true); } else { entityUnit->GetComponent<Unit>()->goTo(pick.position, true); } } } } Or just download full class: StrategyController.zip Custom Save/Load system Current official system have a lot of flaws which are listed here: Most of them will be fixed, but something like no loading entities, which were added while run time like flags in this game, may still persist. This one is resolved by loading prefabs. You can also add manual recreation for most types of entities, depends on needs, but prefabs should be enough in most cases. Game class have a lot of changes, which were made to create custom save system. Whole Game.h: #pragma once #include "UltraEngine.h" #include "Components/Player/FPSPlayer.h" using namespace UltraEngine; class Game : public Object { protected: shared_ptr<Camera> uiCamera; shared_ptr<Scene> scene; shared_ptr<FPSPlayer> fpsPlayer; shared_ptr<Widget> menuPanel; shared_ptr<Widget> gameSavedLabel; //hide gameSavedLabel on timer shared_ptr<Timer> gameSavedLabelTimer; Game(); void init(shared_ptr<Framebuffer> framebuffer, WString mapPath); //update basic entity properties - position, rotation, tags void loadEntity(shared_ptr<Entity> entity, table entityTable); void loadGame(table saveTable); void saveGame(WString saveName); static bool QuickSaveGameCallback(const UltraEngine::Event& ev, shared_ptr<UltraEngine::Object> extra); static bool HideGameSavedLabelCallback(const UltraEngine::Event& ev, shared_ptr<UltraEngine::Object> extra); public: //to show/hide game menu on Esc static bool GameMenuButtonCallback(const Event& ev, shared_ptr<Object> extra); static std::shared_ptr<Game> create(shared_ptr<Framebuffer> framebuffer, WString mapPath); //for game loading static std::shared_ptr<Game> create(shared_ptr<Framebuffer> framebuffer, table saveTable); shared_ptr<Interface> ui; shared_ptr<World> world; }; Game.cpp: #include "UltraEngine.h" #include "Game.h" #include "CustomEvents.h" Game::Game() = default; std::shared_ptr<Game> Game::create(shared_ptr<Framebuffer> framebuffer, WString mapPath) { struct Struct : public Game {}; auto instance = std::make_shared<Struct>(); instance->init(framebuffer, mapPath); return instance; } std::shared_ptr<Game> Game::create(shared_ptr<Framebuffer> framebuffer, table saveTable) { struct Struct : public Game {}; auto instance = std::make_shared<Struct>(); std::string mapName = saveTable["MapPath"]; instance->init(framebuffer, WString(mapName)); instance->loadGame(saveTable); return instance; } bool Game::GameMenuButtonCallback(const Event& ev, shared_ptr<Object> extra) { if (KEY_ESCAPE == ev.data && extra) { auto game = extra->As<Game>(); bool isHidden = game->menuPanel->GetHidden(); game->menuPanel->SetHidden(!isHidden); if (game->fpsPlayer) { //we can get a game window anywhere, but take in mind that it will return nullptr, if window is not active ;) auto window = ActiveWindow(); //checking just in case if we actually got a window if (window) { //hiding cursor when hiding a menu and vice versa window->SetCursor(isHidden ? CURSOR_DEFAULT : CURSOR_NONE); } game->fpsPlayer->doResetMousePosition = !isHidden; } //If the callback function returns false no more callbacks will be executed and no event will be added to the event queue. //to avoid double call return false; } return true; } static bool MainMenuButtonCallback(const Event& ev, shared_ptr<Object> extra) { EmitEvent(EVENT_MAIN_MENU); return true; } static bool ExitButtonCallback(const Event& ev, shared_ptr<Object> extra) { exit(0); return true; } void Game::init(shared_ptr<Framebuffer> framebuffer, WString mapPath) { world = CreateWorld(); scene = LoadMap(world, mapPath); for (auto const& entity : scene->entities) { auto foundPlayer = entity->GetComponent<FPSPlayer>(); if (foundPlayer) { fpsPlayer = foundPlayer; break; } } auto font = LoadFont("Fonts/arial.ttf"); //Create user interface for game menu auto frameSize = framebuffer->GetSize(); ui = CreateInterface(world, font, frameSize); ui->SetRenderLayers(2); ui->root->SetColor(0.0f, 0.0f, 0.0f, 0.0f); uiCamera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); uiCamera->SetPosition(float(frameSize.x) * 0.5f, float(frameSize.y) * 0.5f, 0); uiCamera->SetRenderLayers(2); uiCamera->SetClearMode(CLEAR_DEPTH); //widgets are stays without extra shared pointers because parent widet, ui->root in this case, keep them //to remove widget you should do widget->SetParent(nullptr) menuPanel = CreatePanel(frameSize.width / 2 - 150, frameSize.height / 2 - 300 / 2, 300, 250, ui->root); gameSavedLabel = CreateLabel("GAME SAVED", frameSize.width / 2 - 100, 50, 200, 30, ui->root); gameSavedLabel->SetFontScale(2.0f); gameSavedLabel->SetHidden(true); auto menuButton = CreateButton("Main menu", 50, 50, 200, 50, menuPanel); ListenEvent(EVENT_WIDGETACTION, menuButton, MainMenuButtonCallback); auto exitButton = CreateButton("Exit", 50, 150, 200, 50, menuPanel); ListenEvent(EVENT_WIDGETACTION, exitButton, ExitButtonCallback, nullptr); //we don't need game menu on screen while playing menuPanel->SetHidden(true); //and we will need it once hitting Esc button ListenEvent(EVENT_KEYUP, nullptr, GameMenuButtonCallback, Self()); //take in mind that extra param will be kept as shared_ptr in callback ^ ListenEvent(EVENT_KEYUP, nullptr, QuickSaveGameCallback, Self()); } void Game::loadEntity(shared_ptr<Entity> entity, table entityTable) { if (entityTable["position"].is_array() && entityTable["position"].size() == 3) { entity->SetPosition(entityTable["position"][0], entityTable["position"][1], entityTable["position"][2], true); } if (entityTable["rotation"].is_array() && entityTable["rotation"].size() == 3) { entity->SetRotation(entityTable["rotation"][0], entityTable["rotation"][1], entityTable["rotation"][2], true); } if (entityTable["tags"].is_array()) { for (int i = 0; i < entityTable["tags"].size(); i++) { entity->AddTag(std::string(entityTable["tags"][i])); } } } void Game::loadGame(table saveTable) { //old-new entity id vector<std::pair<String, String>> uuids; std::set<String> newEntities; //entites that was not in scene will be deleted once Components will be loaded and gets needed entities std::set<shared_ptr<Entity>> entitiesToRemoveFromScene; //iterating std::map by key (uuid) and value (entityTable) instead of pair for (auto& [uuid, entityTable] : saveTable["SavedEntities"]) { auto entity = scene->GetEntity(uuid); //load properties for saved entity that was initially on map if (entity) { loadEntity(entity, entityTable); //or if it was not we can recreate prefab at least } else if (entityTable["prefabPath"].is_string()) { //spawn saved entity that was not initially on map auto spawnedEntity = LoadPrefab(world, String(entityTable["prefabPath"])); if (!spawnedEntity) { continue; } scene->AddEntity(spawnedEntity); if (entityTable["isInScene"].is_boolean() && !entityTable["isInScene"]) { entitiesToRemoveFromScene.insert(spawnedEntity); } loadEntity(spawnedEntity, entityTable); uuids.push_back(std::pair(uuid, spawnedEntity->GetUuid())); newEntities.insert(spawnedEntity->GetUuid()); } } //delete not saved entities for (auto const& entity : world->GetTaggedEntities("Save")) { //does newEntities containes curent entity if (newEntities.find(entity->GetUuid()) != newEntities.end()) { //skip new entity continue; } //if supposed to be saved and was not due being removed when save was made then remove it from scene table entityTable = saveTable["SavedEntities"][entity->GetUuid()]; if (entityTable.empty()) { scene->RemoveEntity(entity); } } //saving table++ as a string auto saveString = String(saveTable.to_json()); //replace entities ids so component would use new ones for (auto const& [oldUuid, newUuid] : uuids) { saveString = saveString.Replace(oldUuid, newUuid); } //converting back to table++ from string saveTable = ParseJson(saveString); //Load saved data to components for (auto const& entity : world->GetTaggedEntities("Save")) { auto& entityTable = saveTable["SavedEntities"][entity->GetUuid()]; for (auto const& component : entity->components) { component->Load(entityTable, nullptr, scene, LOAD_DEFAULT, nullptr); } } //starting components now when all data is there for (auto const& entity : world->GetTaggedEntities("Save")) { for (auto const& component : entity->components) { component->Start(); } } //removing from scene entites that scene had not for (auto const& entity : entitiesToRemoveFromScene) { scene->RemoveEntity(entity); } } void Game::saveGame(WString saveName) { table saveTable; //saving map path to use it later to load correct map saveTable["MapPath"] = RelativePath(scene->path).ToUtf8String(); saveTable["SavedEntities"] = {}; for (auto const& entity : world->GetTaggedEntities("Save")) { table entityTable; for (auto const& component : entity->components) { component->Save(entityTable, nullptr, scene, SAVE_DEFAULT, nullptr); } //just to make save file more readable if (!entity->name.empty()) { entityTable["name"] = entity->name.ToUtf8String(); } //saving position and rotation of entity to restore them in Load auto position = entity->GetPosition(true); entityTable["position"] = {}; entityTable["position"][0] = position.x; entityTable["position"][1] = position.y; entityTable["position"][2] = position.z; auto rotation = entity->GetRotation(true); entityTable["rotation"] = {}; entityTable["rotation"][0] = rotation.x; entityTable["rotation"][1] = rotation.y; entityTable["rotation"][2] = rotation.z; entityTable["tags"] = {}; //to remove it from scene later once everything restored inc case if only components supposed to keep this entity entityTable["isInScene"] = scene->GetEntity(entity->GetUuid()) ? true : false; int tagIndex = 0; for (auto& tag : entity->tags) { entityTable["tags"][tagIndex] = tag.ToUtf8String(); tagIndex++; } //save prefab path to be able restore entity if it was added to scene later as prefab auto prefab = entity->GetPrefab(); if (prefab) { entityTable["prefabPath"] = RelativePath(prefab->GetPath()).ToUtf8String(); } //using entity id as key for its properties saveTable["SavedEntities"][entity->GetUuid()] = entityTable; } SaveTable(saveTable, saveName); //showing "Game Saved" labl for 2 seconds gameSavedLabel->SetHidden(false); gameSavedLabelTimer = UltraEngine::CreateTimer(2000); ListenEvent(EVENT_TIMERTICK, gameSavedLabelTimer, HideGameSavedLabelCallback, Self()); } bool Game::QuickSaveGameCallback(const UltraEngine::Event& ev, shared_ptr<UltraEngine::Object> extra) { if (KEY_F5 == ev.data && extra) { auto game = extra->As<Game>(); game->saveGame("QuickSave.save"); } return true; } bool Game::HideGameSavedLabelCallback(const UltraEngine::Event& ev, shared_ptr<UltraEngine::Object> extra) { if (extra && extra->As<Game>()) { auto game = extra->As<Game>(); game->gameSavedLabel->SetHidden(true); game->gameSavedLabelTimer->Stop(); game->gameSavedLabelTimer = nullptr; } return false; } Game.zip Add new functions to main.cpp: void LoadGame(WString savePath) { table saveTable = LoadTable(savePath); if (saveTable == nullptr) { return; } menu.reset(); //to avoid random error in World::Update() game.reset(); loadingWorld->Render(framebuffer); if (currentWorld) currentWorld.reset(); if (currentUi) currentUi.reset(); game = Game::create(framebuffer, saveTable); currentWorld = game->world; currentUi = game->ui; } bool QuickLoadGameCallback(const Event& event, shared_ptr<Object> extra) { if (KEY_F9 == event.data) { LoadGame("QuickSave.save"); } return true; } And add ListenEvent next to other similar lines: ListenEvent(EVENT_KEYUP, nullptr, QuickLoadGameCallback); main.zip Now you can save and load game with F5 and F9 respectively Making Particle Effect Download this blood texture made by TobiasM: https://opengameart.org/content/blood-splat It's not optimal for particle emitter, but good enough for learning purpose. Put into Materials\Particles folder and convert to .dds in the Editor. Generate a material from dds texture. Add to any scene particle emitter: In Appearance tab of Particles choose a recently made material. Now we able to see result when we will change this material properties. Open material: 1. Choose Lambertian shader family - it has better perfomance than PBR and it can make a difference eventually with many particle emitters which produce dozens particles. 2. In Blend tab check Transparent checkbox. Now it particles would look like that: Open Particles tab of Particle Emitter in entity properties: 1. Particle count - how many particles of this emitter exist at same time, left it as 50 2. Emission shape - shape of area where particles will be spawn 3. Emission Area - size of this area (width, height, depth). If 0 then particles spawns at same point. Left it as 0. 4. Burst frequency - how often particles spawns. Will be 800 5. Burst count - how much particles spawns in every burst. Enter 50 6. Colors - how particle looks at spawn and despawn 7. Velocity - direction and speed - make it 0 8. Acceleration - same but it's accel 9. Size - width and height of particle. No depth, because every particle is just a billboard sprite. Makie it 0.2/0.2 10. Radius. First value - relative size (i.e. 1.0 is 100%) for particle at start and second value is size when particles despawns. Value - 1.0/1.0 11. Turbulence - random speed in random direction. With 0 velocity it will make particles move in different directions. Make it 300.0 12. Rotation speed - how fast particle rotate. Make it 0 Download ParticleEffect to ParticleEffect component to Components\Appearance folder. Include into project and add to ComponentSystem as usual. Add this component to an emitter. It's needed to make blood hit effect to dissapear before it would burst again. Temporary checkbox on and Duration 700. Name emitter as BloodHit and save it as prefab "BloodHit.phb" in Prefabs folder Let's use it for units. In Unit.cpp in Damage method add next code somewhere above auto now = world->GetTime(); auto bloodHit = LoadPrefab(world, "Prefabs/BloodHit.pfb"); auto entity = GetEntity(); if (bloodHit) { auto bloodHitPosition = entity->GetPosition(true); //to lift it up to entity center bloodHitPosition.y = bloodHitPosition.y + entity->GetBounds(BOUNDS_GLOBAL).size.height / 2; bloodHit->SetPosition(bloodHitPosition, true); //prefabs component are not started after its load so will do it manually for (auto const& component : bloodHit->components) { component->Start(); } } Making decal Copy blood_splat.dds texture to Materials\Decals folder. Generate a new material from it and name BloodPuddle. Edit this material: 1. Keep PBR as shader family. 2. In Blend tab check Transparent checkbox. 3. In Surface Metalness 0, and Roughness 50. Add new decal to scene - 256x256 size with 16 height (or 250x250 and 20) Choose new material in appearance. Save this decal as prefab wiht BloodPuddle name. We will spawn this decal after unit death. In Unit::Kill() method add above auto model = entity->As<Model>(); line following code: auto scene = sceneWeak.lock(); auto bloodPuddle = LoadPrefab(entity->GetWorld(), "Prefabs/BloodPuddle.pfb"); if (bloodPuddle && scene) { auto bloodHitPosition = entity->GetPosition(true); bloodPuddle->SetPosition(bloodHitPosition, true); //to keep it scene->AddEntity(bloodPuddle); } Pain sounds Download sounds for Warrok: https://opengameart.org/node/132772 And for Paladin: https://opengameart.org/content/pain-sounds-by-emopreben In Sounds folder create Units subfolder and put there bear_02.ogg from 1st pack and "Painsounds v2 - Track 5 - Urggh.ogg" from 2nd Add to properties in Unit.json: { "label": "Pain sound", "name": "painSound", "value": "", "filecategory": "SOUND" }, New member in Unit.h header: shared_ptr<Sound> painSound; In Load method in Unit.cpp will load attached in the Editor sound: if (properties["painSound"].is_string()) painSound = LoadSound(std::string(properties["painSound"])); And play this sound in Damage() above auto now = world->GetTime(); line: if (painSound) { entity->EmitSound(painSound); } Unit class: FinalUnit.zip Now open Paladin prefab and add their pain sound in Unit component. Same for Warror. Delete units from Strategy map and add them again from prefabs. Remember to break prefab after that. strategy.zip Cache In debug mode you could notice micro-freezes when prefabs are loaded every time when it's not at the map. Thats because unload from memory an assets that have no shared_pointer to them. We can fix by making cache in Game class. Add to Game.h new member: vector<shared_ptr<Entity>> prefabCache; And at the end of init method in Game.cpp: //caching prefabCache.push_back(LoadPrefab(world, "Prefabs/BloodPuddle.pfb")); prefabCache.push_back(LoadPrefab(world, "Prefabs/BloodHit.pfb")); prefabCache.push_back(LoadPrefab(world, "Prefabs/FlagWayPoint.pfb")); for (auto const& prefab : prefabCache) { if (prefab) { prefab->SetHidden(true); } } GameCache.zip Now Debug mode will be smoother since assets loaded on game load and not in run time when components uses them. In Release mode it would be also necessary to do for heavy assets. Final version on github: https://github.com/Dreikblack/CppTutorialProject/tree/4-save-load-particles-decals
  2. Steam, beta branch. In steam version music can be found in steam games path\Quake\rerelease\id1\music #include "UltraEngine.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { //Get the displays auto displays = GetDisplays(); //Create window auto window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0], WINDOW_TITLEBAR | WINDOW_CENTER); //Load sound auto sound = LoadSound("track02.ogg"); //Play sound auto speaker = CreateSpeaker(); speaker->SetSound(sound); speaker->SetLooping(true); speaker->Play(); while (window->Closed() == false) { if (window->KeyDown(KEY_ESCAPE)) break; } return 0; }
  3. Playing sounds simultaneously causes a crash when last sounds stop playing. Happens if world created and rendered. When i tried to do it with no world, only one sound played and no crash happened. Steam beta branch. Several months ago had no such problem. #include "UltraEngine.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 300, 300, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); //Create a world auto world = CreateWorld(); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Load FreeImage plugin auto sound = LoadSound("https://raw.githubusercontent.com/UltraEngine/Documentation/master/Assets/Sound/notification.wav"); int i = 0; //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { if (i < 10) { sound->Play(); i++; } world->Update(); world->Render(framebuffer); } return 0; }
  4. Hello. I thought about a physic property for materials where you would choose the kind of material (water, wood, concrete, grass, etc.). Then, from lists of sounds (i.e. walking sounds for the player kind of list), Leadwerk would play them randomly depending on what materials the player is interacting with and depending on the physic of the material. I don't know how complicated this would be to add. I know I could try to make a system like that by I think having it natively into Leadwerk would be a good point for Leadwerk. Thank you and have a nice day.
  5. Hi there team!! I have another programing/sintax question to answer... I want load and play a sound file by LUA pressing 3 keys on my keyboard (without using any PIVOT. Without using NOISE.LUA script. And without using the Flowgraph). Only executed from code of my MAIN.LUA on my project... I have write this, but i don't know if i need anything more, or the sintax is bad writen. The code doesn't give me any errors, but i can't ear anything: if window:KeyDown(Key.J) and window:KeyDown(Key.F) and window:KeyDown(Key.V) then local SonidoJFV = Sound:Load("Sound/MisSonidos/ValidarTICKET.wav") SonidoJFV.source=Source:Create() SonidoJFV.source:SetSound(sound) SonidoJFV.source:SetVolume(100) SonidoJFV.source:SetPitch(1) SonidoJFV.source:SetLoopMode(false) SonidoJFV.source:SetRange(900000) SonidoJFV.source:SetPosition(Vec3(0,0,0)) SonidoJFV.source:Play() --changemapname="1-Tutorial" end Any tip or answer that could help me? Thanks a lot!!
  6. Want to share this, for people needing sounds. Its a graphical programing environment for creating sound effects. It also has a library that can be linked and used from your program. Only downside i see is might take some time to learn lots of documentation. https://puredata.info/downloads/pure-data
  7. When i load a sound properly and that is existed, it will make an error indexing nil. It happens recently with all sounds, the noise script makes no noise also. I have replaced the path with an existing file (in the fpsplayer th footstep ) and also tried it with the noise.lua
  8. function Script:UpdatePhysics() Script.H=false Script.count = 100 ... if H == true then self.Stop() end end function Script:Stop()--in H=true local t = Time:GetCurrent() local bb = 500 if self.count[insert or modify code here] then if t == t+bb then bb=bb+t49 count = count -0.01 self.source:SetVolume(count) end else self:Disable() H=false end end This code is a modified noise script. This code doesnt work, I have a trigger at my map that uses Stop() with the flowgraph . So when I touch the trigger with the fpsplayer the pivot with this script attached the program crashes and says attemt to index local self ( a null value ) at the line marked. Is there an easyer way of just doing this without the timer that i didnt knew yet or does someone got a fix for this ?
  9. I have two questions regarding sound: 1. What are listeners? I can't find any documentation on what they actually are or are supposed to do. 2. Has anyone tried the firepit workshop item? It uses a source object in the code, but the farther you get away from it the volume stays the same and sounds the same no matter your position towards it (and there is no stereo effect, like if one ear is closer to the sound than the other, although this might not be implemented). I checked that it's a mono sound, so this behavior seems odd to me since the sound gets positioned at a certain point (so it should be 3D sound). Basically, it sounds like an ambient sound. What are 3D positioned sounds supposed to do?
  10. It would be nice to be able to click on sound icons to play a sound in the Assets tab in the editor.
  11. I've been following the Project Saturn Tutorials and got to the point with the barrels but I get the Error: Attempt to get Length of Field 'sound' (a nil value) How do I fix it. --[[------------------------------------------------------------------- This is a simple script to provide an impact sound for a physically interactive object. ]]--------------------------------------------------------------------- Script.soundfile1=""--path "Sound 1" "Wac file (*.wav):wav|Sound" Script.soundfile2=""--path "Sound 2" "Wac file (*.wav):wav|Sound" Script.soundfile3=""--path "Sound 3" "Wac file (*.wav):wav|Sound" Script.soundfile4=""--path "Sound 4" "Wac file (*.wav):wav|Sound" Script.threshhold=2--float "Threshhold" Script.maxfrequency=300--minimum delay between sound plays Script.range=20--float "Range" --Global values ImpactNoiseLastSoundTime=0-- This will be shared among all instances of this script and ensure we don't play too many sounds function Script:Start() self.sound={} for n=1,4 do local filepath = self["soundfile"..tostring(n)] if filepath~="" then local noise = Sound:Load(filepath) if noise~=nil then table.insert(self.sound,noise) --self.sound[#self.sound+1]=noise end end end end function Script:Collision(entity, position, normal, speed) if speed>self.threshhold then if #self.sound>0 then local collisiontype = entity:GetCollisionType() if collisiontype==Collision.Prop or collisiontype==Collision.Scene then local t = Time:GetCurrent() if t-ImpactNoiseLastSoundTime>self.maxfrequency then ImpactNoiseLastSoundTime=t local n=math.random(#self.sound) local noise = self.sound[n] self.entity:EmitSound(noise,self.range) end end end end end
  12. Hello, I would like to know more on how to exactly add sound into Leadwerks. As far as I know there is a lot of vague information when it comes to loading sound into a game in Leadwerks and I would like to know how to do so. What I want to know is how exactly do you load sounds into a map? Is there a way in which I can create say a pivot, attach a script that plays a sound for things such as music or ambience?
  13. Hi, When a source has finished playing it gets released every frame. This is a problem, if you want to find out, if it has finished playing, as you can't keep the source (even if you add n AddRefs() for the source, the source will be gone n frames after it finished playing). You can see this by adding a global static variable: [App.h add as class-member] static Source* src; [App.cpp] Source* App::src; [App.cpp: App::Start()] Sound* s = Sound::Load("Sound\\Footsteps\\jump.wav"); Entity* e = world->entities.front(); e->EmitSound(s); src = SoundDriver::GetCurrent()->sources.front(); src->AddRef(); src->AddRef(); src->AddRef(); src->AddRef(); [App.cpp: App::Loop()] printf("Time: %f, Refs: %i\n", src->GetTime(), src->GetRefCount()); Will lead to the following output: (...) Time: 0.074989, Refs: 5 (...) Time: 0.000000, Refs: 5 Time: 0.000000, Refs: 4 Time: 0.000000, Refs: 3 Time: 0.000000, Refs: 2 Time: 0.000000, Refs: 1 And an access violation after that, when accessing the GetTime()-method of the source. The expected behaviour would be, that the RefCount is decreased only once, so if I added Refs before, I have to release it myself. I even tried, setting "src->autorelease = false" but that didn't change anything.
  14. Doe anyone know if you can stop a looping Entity:EmitSound() method without releasing the entity, then start the sound again back in loop mode? It looks like EmitSound automatically creates a Source and the entity manages it. Is there some way to get reference to this Source to call Source:Stop()? EDIT: Nevermind, I'll just create and manage the Source manually.
  15. How do I stop the sound? I can not find any Stop(). Sound* sound; sound = Sound::Load(wav_file); sound->Play();
×
×
  • Create New...