Jump to content

reepblue

Developers
  • Posts

    2,483
  • Joined

  • Last visited

Everything posted by reepblue

  1. I better stop using Leadwerks then! just kidding...
  2. Fixing Filters 1) Filter's don't seem to be working for Visual Studio upon the release of 4.2. To fix, rename $PROJECT_NAME.filters to $PROJECT_NAME.vcxproj.filters. Fixing Debug working directory 2) Debugging from the IDE seems to not be working. To fix Go to Properties->Debugging and change the working directory from $(ProjectDir) to $(SolutionDir)..\..\ Very minor, but should be addressed. Thanks.
  3. Use this script instead. http://www.leadwerks.com/werkspace/topic/15382-volumetrigger-script/
  4. Ahh, recalling old forum posts, I thought the engine would just "magically" be able to read the contents.
  5. You can just use 7Zip to zip up each asset folder with a password. Tedious, but it should only be done post release and each update.
  6. I feel that way when Epic releases a patch for the new Unreal Tournament where minor bug fixes go to be a gig and a half big. On packaging, if you're not making a Game Launcher game, you should actually consider of ether hand packaging or making a batch or software that does the packaging for you the way you want. Just split the game's assets in password protected zip files and be done with it. A lot of thought should be taken into account before pushing a game on Steam.
  7. I tried using SDL2 and SDL2_mixer and the outcome was crackling audio. Really hope this gets added eventually. I'd only use ogg for music tracks, as I don't think there is a real point using ogg for simple sounds. 3-4 minute music tracks; yeah that can eat up a lot of space.
  8. Just to be clear, this isn't vegetation placed rocks, right? It might be an issue with imported collision meshes from the fbx. I noticed a few gotchas with this system, but most people use the model editor to build shapes.
  9. It would be nice to see scripted emitters and such be live, but I understand if that can't happen.
  10. Not mine, but in 4.2, there is a default trigger material.
  11. Regarding 1, it doesn't work because level transition is being handled via the template that I wrote during the 3.6 era. The template if I recall correctly doesn't allow quick window to fullscreen mode (It actually requires a restart) and fullscreen auto forces to the user's current monitor resolution.
  12. The fire pit prefab used a plane model with a script attached to it to make it face the player. This is because Sprites were not added to the engine until 3.3 I believe. If you set a sprite to the firepit's firs sprite material/shader, it should work. Just adjust the sprite settings.
  13. Still no dice. I got my custom Actor Class to work tho. There seems to be an issue with Detach. When CUSTOM_ACTOR is defined, everything works like expected. (Fully custom class based on hooks) vs the class derived from the stock Actor Class. Header: // Temp Actor class until the offical one gets improved. #if !defined(BASEACTOR_H) #define BASEACTOR_H #pragma once #include "Leadwerks.h" #define CUSTOM_ACTOR namespace Leadwerks { #ifdef CUSTOM_ACTOR class BaseActor : public Object { public: Entity* entity; BaseActor() {}; virtual ~BaseActor(); virtual void Attach(); void RemoveHooks(); virtual void Detach(); void Shutdown() { Detach(); }; virtual void Collision(Entity* pEntity, float* position, float* normal, float speed) {}; virtual void UpdateWorld() {}; virtual void UpdatePhysics() {}; virtual void UpdateMatrix() {}; virtual void PostRender(Context* context) {}; virtual void Draw() {}; virtual void DrawEach(Camera* camera) {}; protected: static void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed); static void DrawHook(Entity* entity); static void DrawEachHook(Entity* entity); static void PostRenderHook(Entity* entity); static void UpdateMatrixHook(Entity* entity); static void UpdatePhysicsHook(Entity* entity); static void UpdateWorldHook(Entity* entity); }; inline void AttachEntityToActor(Entity* entity, BaseActor* actor) { actor->entity = entity; actor->Attach(); } inline void DetachEntityFromActor(Entity* entity) { if (entity->GetUserData() != NULL) { BaseActor* actor = (BaseActor*)entity->GetUserData(); actor->RemoveHooks(); delete actor; } } bool DetachAllActors(); #else class BaseActor : public Actor { public: BaseActor(); virtual ~BaseActor(); virtual void Attach(); virtual void Detach(); void AddHooks(); void RemoveHooks(); // Hooks that are not working with actors in 4.2 virtual void UpdateWorld() {}; virtual void UpdatePhysics() {}; virtual void PostRender(Leadwerks::Context* context) {}; protected: static void PostRenderHook(Entity* entity); static void UpdatePhysicsHook(Entity* entity); static void UpdateWorldHook(Entity* entity); }; #endif } #endif CPP: // Temp Actor class until the offical one gets improved. #include "BaseActor.h" std::vector<Leadwerks::BaseActor*> vActors; namespace Leadwerks { #ifdef CUSTOM_ACTOR bool DetachAllActors() { if (vActors.size() <= 0) return false; // Come back to this later... for (auto actor : vActors) { actor->Shutdown(); } vActors.clear(); return true; } void BaseActor::Attach() { if (entity == nullptr) { return; } entity->SetUserData((void*)this); entity->AddHook(Entity::CollisionHook, (void*)CollisionHook); entity->AddHook(Entity::DrawHook, (void*)DrawHook); entity->AddHook(Entity::DrawEachHook, (void*)DrawEachHook); entity->AddHook(Entity::PostRenderHook, (void*)PostRenderHook); entity->AddHook(Entity::UpdateMatrixHook, (void*)UpdateMatrixHook); entity->AddHook(Entity::UpdatePhysicsHook, (void*)UpdatePhysicsHook); entity->AddHook(Entity::UpdateWorldHook, (void*)UpdateWorldHook); vActors.push_back((BaseActor*)this); } void BaseActor::RemoveHooks() { if (entity == nullptr) { return; } entity->RemoveHook(Entity::CollisionHook, (void*)CollisionHook); entity->RemoveHook(Entity::DrawHook, (void*)DrawHook); entity->RemoveHook(Entity::DrawEachHook, (void*)DrawEachHook); entity->RemoveHook(Entity::PostRenderHook, (void*)PostRenderHook); entity->RemoveHook(Entity::UpdateMatrixHook, (void*)UpdateMatrixHook); entity->RemoveHook(Entity::UpdatePhysicsHook, (void*)UpdatePhysicsHook); entity->RemoveHook(Entity::UpdateWorldHook, (void*)UpdateWorldHook); entity->SetUserData(NULL); } BaseActor::~BaseActor() { //RemoveHooks(); } void BaseActor::Detach() { System::Print("Puppeteer: Detach() was called."); RemoveHooks(); delete this; } void BaseActor::CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed) { BaseActor* actor = (BaseActor*)entity0->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { actor->Collision(entity1, position, normal, speed); } } void BaseActor::DrawHook(Entity* entity) { BaseActor* actor = (BaseActor*)entity->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { //actor->Draw(WORLD->); } } void BaseActor::DrawEachHook(Entity* entity) { BaseActor* actor = (BaseActor*)entity->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { //actor->DrawEach(); } } void BaseActor::PostRenderHook(Entity* entity) { BaseActor* actor = (BaseActor*)entity->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { actor->PostRender(Leadwerks::Context::GetCurrent()); } } void BaseActor::UpdateMatrixHook(Entity* entity) { BaseActor* actor = (BaseActor*)entity->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { actor->UpdateMatrix(); } } void BaseActor::UpdatePhysicsHook(Entity* entity) { BaseActor* actor = (BaseActor*)entity->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { actor->UpdatePhysics(); } } void BaseActor::UpdateWorldHook(Entity* entity) { BaseActor* actor = (BaseActor*)entity->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { actor->UpdateWorld(); } } #else BaseActor::BaseActor() : Actor() {}; BaseActor::~BaseActor() {}; void BaseActor::Attach() { AddHooks(); } void BaseActor::Detach() { RemoveHooks(); } void BaseActor::AddHooks() { entity->AddHook(Entity::PostRenderHook, (void*)PostRenderHook); entity->AddHook(Entity::UpdatePhysicsHook, (void*)UpdatePhysicsHook); entity->AddHook(Entity::UpdateWorldHook, (void*)UpdateWorldHook); } void BaseActor::RemoveHooks() { entity->RemoveHook(Entity::PostRenderHook, (void*)PostRenderHook); entity->RemoveHook(Entity::UpdatePhysicsHook, (void*)UpdatePhysicsHook); entity->RemoveHook(Entity::UpdateWorldHook, (void*)UpdateWorldHook); } void BaseActor::PostRenderHook(Entity* entity) { BaseActor* script = (BaseActor*)entity->GetUserData(); Leadwerks::Context* context = Leadwerks::Context::GetCurrent(); if (script != nullptr) { script->PostRender(context); } } void BaseActor::UpdatePhysicsHook(Entity* entity) { BaseActor* script = (BaseActor*)entity->GetActor(); if (script != nullptr) { script->UpdatePhysics(); } } void BaseActor::UpdateWorldHook(Entity* entity) { BaseActor* script = (BaseActor*)entity->GetActor(); if (script != nullptr) { script->UpdateWorld(); } } #endif } Only gotcha with mine is that I need to call this command before clearing/releasing the world. Leadwerks::DetachAllActors();
  14. Seem to be getting crashes when I clear the world. I thought it was because the hooks were not being detached before the actor was, but I disabled my additional hooks and I'm getting the same crash.
  15. I just put it together; can't say I tested it, but this chunk of code is how my Puppeteer class worked. This class derives from the actor class so that the update and post render functions update. BaseActor.h // Temp Actor class until the offical one gets improved. #if !defined(BASEACTOR_H) #define BASEACTOR_H #pragma once #include "Leadwerks.h" namespace Leadwerks { class BaseActor : public Actor { BaseActor(); virtual ~BaseActor(); virtual void Attach(); virtual void Detach(); // Hooks that are not working with actors in 4.2 virtual void UpdateWorld() {}; virtual void UpdatePhysics() {}; virtual void PostRender(Leadwerks::Context* context) {}; protected: static void PostRenderHook(Entity* entity); static void UpdatePhysicsHook(Entity* entity); static void UpdateWorldHook(Entity* entity); }; } #endif BaseActor.cpp // Temp Actor class until the offical one gets improved. #include "BaseActor.h" namespace Leadwerks { BaseActor::BaseActor() : Actor() {}; BaseActor::~BaseActor(){}; void BaseActor::Attach() { Actor::Attach(); entity->AddHook(Entity::PostRenderHook, (void*)PostRenderHook); entity->AddHook(Entity::UpdatePhysicsHook, (void*)UpdatePhysicsHook); entity->AddHook(Entity::UpdateWorldHook, (void*)UpdateWorldHook); } void BaseActor::Detach() { entity->RemoveHook(Entity::PostRenderHook, (void*)PostRenderHook); entity->RemoveHook(Entity::UpdatePhysicsHook, (void*)UpdatePhysicsHook); entity->RemoveHook(Entity::UpdateWorldHook, (void*)UpdateWorldHook); Actor::Detach(); } void BaseActor::PostRenderHook(Entity* entity) { BaseActor* script = (BaseActor*)entity->GetUserData(); Leadwerks::Context* context = Leadwerks::Context::GetCurrent(); if (script != nullptr) { script->PostRender(context); } } void BaseActor::UpdatePhysicsHook(Entity* entity) { BaseActor* script = (BaseActor*)entity->GetUserData(); if (script != nullptr) { script->UpdatePhysics(); } } void BaseActor::UpdateWorldHook(Entity* entity) { BaseActor* script = (BaseActor*)entity->GetUserData(); if (script != nullptr) { script->UpdateWorld(); } } } You may need to static cast your Actors based off this when you go to attach the actor to the entity with Entity->SetActor().
  16. It also seems selected objects still pop up in there as well! (Redness)
  17. I expected Editor Hints would get skipped, but they don't.
  18. reepblue

    Anatomy of a Bug

    Really happy to see this bug fixed. Great work!
  19. Just want to mention that Einlander's script is collision based, and mine is aabb based. The difference is that if you wish props to enter with swept collision enabled, the object will collide into the trigger like it's a wall ignoring any collision rules. I haven't tried Einlander's but I'm sure it's also useful. Pretty much, mine mimics Source's BaseTrigger class, and Einlander mimics Unity's. Use whatever works best for you.
  20. I like to post on the forum so if any users who wish to do the same thing, can find it with the search engine. I'm gonna pack all my scripts up in one big chunk when they are fully tested and ironed out.
  21. I forgot IsAABBOverlap.lua. Place in the functions directory. -- Thanks to CrazyCarpet for this snippet! function IsAABBOverlap(hostent, testent, usesizetest) if hostent == nil then return false end if usesizetest == nil then usesizetest = false end if usesizetest then local aabb = hostent:GetAABB(Entity.GlobalAABB) local eaabb = testent:GetAABB(Entity.GlobalAABB) if (eaabb.min.x > aabb.max.x) or (aabb.min.x > eaabb.max.x) then return false end if (eaabb.min.y > aabb.max.y) or (aabb.min.y > eaabb.max.y) then return false end if (eaabb.min.z > aabb.max.z) or (aabb.min.z > eaabb.max.z) then return false end return true else local aabb = hostent:GetAABB(Entity.GlobalAABB) local pos = testent:GetPosition(true) if pos.x < aabb.min.x then return false end if pos.y < aabb.min.y then return false end if pos.z < aabb.min.z then return false end if pos.x > aabb.max.x then return false end if pos.y > aabb.max.y then return false end if pos.z > aabb.max.z then return false end return true end return false end
  22. Unlike CollisionTrigger, VolumeTrigger does it's work by it's entity's aabb radius being called on the UpdatePhysics thread. VolumeTrigger also keeps track of what objects are in the volume, and entities with swept collision can enter the volume because it doesn't use shapes for triggering. --[[ This script will make any entity act as a volume trigger. Having a trigger be AABB tests rather than collision has it's perks as it's easier to keep track of what entities are in the volume. Also, objects with swept collision can now activate triggers! ----NOTES---- filter <entity> = Use this feild if you wish to have a specific entity trigger outputs. enabled <bool> = Toggle the trigger on and off onlyonce <bool> = When true, the trigger deactivate forever when triggered the first time. sizetest <bool> = When true, the overlap test will preform a aabb radius on both the trigger and entity in question. If false, only the entity's position will be tested. Make this true if you want a true collision like trigger. allowcharacters <bool> = Toggles if characters can activate. allowprops <bool> = Toggles if props can activate. allowdebri <bool> = Toggles if debris can activate. allowprojectiles <bool> = Toggles if projectiles can activate. ]]-- import "Scripts/Functions/IsAABBOverlap.lua" Script.filter=nil--entity "Filter" Script.enabled=true--bool "Enabled" Script.onlyonce=false --bool "Only Once" Script.sizetest=false --bool "Size Test" -- These values will get ignored if there is no filter. Script.allowcharacters=true --bool "Allow Characters" Script.allowprops=true --bool "Allow Props" Script.allowdebris=true --bool "Allow Debris" Script.allowprojectiles=true --bool "Allow Projectiles" function TriggerForEachEntityInAABBDoCallback(entity,extra) local volumeent = extra local filterent = volumeent.script.filter -- Always skip these! if entity == volumeent then return end if entity:GetClass() == Object.PivotClass then return end if entity:GetClass() == Object.BoneClass then return end if entity:GetClass() == Object.DirectionalLightClass then return end if entity:GetClass() == Object.SpotLightClass then return end if entity:GetClass() == Object.PointLightClass then return end if entity:GetClass() == Object.ListenerClass then return end if entity:GetClass() == Object.ProbeClass then return end -- Don't count static brushes! if entity:GetCollisionType() == Collision.Scene then if entity:GetMass() <= 0 then return end end -- If we're not looking for a specific entity, filter by collision types. if filterent == nil then if entity:GetCollisionType() == Collision.None then return end if entity:GetCollisionType() == Collision.Character and not volumeent.script.allowcharacters then return end if entity:GetCollisionType() == Collision.Prop and not volumeent.script.allowprops then return end if entity:GetCollisionType() == Collision.Debris and not volumeent.script.allowdebris then return end if entity:GetCollisionType() == Collision.Projectile and not volumeent.script.allowprojectiles then return end if IsAABBOverlap(volumeent,entity,volumeent.script.sizetest) == true then volumeent.script:onstartTouch(entity) end elseif entity == filterent then if IsAABBOverlap(volumeent,filterent,volumeent.script.sizetest) == true then volumeent.script:onstartTouch(entity) end end end function Script:SearchForEntites() self.entity.world:ForEachEntityInAABBDo(self.entity:GetAABB(Entity.GlobalAABB),"TriggerForEachEntityInAABBDoCallback",self.entity) end function Script:IsAlreadyTouching(entity) local key,value for key,value in pairs(self.touchingents) do if value == entity then return true end end return false end function Script:Start() self.touchingents={} self.triggered=false -- Disable Shadows self.entity:SetShadowMode(0) -- Ignore all picking. self.entity:SetPickMode(0) -- Automaticly fix the Physics self.entity:SetCollisionType(Collision.None) self.entity:SetMass(0) self.entity:SetKeyValue("type", "trigger") self.entity:SetViewRange(Entity.NearViewRange) end function Script:UpdatePhysics() if not self.enabled then return end if onlyonce and self.triggered then return end self:SearchForEntites() if table.getn(self.touchingents) > 0 then local key,value for key,value in pairs(self.touchingents) do local zentity = value if zentity ~= nil then if IsAABBOverlap(self.entity,zentity,self.sizetest) == false then self:onendTouch(key, zentity) break end end end end end function Script:onstartTouch(entity) if self:IsAlreadyTouching(entity) == false then if table.getn(self.touchingents) == 0 then -- If it's the first item, call a special function. self.component:CallOutputs("onstartTouchAll") self.component:CallOutputs("onstartTouch") else self.component:CallOutputs("onstartTouch") end table.insert(self.touchingents, entity) self.triggered=true --System:Print("Added " ..entity:GetKeyValue("name") .. " to list") end end function Script:onendTouch(key, entity) if table.getn(self.touchingents) < 0 then return end if table.getn(self.touchingents) == 1 then -- If it's the last item, call a special function. self.component:CallOutputs("onendTouchAll") self.component:CallOutputs("onendTouch") else self.component:CallOutputs("onendTouch") end --System:Print("Removing " ..entity:GetKeyValue("name") .. " from list") table.remove(self.touchingents, key) end
×
×
  • Create New...