v

VENCIOUS
BACK


 Dynamic RayCast System v1.73.2

 

This is colliders free system which uses custom Ray and SphereCast functions to detect objects. It supports Skinned and Rigid(Non Skinned) meshes.

 

        Features

 

  • RayCast and RayCastAll against triangular meshes
  • SphereCast ans SphereCastAll against triangular meshes - useful for simulating (projectiles)
  • OverlapSphere - test against bounds and triangular meshes
  • OverlapBox - test against bounds and triangular meshes
  • Object types: Skinned, Rigid (Non Skinned)
  • Custom LOD Meshes - use them for intersection at distance. This can help greatly improves performance
  • Swap LOD meshes at runtime. This will force the simpler meshes to be rendered at distance
  • Temporarily exclude objects from the system
  • Adding components at runtime
  • Get the closest bone to a hit point - This way you can attach some objects to that bone transform
  • Stick objects to the hit point on Skinned Meshes - Every frame a new position is calculated
  • Mesh Grouping Tool - select and group triangles by tags, i.e. define character's head with tag "head"
  • Rich “DRCHitInfo” class filled with information about any intersected object

 

   * GameObject  hitObject;

   * Renderer       hitObjectRenderer;

   * Transform      shapeTransform;

   * Vector3          hitPoint;

   * Vector3          hitNormal;

   * float               hitDistance;

   * Vector3          barycentricCoordinate;

   * Vector2          textureCoordinates;

   * int                  triangleIndex;

   * string             drcTag;

   * ObjectType    hitObjectType;

   * DRCM             drcmObject;

 

 

NOTE : The triangle tag buffers are specified by LOD level and are not initialized initially. if the Mesh Grouping Tool is used specifically for initializing and updating them, The "default" tag is filled in the DRCHitInfo structure in case the buffers are empty.

 

__________________________________________________________________________________________________________________

 

v 1.73.2

__________________________________________________________________________________________________________________

 

New Features and improvements

 

  • Custom LOD support - use meshes with lower verts count for intersection in distance
  • A "Swap LOD Meshes" option - will swap the meshes at runtime. This way the engine uses the simple meshes to render in distance

 

__________________________________________________________________________________________________________________

 

v 1.60

__________________________________________________________________________________________________________________

 

New Features and improvements

 

  • Now the Multi-Threading is moved to the DRCS script as a global option and all the objects are distributed to different cores. No more MT per object is used!

 

NOTE: MultiThreading currently uses the integrated ThreadPool in .NET 2

NOTE: Consumes more memory because of the synchronization but not that much

NOTE: MultiThreading will probably change in future when Dot Net version is updated.

NOTE: Currently only Windows, Mac, Android and iOS are supported because are the only tested platforms.

            You can add more platforms. It is described below.

  • Added OverlapBox method - simulates an oriented box in spaces which collects all the DRCM objects within its volume. It can be used to test objects by bounds only or by testing mesh triangles.
  • OverlapSphere method now can test objects against their meshes as well (previously was working only with bounds)
  • Further code cleanup and small optimizations

 

Changes

 

  • MONO.Simd plugins is now completely removed (it was used before with the MehsGroupingTool)
  • The KD-Tree is removed from SRCMesh objects and it's only used with MeshGroupingTool
  • DRCShape script is removed

 

Limitations

 

  • If you want to stick an object to a mesh which uses blendshapes, the sticking point will not take into account the blend shapes.

 

 

__________________________________________________________________________________________________________________

 

System Components Overview

__________________________________________________________________________________________________________________

 

The “Dynamic RayCast System” - (or DRCS in short) is a COLLIDER FREE system which is capable of testing a mesh for intersection with rays and swept spheres ( capsules ). For the purpose it uses custom RayCast and SphereCast functions. Simply said it can be used in case you want to simulate weapon shooting or in other cases where you need to test a mesh for intersection and get accurate results. All the objects that are part of the system are tested by calling any of the DRCS methods and if you have an object that was intersected, true is returned and a structure with some useful information about the intersection is filled. As probably became clear, what the system does is pretty similar to using Unity's "Physics.RayCast() and Physics.SphereCast()" functions, but there are two main differences:

 

  • You don’t need to use colliders
  • You get precision

 

How it works internally?

 

__________________________________________________________________________________________________________________

 

