Apply decal to wall? (blood splatter) & Instantiated object rotation problems

Hey all,

I’m trying to apply a decal (at the moment a quad) to a wall when the raycast hits it.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Rob_Blood_Test : MonoBehaviour {

    // Use this for initialization
    public GameObject quad;
    public float raydistance = 0.1f;

    public ParticleSystem part;
    public List<ParticleCollisionEvent> colEvents;
    void Start ()
    {
        part = GetComponent<ParticleSystem>();
        colEvents = new List<ParticleCollisionEvent>();

    }
   
    // Update is called once per frame
    void Update ()
    {

        //LayerMask layerMask = (1 << 10 | 1 << 16 | 1 << 9);
        //Collider[] checkObj = Physics.OverlapSphere(this.gameObject.transform.position, 0.01f, layerMask);

        //List<GameObject> cols = new List<GameObject>();

        //foreach (Collider hit in checkObj)
        //{
        //    RaycastHit rayhit;

        //    if (Physics.Linecast(transform.position,hit.gameObject.transform.position, out rayhit, layerMask, QueryTriggerInteraction.Collide))
        //    {
        //        // ContactPoint contact = checkObj[0].ClosestPointOnBounds(this.transform.position)
        //        //Vector3 closestPoint = checkObj[0].ClosestPointOnBounds(rayhit.transform.gameObject.transform.position);
        //        GameObject go = Instantiate(quad, rayhit.point, Quaternion.Euler(new Vector3(0,checkObj[0].transform.rotation.y,0))) as GameObject;
        //       // go.transform.rotation = Quaternion.FromToRotation(transform.up, rayhit.normal) * transform.rotation;
        //        //float distance = Vector3.Distance(closestPoint, this.gameObject.transform.position);
        //        //Debug.Log(distance);
        //        //  Instantiate(quad, rayhit.point, Quaternion.identity);
        //        // Destroy(this.gameObject);
        //    }



        //}
        RaycastHit hit;
        if (Physics.Raycast(transform.position, -transform.forward, out hit, raydistance))
        {
            // Instantiate(quad, hit.point, Quaternion.FromToRotation(transform.up, hit.normal) * transform.rotation);
            Quaternion rot = Quaternion.LookRotation(hit.normal);
            //Instantiate(quad, hit.point, Quaternion.Euler(new Vector3(rot.x,rot.y + 180, rot.z)));
            Instantiate(quad, hit.point, rot);
            Debug.Log(hit.normal);
        }
        Debug.DrawRay(transform.position, -transform.forward * raydistance, Color.green);

        // gameObject.GetComponent<ParticleSystem>().collision.sendCollisionMessages
    }


}

I can’t find anything online about how this could be done without getting redirected to asset packs, any links would be great

Also the second problem i’m having is that the quad is not rotating to the hit.normal of the raycast I have tried using

Quaternion.FromToRotation(transform.up, hit.normal)

and

            Quaternion rot = Quaternion.LookRotation(hit.normal);

but both give the same result and aren’t rotating the instantiated object at all :confused:

The default quad has no backface. You’ll want to use the inverse of the normal to turn it around. You’ll also want to offset the exact placement by a tiny little bit to avoid Z-fighting.

  Quaternion rot = Quaternion.LookRotation(-hit.normal);
       Instantiate(quad, hit.point + hit.normal * 0.01f, rot);

Hey thanks this is great :slight_smile: but now i have the problem that it’s sometimes instantiating not even close to a wall, would you know why?

probably because the raycast is hitting something else. Try logging it:

if (Physics.Raycast(transform.position, -transform.forward, out hit, raydistance))
{
    Debug.Log(hit.collider.name, hit.collider.gameObject);
    ...

The easiest way to only hit walls is to use layers and a LayerMask for the Raycast.