Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

how to place something on skin of animated object?

Discussion in 'Scripting' started by steveh2112, Mar 8, 2020.

  1. steveh2112

    steveh2112

    Joined:
    Aug 30, 2015
    Posts:
    314
    i want to place a blood splat on the skin of my player or a NPC when hit.

    sure, raycast will give you a hit point of the collider but that's no use if i want the skin.

    so i wrote a handy little bit of code to find the closest bone to the hitpoint

    Code (CSharp):
    1.  
    2. Transform hips = transform.Find("mixamorig:Hips");
    3.         if (!hips)
    4.             Debug.LogError("AiOnDamage ArrowHit NO mixamorig:Hips");
    5.  
    6.         float closestSoFar = Mathf.Infinity;
    7.         Transform closestBone = null;
    8.         FindClosestBone(hips, hitPosition, ref closestSoFar, ref closestBone);
    9.         Debug.Log("AiOnDamage DoDamage closestBone=" + closestBone);
    10.  
    11. void FindClosestBone(Transform root, Vector3 point, ref float closestSoFar, ref Transform closestBone)
    12.     {
    13.         foreach(Transform t in root)
    14.         {
    15.             float distFromPoint = Vector3.Distance(t.position, point);
    16.             if (distFromPoint < closestSoFar)
    17.             {
    18.                 closestSoFar = distFromPoint;
    19.                 closestBone = t;
    20.             }
    21.            
    22.             if (t.childCount > 0)
    23.                 FindClosestBone(t, point, ref closestSoFar, ref closestBone);
    24.         }
    25.     }
    which is great for parenting something so it moves with the mesh.
    but still no idea how to find the exact point on the mesh that matches the hit point
    any ideas?

    thx
     
  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    I believe you are looking for decals, ie textures you place on other textures. The new'ish HDRP includes a Decal ("Projector") Shader you could use: https://docs.unity3d.com/Packages/c...gh-definition@5.7/manual/Decal-Projector.html , even tho i dont know how well it works with animated meshes.

    You could also try writing your own. Overlaying textures should only be a matter of blending two textures together, but i'm not exactly a shader pro and cant say a lot about how difficult it may be to turn this on / off for multiple blood splat locations.
    You could use RaycastHit.textureCoord to get the UV coordinates of the texture at the hit location, which gives you information on where to put the decal.

    I believe putting the blood splat directly on the material is your only option if you want it to look decent. Otherwise i'm not sure how you would make it deform to follow animations and so on.
     
    steveh2112 likes this.
  3. steveh2112

    steveh2112

    Joined:
    Aug 30, 2015
    Posts:
    314
    thanks,
    RaycastHit.textureCoord wouldn't work because it needs a mesh collider and for characters, people typically use capsule colliders for efficiency i guess, and anyhow, i don't think mesh colliders will deform with the animation

    but maybe i could add a temporary mesh collider just to find the uv coord?

    i'll experiment with it, but i think you are right, 'putting the blood splat directly on the material is your only option if you want it to look decent'

    even if its not exactly the right spot, i can probably get it close just from the capsule collider hit

    so how to paint directly onto the characters texture?
    some discussion here
    https://forum.unity.com/threads/painting-a-texture-ingame.323199/
    but no clear answer
    UPDATE
    i just tried added a blood splat png with transparent background into the detail mask and detail albedo slots on the standard shader and it does work
    the trick is how to create potentially hundreds of blood splats in different locations if i go for a pre canned approach, or create an on the fly texture and no idea how to do that Untitled.png
     
    Last edited: Mar 9, 2020
  4. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    You will probably want to look into writing a small shader to do so. The new shader graph may help, but i'm am not an expert on either. Blending two textures should be rather easy. You can also pass a coordinate for where to put it. So doing it for one blood splat should be trivial. Doing it for multiple.. i'm not sure. You may be able to pass an array of coordinates and just place a bloodsplat for each of them, which would make the whole thing kind of easy. But then again, i'm not very experienced at all in writing shaders yet, so that may or may not be possible.