1. DRCS - This is the main manager and it should be placed in a scene in order to have working system. It contains a list with all of the system objects and manages them. All of the detection function are used through this manager.

__________________________________________________________________________________________________________________

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

DRCS.RayCast() – It actually calls internally DRCS.RayCastAll() function, which returns sorted by distance list of type DRCHitInfo with all the intersected objects. It then returns true and fills an instance of the DRCHitInfo class with information about the first(closest) object in the list.  For every RayCast, the system does also a Physics.RayCast() which uses the “mask” variable exposed in the manager's inspector - this is explained below. If the Physics.RayCast() has detected some collider, then all the objects from the system which are intersected are compared with that collider by distance and are stored in the list only if they are closer than the collider object. The Physics.RayCast() is needed of course to detect obstacles (colliders).

 

DRCS.RayCastAll() – Does also a Physics.RayCast() before the DRCS.RayCastAll() itself. If there is intersection with some collider too, then all the objects are compared by distance with the collider object and if they are closer to the player(camera etc.), the system stores them in a temp array, and also adds the collider at the end of the array. Let’s say if we did intersected 3 enemies and the wall behind them, we can then instantiate blood particle system at the hit points on the enemies and then instantiate some other particle system at the hit point on the wall. The wall as said will be the last object in the array. The information about the collider intersected is filled in the same DRCHitInfo structure, but only some fields are filled - objectType set to “Collider”, hitObject - the collider.gameObject, hitPoint, hitNormal and distance.

 

DRCS.SphereCast() – This actually is a Swept-Sphere(Capsule) which is moving in space. The same as Unity’s Physics.SphereCast() function. It requires old and current positions as well as sphere radius and DRCHitInfo reference. It does not use the “mask” field from the system as in the current version Physics.SphereCast() is not used internally to check for colliders closer to the projectile as with the Raycasting. If you want the projectiles to be able to detect colliders while flying, simply add sphere or capsule collider as well as rigidbody components, or add Physics.SphereCast() function to your custom Projectile script.

 

  • NOTE: The projectile behavior is meant to be designed by the developers, as it will be better if everyone could decide how to manage it - where and how fast to move, to whether explode or not when detects an object, plus adding Physics.SphereCast() funciton to be able to detect more precisely colliders etc... The Projectile script in the project shows a way of how to manage projectiles.

 

DRCS.OverlapSphere() - Simulates the spawning of invisible sphere in scene in order to detect if there are some Skinned and Rigid object in it's volume by testing against their bounding boxes only or by testing the triangular meshes of the objects.

 

DRCS.OverlapBox() - Simulates the spawning of invisible box which is set at some rotation (defines by users) sphere in scene in order to detect if there are some Skinned and Rigid object in it's volume by testing against their bounding boxes only or by testing the triangular meshes of the objects.

 

 

__________________________________________________________________________________________________________________

 

2. DRCM - The base class for both DRCMesh and SRCMesh objects!

__________________________________________________________________________________________________________________

 

3. DRCMesh - "Dynamic RayCast Mesh" - use this with Skinned objects.

__________________________________________________________________________________________________________________

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • Exclude From System – when true, the object will not be tested for intersection and vice versa.
  • Uses Blend Shaped - In order to detect Skinned objects which are using BlendShapes properly when scaled, a new option is added temporarily to the DRCMesh components. This is needed because of a bug in the engine (which is reported and is in process of fixing by Unity). Enable if your objects has BlendShapes.
  • AABB Test - enable/disable the initial AABB test. Disable only in case you are forced to test an object and you don't care about the AABB.
  • DRCGourpID - select objects of similar type, give them the same id (string name) to group them logically and use the new DRCS.RayCast(... List<string> groupIDs) overridden method which uses a list of strings with the groups ids you want in order to raycast against these groups only. The list could contain only one string if you want to only raycast against a single group.
    NOTE: string ids are managed by developers.
  • Skinned Mesh Renderer - load the SkinnedMeshRenderer from the hierarchy.
  • Root Transform – the idea is to load the object on which you have attached most of the important scripts controlling the object. This way you can have faster access to it.
  • Transform once per frame - this option does not allow the mesh to be transformed multiple time per frame. This means no matter how many sources invoke RayCast(), the mesh will be transformed only the first time the system calls the method in a given frame. Other advantage of this options is that you can now make a loop with RayCast calls instead of using the RayCast with an array of rays.
    NOTE: if you want to intersect an object, then move it somewhere in space and test it again in a single frame, this option will not allow you doing it. You will need to disable it.
  • What to transform - Ray or Mesh. Every time we need to test an object for intersection, the system has to transform (bake) the mesh. In other words it makes a snapshot of the current pose of an animated object. For that purpose, a Unity's mesh baking function is used. What that function does is to bake the object to the current pose but leaves it's scale to the original scale, leaves the vertices in the center of the scene and orientates it towards the forward direction. So here you have the options to use the "mesh transform" option after the mesh baking which further transforms the vertices so the newly created snapshot looks exactly the way the object looks in the viewport (including position, rotation and scale). This takes some time. The second and recommended option is to leave the snapshot object in the center of the scene and to just transform the ray's position and direction in a way that will be able to detect the object properly in case it is left in the center of the viewport. All of this happens internally and is not visualized.
    NOTE: in feature updates the "Ray" transforming could be the only option available.
  • Edit Tags button - opens the MeshGroupingTool to edit tags

 

  • LODs are explained below

