Feb 182017
 

Instructions

I will be creating a dedicated module using Drupal Console for this event subscriber. But feel free to use your own if you already have one! (don’t forget to backup)

  1. Access the drupal root folder in command line.
  2. Generate a new module:
  3. Generate the event subscriber. We will subscribe to the kernel.request event:
  4. Current state:
  5. Install the module using either drupal module:install or drush pm-enable:
  6. Now, refresh your web page and on each request received server side, a message will tell you the event occurred!

Additional Information

  • Instructions made on Drupal 8.2.x.
  • Using Drupal Console, you can easily inject services such as the current_user one by answering yes when it asks if you want to load services from the container. Please check this article about service dependency injection: [Drupal] Service dependency injection in a service type class.
  • After editing your files, remember to run a cache rebuild either with drupal cache:rebuild or drush cache-rebuild.
  • Events documentation entry point: Events on Drupal 8. You will find a few core events here.
  • The callback function’s name can be changed to whatever you want.
Feb 162017
 

The code

Additional Information

Feb 162017
 

The code

Additional Information

  • Unlike service type class service dependency injection, there may be no need to implement an interface to be able to load the needed services, such as extending from ControllerBase. So if you are extending from a class which already has the dependency injection implementation, you can just override the create and __construct methods. Don’t forget to call parent methods if needed.
  • Think of the create method as the model used by the __construct of your class.
  • The create signature needs to respect the one of the implemented interface (use your IDE to check against the original declaration).
  • Originally made and tested on Drupal 8.2.x.
  • A convenient list of core services can be found here: https://api.drupal.org/api/drupal/core%21core.services.yml/8.2.x (don’t forget to select the Drupal version if you are not on 8.2.x).
  • Some classes such as ones extending BlockBase will need to implement interfaces to access this pattern:
Dec 162016
 

The code

The maths behind

To get the point where two lines intersect, we will do some maths. To the mathematicians who will come across this post, I’m truly sorry for the heart attacks or strokes you may experience by reading this post.

Ok, let’s take a look on the figure:

Study case. We can see two lines crossing in an 2D Euclidian space.

Figure 1

First, sorry, I was too lazy to make a proper figure using computer tools so I just put a scan. XD

Next, here are the definitions:

  • A & B: the two lines,
  • A_1, B_1: the arbitrary starting points of the two lines,
  • A_2, B_2: the arbitrary points which tells the direction of the two lines,
  • X: the intersection point,
  • O: the origin point.

Kewl. Now, what we want is the intersection point X between those two lines. In other words, we want to know the position which starts from either lines’ arbitrary starting point, added by the direction of the line multiplied by a scalar value. So in our figure 1, the X position is:

  • the A_1 position added by the components of \overrightarrow{A_1A_2} multiplied by an unknown which I named \lambda
  • the B_1 position added by the components of \overrightarrow{B_1B_2} multiplied by an unknown which I named \mu

In this case, it is clear that \lambda = \mu = 0.5 so it will be easy to check if our final formula is correct. 🙂

At the point of intersection, we know that:
\begin{array}{rcl} \overrightarrow{OX} = \overrightarrow{OA_1} + \lambda\times\overrightarrow{A_1A_2} & and & \overrightarrow{OX} = \overrightarrow{OB_1} + \mu\times\overrightarrow{B_1B_2} \end{array}

… which gives us:
\begin{array}{rcl} \overrightarrow{OA_1} + \lambda\times\overrightarrow{A_1A_2} & = & \overrightarrow{OB_1} + \mu\times\overrightarrow{B_1B_2} \\ \overrightarrow{OA_1} - \overrightarrow{OB_1} & = & \mu\times\overrightarrow{B_1B_2} - \lambda\times\overrightarrow{A_1A_2} \end{array}

