DRCS C# Jobs Documentation


CURRENT STATE : BETA

This is a collider free system which uses custom RayCast and SphereCast methods to detect mesh objects. It is based on the new C# Job system and Burst compiler for greater performance and supports Skinned and Rigid (Non-Skinned) meshes.

This system is not meant to replace any of Unity’s regular raycast or spherecast methods. What it’s capable of is detecting triangular meshes without the need to add any colliders to them. It just iterates over triangles in a mesh and checks for intersection with rays and swept spheres ( type of a capsule ). The idea of this system is to be used with most important objects only, because raycast against triangles is some what slower than spheres and boxes, and if you have many objects with many triangles, it becomes slow.

PLEASE NOTE THAT PROJECT UPGRADE FROM THE STANDARD VERSION IS NOT SUPPORTED, HOWEVER IF YOU FOLLOW THE STEPS BELOW YOU MIGHT BE ABLE TO SUCCESSFULLY UPGRADE WITHOUT LOOSING SETUP AND PREFABS
Check this link to the forum page to see how you can try to upgrade without loosing previous setup : HOW TO UPGRADE !

  • NOTE : requires .Net 4 to be selected and Jobs, Burst and Collection packages from the package manager !
  • NOTE : Platform support is based on Unity’s support for C# Jobs and Burst compiler and their current state !
  • DRCS will not fit in every project (for any question use the support email to contact me for more information )

Features

  • RayCastFast, 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 improve 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 ( bone transforms should be visible )
  • Mesh Grouping Tool – select and group triangles by tags, i.e. define character’s head with tag “head”
  • Object groups – using strings you can put the same string to group of objects and check only against them
  • Custom mesh skinning method ( automatically managed and uses IJobParallel in order to calculate skinning on multiple CPU cores ). This is needed for animated objects and blend shapes in order to calculate current position of mesh vertices.
  • Rich “DRCHitInfo” class filled with information about any intersected object
  1. GameObject  hitObject;
  2. Renderer       hitObjectRenderer;
  3. Vector3          hitPoint;
  4. Vector3          hitNormal;
  5. float               hitDistance;
  6. Vector3          barycentricCoordinate;
  7. Vector2          textureCoordinates;
  8. int                  triangleIndex;
  9. string             drcTag;
  10. ObjectType    hitObjectType;
  11. DRCM            drcmObject;

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


How it works internally

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 what Unity’s “Physics.RayCast() and Physics.SphereCast()” functions are doing, but there are two main differences:

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

System Components Overview

2. DRCM – 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).

NOTE : there is a parameter in the method which says “ignoreColliders”. Set this parameter to false will not ignore the Unity’s Physics RayCast() call. This is explained again below !

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 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
  • 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 !

NOTE : when LODs are enabled, a custom “update()” coroutine is started for this DRCM object and it is manged automatically. An update() is required in order to swap
correctly the mesh at run-time ( if the “swapLODMeshes” options is enabled ) !

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”


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.

DOCS UNDER CONSTRUCTION …