__________________________________________________________________________________________________________________

 

4. SRCMesh -"Static RayCast Mesh" - add this to Rigid(Non Skinned) objects, which have "MeshFilter" and "MeshRenderer" components attached

__________________________________________________________________________________________________________________

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • Exclude From System – when true, the object will not be tested for intersection and vice versa.
  • AABB Test - enable/disable the initial AABB test. Disable only in case you are forced to test an object and you don't care about the AABB.
  • DRCGourpID - select objects of similar type, give them the same id (string name) to group them logically and use the new DRCS.RayCast(... List<string> groupIDs) overridden method which uses a list of strings with the groups ids you want in order to raycast against these groups only. The list could contain only one string if you want to only raycast against a single group.
    NOTE: string ids are managed by developers.
  • Mesh Renderer – load the object’s MeshRenderer component.
  • Root Transform – the idea is to load the object on which you have attached most of the important scripts controlling the object. This way you can have faster access to it.
    NOTE:  the Rigid objects always use "Ray" transformation and are not transformed in any way. That makes them faster to test for intersection compared to Skinned objects
    NOTE: in v1.31 there was an option to set rigid objects to static or dynamic. This option is now removed and all of the objects are dynamic as the performance is the same and the component become much simpler.

 

  • LODs are explained below

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

5. DRCLOD – contains the LOD functionality. This is used internally.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

LOD variables

  • swapLODMeshes - If this toggle is enabled, the meshes loaded into LOD slots will be used to replace the one that the MeshFilter is using. The effect is that you will get different meshes visible in the scene based on the culling distance and current active LOD level!"

  • lowestLODWhenCulled - This option will force the culling group to use the lowest LOD level if the object is culled ( when not visible to the culling camera, e.g. behind the player in a FPS shooter game or in case player is looking down or up ).  The point is that originally if the object is behind the culling camera it still might use the highest LOD level if it's close enough.  Where this helps !? DRCS provides OverlapBox and OverlapSphere methods which can use the BBOX or the mesh for intersection tests. In case you use the mesh for intersection with these methods and not the BBOX you will probably want to use the lowest LOD. This is kind of optimization  which might not be that useful in every case. But having it enabled is not a bad idea !

 

Some notes about LODs

 

  • You set up the LODs in the inspector. The first LOD level always uses the original mesh which is initially loaded in the SkinnedMeshRenderer or the MeshFilter components. Is just cached internally. You can add and remove additional LOD levels! You will have to load the mesh that will be used in the mesh field and give it a distance. Every next LOD should have a distance greater than the previous!

  • You can toggle the swapLODMeshes option in order to have the LOD meshes swapped at runtime. This is useful if you have  some more meshes visible at a time. It will be a bit more optimal while the Skinned Mesh Renderer will have to skin the simplified meshes in distance.

  • In case you do not want to use the original mesh as LOD0 you always can load another simplified mesh to the LOD0 slot to be used for intersection tests.
    NOTE : "swapLODMeshes" option is not recommended in this case because the object will use only the other LOD meshes for visualization and the original mesh is not part of the LODs anymore.
    NOTE : when you toggle LODs the original mesh is referenced internally and is restored to the MeshFilter/SkinnedMeshRenderer if you disable the LODs or remove the component.

  • If you add some of the components at runtime you have to call the DRCM.Initialize() methods and provide a list of meshes and and distances. Be sure they are equal in size - 3 meshes 3 distances...

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