But we can’t use this statement exactly like this to solve our equation as we cannot multiply and divide vectors in this raw format. Also we need to reduce the unkowns count to 1. So we will separate our equation into two equations with the magic of matrices (which I don’t understand well at the moment), one for the x component and one for the y:
\left\{\begin{array}{c}  \overrightarrow{OA_1}_x - \overrightarrow{OB_1}_x = \mu\times\overrightarrow{B_1B_2}_x - \lambda\times\overrightarrow{A_1A_2}_x \\   \overrightarrow{OA_1}_y - \overrightarrow{OB_1}_y = \mu\times\overrightarrow{B_1B_2}_y - \lambda\times\overrightarrow{A_1A_2}_y  \end{array}\right.

To make our equation more readable, we will use some shorthands:
\begin{array}{r}A_\alpha = \overrightarrow{A_1A_2}\end{array}\\  \begin{array}{r}B_\alpha = \overrightarrow{B_1B_2}\end{array}\\  \begin{array}{r}C = \overrightarrow{OA_1} - \overrightarrow{OB_1}\end{array}

… so:
\left\{\begin{array}{c}  C_x = \mu B_{\alpha x} - \lambda A_{\alpha x} \\   C_y = \mu B_{\alpha y} - \lambda A_{\alpha y}  \end{array}\right.

From this point, we can reduce the unknown count. In my case, I have chosen to keep \mu instead of \lambda:
\left\{\begin{array}{c}  C_x A_{\alpha y} = \mu B_{\alpha x} A_{\alpha y} - \lambda A_{\alpha x} A_{\alpha y} \\   C_y A_{\alpha x} = \mu B_{\alpha y} A_{\alpha x} - \lambda A_{\alpha y} A_{\alpha x}  \end{array}\right.\\  \begin{array}{rcl}  C_x A_{\alpha y} - C_y A_{\alpha x} & = & \mu B_{\alpha x} A_{\alpha y} - \lambda A_{\alpha x} A_{\alpha y} - (\mu B_{\alpha y} A_{\alpha x} - \lambda A_{\alpha y} A_{\alpha x}) \\  C_x A_{\alpha y} - C_y A_{\alpha x} & = & \mu B_{\alpha x} A_{\alpha y} - \lambda A_{\alpha x} A_{\alpha y} - \mu B_{\alpha y} A_{\alpha x} + \lambda A_{\alpha y} A_{\alpha x} \\  C_x A_{\alpha y} - C_y A_{\alpha x} & = & \mu B_{\alpha x} A_{\alpha y} - \mu B_{\alpha y} A_{\alpha x} \\  C_x A_{\alpha y} - C_y A_{\alpha x} & = & \mu (B_{\alpha x} A_{\alpha y} - B_{\alpha y} A_{\alpha x}) \\  \mu & = & \frac{C_x A_{\alpha y} - C_y A_{\alpha x}}{B_{\alpha x} A_{\alpha y} - B_{\alpha y} A_{\alpha x}}  \end{array}

And finally, you have to check if B_{\alpha x} A_{\alpha y} - B_{\alpha y} A_{\alpha x} = 0. This will happen if your two lines are parallel or if there is one line defined as a point such as A_1 = A_2 or B_1 = B_2; no solution exists in those cases.

Test 1

Kewl! Now let’s try it with the Figure 1:
\begin{array}{rcl}  \mu & = & \frac{(1 - 1) \times 1 - (2 - 4) \times 2}{2 \times 1 - (-3) \times 2} \\  \mu & = & \frac{4}{8} = 0.5  \end{array}

We can get the X position:
\left\{\begin{array}{l}  \overrightarrow{OX}_x = \overrightarrow{OB_1}_x + B_{\alpha x} \times \mu = 1 + 2 \times 0.5 = 2 \\  \overrightarrow{OX}_y = \overrightarrow{OB_1}_y + B_{\alpha y} \times \mu = 4 + (-3) \times 0.5 = 2.5  \end{array}\right.

Test 2

Ok done! Now let’s try with another figure:

Study case 2. We can see two lines crossing in an 2D Euclidian space.

Figure 2

\begin{array}{rcl}  \mu & = & \frac{((-2) - 2) \times (-1) - ((-2) - (-3)) \times 0}{(-1.5) \times (-1) - 1.5 \times 0} \\  \mu & = & \frac{4}{1.5} \approx 2.666  \end{array}

We can get the X position:
\left\{\begin{array}{l}  \overrightarrow{OX}_x = \overrightarrow{OB_1}_x + B_{\alpha x} \times \mu = 2 + (-1.5) \times 2.666 = -2 \\  \overrightarrow{OX}_y = \overrightarrow{OB_1}_y + B_{\alpha y} \times \mu = (-3) + 1.5 \times 2.666 = 1  \end{array}\right.

Nov 302016
 

Method 1: mega box collider

Use a single BoxCollider for all your planes. For example, if you have multiple aligned planes, remove their Collider component (Box, Mesh, whichever they have) and on only one of the planes, add a BoxCollider and adjust its center and size values in the component’s inspector to encapsulate all the planes.

Pros

  • Simple.

Cons

  • Supports only rectangular surfaces.

Method 2: generated colliders

If you are rolling your ball on a non rectangular surface, you will need to find a way to generate a mesh collider for all your planes. For this, choose one of the following:

Pros

  • Just works.

Cons

  • Uses noticeable CPU power when updating (baking) the colliding mesh in real time. Update sparingly.

Method 3: ramps as bridges

Create a set of meshes from a 3D software such as Blender to make invisible ramps which will be placed partly underground between your planes. They have to be large enough to make the transitions as smooth as possible. The height between the top of the bridge and the ground (the planes) should be approximately the value defined by the Default Contact Offset value in the Physics Manager.

Pros

  • No real improvement.

Cons

  • The ball may jump a little, especially at high speed.
  • Doesn’t work with small tiling (or when your successive planes are small): the longer the tiles, the longer bridges can be.
  • Requires a lot of testing.
  • Requires 3D software usage.
  • The result is not consistent.
  • Requires good workflow / toolchain.

Method 4: make custom extended planes’ colliders

This one should not work very well.

Create in a 3D software a planar mesh. Then, on its edges, extrude towards outside and lower down slightly the new edges. To put the words into image:

Photo of speed cushions.

Credits: Richard Drdul — cc-by-sa-2.0 (original)

Make them intersect, and hopefully the bouncing will be invisible.

Pros

  • Quite simple.

Cons

  • The ball may jump a little, especially at high speed.
  • Requires a lot of testing.
  • Requires 3D software usage.
  • The result is not consistent.
  • Requires good workflow / toolchain.

Method 5: turn slightly your planes’ colliders

Make your planes’ colliders slightly rotated so that, in the direction of movement, the end of a collider is slightly above the next plane’s collider. The height should be approximately the value defined by the Default Contact Offset value in the Physics Manager and hopefully no bouncing will occur.

Pros

  • Works flawlessly.

Cons

  • You will see the ball flying and falling a few units from one plane to another.

Method 6: do everything by script

Maybe the Physics is not what is the best for your gameplay. Write your own system with accelerations, collision detection. This is the old-fashioned way and is the choice of a lot of developers! ^^

Pros

  • Works flawlessly.
  • Permits game design driven gameplay and not by physics.

Cons

  • Not using the PhysX forces and gravity.
  • Requires to work (omg! 😉 ) to simulate fake physics.

Method 7: Make your ball much larger

By using a greater ball (x10, x100), this could lead to less edge detection.

Pros

  • May work.

Cons

  • The scale of the simulation would change: if you make everything at the same scale as the ball, objects falling by gravity will look like they fall in slow motion.
  • The result is not consistent.

Method 8: collision layers and raycast

This one is pretty cool.

  1. Keep single BoxColliders for each plane. Set the layer of the plane prefab to SinglePlanes (create the layer).
  2. Make a big Unity cube with a collider which encapsulates all the planes. Set the layer of the cube to ContinuousPlane.
  3. Create two layers: OnAPlane and NotOnAPlane.
  4. Set the ball prefab’s layer to OnAPlane.
  5. In Physics Manager, set the collision matrix so that:
    • NotOnAPlane and ContinuousPlane are not collidable (unchecked),
    • OnAPlane and SinglePlanes are not collidable (unchecked).
  6. On each Update(), do a raycast from the center of the ball towards Vector3.down on the layer SinglePlanes:
  7. If the raycast returns false, the center of the ball is not on a plane. So now, we change the layer of the ball to NotOnAPlane. The ball will start to fall through the hole.
  8. If the raycast returns true, set the layer of the ball to OnAPlane.

For how to define a layer, please check the manual.

Pros

  • Works efficiently with dynamic floor layout.
  • You will learn how to deal with layers and Physics.

Cons

  • No real flaws.

Additional Information

  • Methods above may be combined.
  • You can adjust the physics project settings and / or set the physics materials to reduce the bounciness of your objects.
  • Make sure the thickness of the planes collision is not 0f. Make them 1f large or more.
  • There is a possibility to reduce the bounces, but I am not recommending it (may cause jittery and physics artifacts): set the Default Contact Offset to 0.0001. Again, I am not recommending it!
  • All of this post could be useless when the default PhysX embedded in Unity will be upgraded.
  • I originally posted this post as an answer on the Unity Answers website but none of the above methods have been considered as valid by the OP. Hence the removal from the answers website.
Mar 302015
 

Je mets le contenu du fichier .hgignore que j’utilise pour mes projets sur Android Studio. Je suis parti du .gitignore de base livré avec un nouveau projet dans Android Studio et je l’ai complété en m’inspirant de plusieurs réponses sur Stack Overflow.

À noter que la configuration suivante est réglée pour que le projet soit importé dans Android Studio (Import project (Eclipse ADT, Gradle, etc.)) juste après un clonage, et pas juste ouvert comme un projet existant. L’import créera les fichiers nécessaires tels que les *.iml et ceux du dossier .idea.

Jan 292014
 
En-tête d'article

Vous avez besoin d’un petit script en Visual Basic pour faire un export simple d’un tableau Excel vers un fichier texte .txt ? Alors j’ai peut-être le script dont vous avez besoin !

Enthousiasmé

Je ne connais pas vraiment VB, mais une lecture rapide de quelques tutoriaux m’a permis de faire ce que je cherchais comme comportement. Ce script fonctionnerait uniquement sur Windows. Voici le résultat :

Il est probable que le code puisse être optimisé pour être exécuté plus rapidement. Néanmoins, il me suffit dans son état actuel pour exporter mes fichiers.

À noter que ce script s’exécute sans problème lorsque le document est ouvert dans LibreOffice Calc (toujours sur Windows).