Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more..
    Dismiss Notice
  3. Dismiss Notice

Resolved Intermediate - weird transform/raycast/particleSystem issue. Save me!

Discussion in 'Editor & General Support' started by Henzig, Jun 3, 2022.

  1. Henzig

    Henzig

    Joined:
    Aug 18, 2020
    Posts:
    22
    Hey guys! Any suggestions for a solution is more than welcome.

    My issue is fairly simple but I'm uploading everything connected to the issue just in case. I also hope I'm making sense here (english is not my first language).

    - I'm instantiating a prefab (attached "hierarchy cutout")
    - the RayCaster casts a ray to find any enemy directly in front of the player (pink capsule).
    - The RayCaster then moves the DetonationObject to the raycast hitPoint (or 30 points along the z-axis.
    - ParticleEmitter is called by the DetonationObject in "InitializeParticleSystem".

    For some doggone reason the RayCaster refuse to cast straight ahead (Vector3.forward) and tilts the ray. It is essential here that the tilt perfectly correlates with player position on the y-axis. Also the y-value differential between "relativeHitPos" and Player is almost exactly the same as the y-value differential between Player and origo (attached GameView2). Lastly as you can see the actual particles are rendered way above the ray.

    I can't find anything strange in the code. It looks like a scaling issue to me but all transforms are zero and the Instantiation does not assign a parent to the prefab. Can it be part of the particleSystem-component it self? I KNOW this is obvious to someone but I'm oblivious after several hours.

    Instantiation of prefab "Particle1"
    Code (CSharp):
    1. Instantiate(projectiles.Items[preppedWeapon], transform.position, Quaternion.identity);
    RayCaster:
    Code (CSharp):
    1.     private void CastRay()
    2.     {
    3.         Ray ray = new Ray(transform.position, transform.forward);
    4.         RaycastHit hitData;
    5.  
    6.         if (Physics.Raycast(ray, out hitData, 30, layerMask))
    7.         {
    8.             Vector3 hitPos = hitData.collider.gameObject.transform.position;
    9.             Vector3 relativeHitPos =  transform.position + hitPos;
    10.  
    11.             Debug.DrawRay(transform.position, relativeHitPos, Color.blue, 2);
    12.  
    13.             StartCoroutine(ActivateDetonationObject(relativeHitPos));
    14.         }
    15.         else
    16.         {
    17.             Debug.DrawRay(transform.position, new Vector3(transform.position.x,
    18.                 transform.position.y, transform.position.z + 30), Color.blue, 2);
    19.  
    20.             StartCoroutine(ActivateDetonationObject(new Vector3(transform.position.x,
    21.                 transform.position.y, transform.position.z + 30)));
    22.         }
    23.     }
    24.  
    25.     private IEnumerator ActivateDetonationObject(Vector3 moveTo)
    26.     {
    27.         detonationObject.transform.Translate(moveTo);
    28.         detonationObject.SetActive(true);
    29.  
    30.         yield return new WaitForFixedUpdate();
    31.  
    32.         //Debug option.
    33.         //yield return new WaitForSeconds(2);
    34.  
    35.         detonationObject.SetActive(false);
    36.         detonationObject.transform.Translate(transform.position);
    37.     }
    ParticleEmitter:

    Code (CSharp):
    1. public void InitiateParticleSystem(Vector3 endPos)
    2.     {
    3.         startPosition = transform.position;
    4.         endPosition = endPos;
    5.  
    6.         Vector3 particlePosition = (endPosition - startPosition) / 2 + startPosition;
    7.         float distance = Vector3.Distance(endPosition, startPosition) / 2;
    8.         int numParticles = (int)distance * 100;
    9.         particleSystem.transform.LookAt(endPosition);
    10.         ParticleSystem.ShapeModule sm = particleSystem.shape;
    11.         sm.position = particlePosition;
    12.         sm.radius = distance;
    13.  
    14.         ParticleSystem.EmissionModule em = particleSystem.emission;
    15.         em.rateOverTime = numParticles;
    16.  
    17.         particleSystem.Play();
    18.     }
     

    Attached Files:

  2. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    626
    What I don't understand is:
    A) What do you want your program to do?
    B) What does it do instead?
    C) How you calculate a relative position ->
    Vector3 relativeHitPos =  transform.position + hitPos;
    Shouldn't this be
    Vector3 relativeHitPos =  hitPos - transform.position;
    ?

    Also for readability I suggest changing this

    Code (CSharp):
    1.            Debug.DrawRay(transform.position, new Vector3(transform.position.x,
    2.                 transform.position.y, transform.position.z + 30), Color.blue, 2);
    3.  
    4.            StartCoroutine(ActivateDetonationObject(new Vector3(transform.position.x,
    5.                 transform.position.y, transform.position.z + 30)));
    To this:

    Code (CSharp):
    1.            Vector3 targetPos = transform.position;
    2.            targetPos.z += 30;
    3.  
    4.            Debug.DrawRay(targetPos, Color.blue, 2);
    5.  
    6.            StartCoroutine(ActivateDetonationObject(targetPos));
    also you can read the Transform directly from the raycastHit
    -> https://docs.unity3d.com/ScriptReference/RaycastHit-transform.html

    So you can change
    Vector3 hitPos = hitData.collider.gameObject.transform.position;

    to
    Vector3 hitPos = hitData.transform.position;
     
    Last edited: Jun 3, 2022
  3. Henzig

    Henzig

    Joined:
    Aug 18, 2020
    Posts:
    22
    Big thanks for replying!

    A) I want the raycast to find a position directly .forward of the raycaster. That's it basically! Really basic stuff that doesn't work for me.
    B) Instead I get this angled raycast that I don't understand.
    C) Strangely enough. That change in code made no difference to the behaviour. That surely is a clue...

    Edit: clarification.
    A) To raycast from the RayCaster and find a collider directly .forward of the RayCaster.transform.position or (if no collider is found) a point 30 units along the z-axis. Then move DetonationObject to that point.

    Thanks for the input. It's a lot cleaner.
     
  4. Henzig

    Henzig

    Joined:
    Aug 18, 2020
    Posts:
    22
    So it turn out setting the position of a particle system shape module isn't actually setting the position. Instead it is setting an offset to the current position.

    Rewriting the RayCaster and adding a line "particlePosition.y = 0;" to the ParticleEmitter solved the issue.

    Code (CSharp):
    1.     private void CastRay()
    2.     {
    3.         Ray ray = new Ray(transform.position, transform.forward);
    4.         RaycastHit hitData;
    5.  
    6.         if (Physics.Raycast(ray, out hitData, 30, layerMask))
    7.         {
    8.             IDamageable hit = hitData.transform.GetComponent<IDamageable>();
    9.  
    10.             if (hit == null)
    11.             {
    12.                 hitPoint = new Vector3(transform.position.x, transform.position.y,
    13.                     transform.position.z + 30);
    14.  
    15.                 particleEmitter.InitiateParticleSystem(hitPoint);
    16.             }
    17.             else
    18.             {
    19.                 hit.Damage(doDamage);
    20.                 hitPoint = hitData.transform.position;
    21.                 particleEmitter.InitiateParticleSystem(hitPoint);
    22.             }
    23.         }
    24.         else
    25.         {
    26.             hitPoint = new Vector3(transform.position.x, transform.position.y,
    27.                     transform.position.z + 30);
    28.  
    29.             particleEmitter.InitiateParticleSystem(hitPoint);
    30.         }
    31.     }
    Code (CSharp):
    1.     public void InitiateParticleSystem(Vector3 endPos)
    2.     {
    3.         startPosition = transform.position;
    4.  
    5.         Vector3 particlePosition = (endPos - startPosition) / 2 + startPosition;
    6.         float distance = Vector3.Distance(endPos, startPosition) / 2;
    7.         int numParticles = (int)distance * 100;
    8.         particleSystem.transform.LookAt(endPos);
    9.         ParticleSystem.ShapeModule sm = particleSystem.shape;
    10.         particlePosition.y = 0;
    11.         sm.position = particlePosition;
    12.         sm.radius = distance;
    13.  
    14.         ParticleSystem.EmissionModule em = particleSystem.emission;
    15.         em.rateOverTime = numParticles;
    16.  
    17.         particleSystem.Play();
    18.     }
     
    Last edited: Jun 5, 2022