6. DRCSticker – this is a class which shows how to implement such functionality which can stick an objects to the same position of deformed by animation triangle mesh.

 

NOTE : this only works in case the mesh bones are available to the system, so if optimize bone hierarchy option in the skinned mesh is enabled, you will no be able to stick objects to the mesh as there is no way to calculate the sticking position.

NOTE: unfortunately blend shapes are not taken into account.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

7. MeshGrouping folder contains the "MeshGroupinTool" which is explained below.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

8. DRCU – Custom stuff – don’t need to check it.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

FAQs

 

Q: Do i have to use triangle tags ?

A: No the lists with tags are initialized and specified by wish in editor only using the "Mesh Grouping Tool"

 

Q: Skinned meshes using blend shapes are not intersected properly. Why is this happening ?

A: One option is because you did not enable the option "usesBlendShapes" in the "DRCMesh" component's inspector. It is important to do in order to have proper intersection currently! This has to do with a bug inside Unity !

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

System Setup

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

There are a few steps you need to complete in order to have the system setup properly:

 

1. Create an empty game object in the scene and add the "DRCS" script as component. It has one field called “mask”. To set this up properly, you have to include only the layers with objects that have Unity’s colliders attached. Why is that? Let’s say your enemies have single capsule collider to block the player, then the Physics.RayCast() function which is called as well internally will detect them. So put all the objects part of the system in custom layers and exclude them from the mask.

 

2. Choose a Character model which has a SkinnedMeshRenderer component attached and add a "DRCMesh" script on it. It is good idea to add it to the root of the object. In general the system was designed to work especially with Skinned objects. These objects have the "objectType" parameter set to "ObjectType.SkinnedMesh". As addition if you need, you can add in the scene some objects that are not skinned but rather have MeshFilter and MeshRenderer components attached. These objects have to have the SRCMesh component attached. They work as the DRCMesh objects but have "objectType" set to "ObjectType.RigidMesh".

3. The last thing you have to do is to write a script to implement the Ray and Sphere casting. There is a "Sniper" script part of the player, included in the project (there are a couple more scripts which implement a raycast functionality included in the project) The RayCasting is implemented in that script. It has a reference to the BulletProjectile prefab which shows how to implement projectiles using DRCS.SphereCast() function. For the RayCasting itself we have to do a few things: - to create a ray, to call a DRCS.RayCast() function to test the objects and lastly to do something we want with the object or objects that was hit. The same is with the DRCS.SphereCast() function. I say object or objects because there are two functions we can use. The first one is "DRCM.RayCast()" that returns the closest hit object if there is one and the second function is "DRCM.RayCastAll()" that returns an array with all the objects that are intersected. This is the same as with the Unity's Physics.RayCast() and Physics.RayCastAll() methods. The DRCS.SphereCast() function always returns an array of type “DRCM” with all intersected objects. Usually only one or two get intersected. It depends on the projectile speed. All of these static functions are of type "bool". The DRCS.RayCast() function has a parameter called ignoreColliders (think of it like "go through walls"). Set to true when you want to be able to shoot rays that go through the objects with colliders e.g. having a heavy weapon that it’s able to blow a wall and the bullets pass through it.

4. There is support for adding both DRCMesh and SRCMesh at rum time. The way of doing it is by invoking the Initialize() method with the appropriate parameters for both Skinned and Rigid meshes:

 gameObject.AddComponent<DRCMesh>().Initialize(parameters…);

 gameObject.AddComponent<SRCMesh>().Initialize(parameters…);

 

NOTE: In case you need to change any parameter just get the DRCM component right after adding it and do the changes you need.

For example: GetComponent<DRCM>().excludeFromSystem = true; - this will exclude the object from the intersection testing routine.

 

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Mesh Grouping Tool

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

This is a tool which can apply tags to triangles. It allows you to logically group a mesh. Check the color mesh and compare the mesh to the tags list by looking at the corresponding colors

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Works with Skinned and Rigid objects. Since v 1.73 the triangle tag lists should be initialized by using that tool. Initially the lists are empty and every triangle just points to the "default" tag. Now when you open the tool to edit an object which is using LODs, you will be given the option to choose which LOD you want to create tags for. The tag lists are of type "int". The actual name of the tag however is filled in the DRCHitInfo structure. So in case you get a tag list and try to read it, it will give integers and not strings. There is a method in the DRCS manager which can convert an int to a string tag. As you can see in the image above, the tags list has int ids and corresponding name.

 

 

 

IMPORTANT NOTES:

 

NOTES:

 

  • THE TOOL DOES NOT SUPPORT "UNDO/REDO".
  • SOMETIMES A STRANGE BEHAVIOR WHEN SELECTING TRIANGLES IS NOTICES. THAT'S WHY WILL NEED TO BEGIN A NEW SELECTION IF MESSED UP, WHILE "UNDO" FUNCTIONALITY IS NOT YET AVAILABLE
  • THE "default" AND "ignore" TAGS SHOULD ALWAYS BE AVAILABLE
  • IF YOU SET SOME TRIANGLES TO USE THE "ignore" TAG, THEY WILL BE IGNORED BY THE SYSTEM WHEN "RayCast()" OR "SphereCast()" AGAINST THEM. THIS IS SOME KIND OF OPTIMIZATION. EVEN THOUGH THE TRIANGLES WILL  ALWAYS BE TRANSFORMED THEY WILL NOT BE DETECTED WHICH SAVES SOME CPU CYCLES
  • IF AN OBJECT USES "LODs" YOU WILL BE PROMPT TO CHOSE THE ONE YOU WANT TO SETUP
  • THE "MESH GROUPING TOOL" USES A FILE CALLED "DRCSTags". THE FILE IS LOCATED AT THE "Dynamic RayCast System\DRCS\Resources\Editor" FOLDER. IT IS RECOMMENDED TO KEEP IT THERE, EVEN THOUGH THE TOOL WILL STILL WORK IF THE FILE IS NOT IN THAT FOLDER. IF YOU ACCIDENTALLY DELETE THE FILE YOU CAN RECREATE IT BY OPEN THE "DRCS\Create DRCSTags Asset" MENU. IT WILL DETECT IF THE FILE EXISTS AND IF IT EXISTS, IT WILL ASK YOU TO OVERRIDE IT. IF YOU DO SO WILL LOSE THE OLD LIST WITH TAGS OTHERWISE IF THE FILE IS MISSING, A NEW FILE WILL BE CREATED IN THE LOCATION MENTIONED ABOVE. IF YOU SELECT THE FILE IN THE INSPECTOR YOU CAN MODIFY THE VALUES, BUT BE SURE TO NOT DO THAT,  BECAUSE THE LIST WITH THE TAGS WILL BE BROKEN WHEN OPEN THE TOOL
  • THE FILE "DRCSTagsTXT" IS USED BY THE "DRCS Manager" AT RUN TIME. IT IS LOCATED AT THE "DRCS\Resources"FOLDER. YOU HAVE TO KEEP THAT FILE IN THAT LOCATION. THIS FILE IS AUTOMATICALLY UPDATED BY THE TOOL WHEN ADDING OR REMOVING TAGS. IT IS STRONGLY RECOMMENDED NOT TO EDIT THIS TEXT FILE BY HAND. ALWAYS USE THE TOOL

 

 

HOW IT WORKS:

 

Select an object of type DRCMesh or SRCMesh first, then open the tool. Press initialize (edit) button to start edit tags or if the object is using LODs be sure to first select the LOD you want to edit. You can open the tool by pressing "Control+W", by going to menu "DRCS\Mesh Grouping Tool" or by pressing the "Edit Tags" button from the object's inspector.

 

When the object is initializes do as follow:

 

1. Select triangles by window selection or by mouse clicking. Hold down "control" or "shift" to append or remove triangles from selection. You can use the "Grow Selection" or "Select Element" buttons. The "Select Element" button requires at least one triangle to be selected.

2. Click on "Apply ID" button to apply the tag you wish to the selection.

3. You can use "Select with ID" button to select all triangles with a given ID. When hold down control you can append to selection.

4. When done just press down the "Quit Edit Mode" button and then close the editor.

You can add and remove tags. You can edit the tag names by double clicking on the it. When done entering the new name, either click outside the filed or press "Enter". If you enter a name that already exists you will be notified and will have to enter another name.

Be sure to always apply changes to prefab when done edit tags or at least save the scene, otherwise you will lose the newly applied tags.