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. Dismiss Notice

Question Increase Trigger Check Rate - Shooting arrow with VIDEO

Discussion in 'Editor & General Support' started by kallifurkan, Oct 31, 2020.

  1. kallifurkan

    kallifurkan

    Joined:
    Apr 13, 2015
    Posts:
    6

    Hello guys, the problem is when i shoot arrow it should freeze when hit collider. But when i shoot it fast its bounce or freeze beyond object.

    Code (CSharp):
    1. private void OnTriggerEnter(Collider other) {
    2.         if(other.gameObject.name != "Player") {
    3.             rb.constraints = RigidbodyConstraints.FreezeAll;
    4.             this.transform.parent = other.transform;
    5.           }rb.velocity = Vector3.zero;
    6.             this.GetComponent<BoxCollider>().enabled = false;
    7.             this.GetComponent<BoxCollider>().isTrigger = false;
    8.             Debug.Log("Arrow Hit : " + other.gameObject.name);
    9.         }
    10.     }
     
    Last edited: Oct 31, 2020
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,120
    Relatively small, fast-moving objects will always have issues with collision. At a certain point, you'll need to resort to other means than OnTriggerEnter or OnCollisionEnter if you want reliable collision detection.

    The approach I use is to perform a Physics.Raycast every FixedUpdate, raycasting forward the distance that the projectile will move that frame. The raycasting approach will hit any obstacles in the way.
     
    kallifurkan likes this.
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,768
    Exactly what @dgoyette says... I always move my own bullets through space and raycast ahead of them each frame. Otherwise it's just too easy to pass right through small objects.

    This code won't compile for you as it is part of my Jetpack Kurt Space Flight combat module, but it sorta shows the thinking on it. I even did the motion in Update() since it isn't really physics per-se.

    Code (csharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class WeaponShot1Controller : MonoBehaviour
    6. {
    7.     const float LaserBoltSpeed = 150.0f;
    8.  
    9.     const float Gravity = -10.0f;
    10.  
    11.     Vector3 velocity;
    12.  
    13.     bool reactive = true;
    14.  
    15.     public static WeaponShot1Controller Create(
    16.         Vector3 startPosition,
    17.         Vector3 startForward,
    18.         Vector3 playerVelocity)
    19.     {
    20.         var sc = new GameObject( "WeaponShot1Controller.Create();").AddComponent<WeaponShot1Controller>();
    21.  
    22. // destroy in this much lifetime
    23.         TTL.Attach( sc.gameObject, Random.Range( 3.5f, 4.5f));
    24.  
    25.         sc.transform.position = startPosition;
    26.  
    27. // a streaky particle rate-over-distance object that looks cool
    28.         Instantiate<GameObject>( Resources.Load<GameObject>(
    29.             "Prefabs/WeaponShot1Controller_prefab"), sc.transform);
    30.  
    31.         sc.velocity = playerVelocity + startForward.normalized * LaserBoltSpeed;
    32.  
    33.         sc.UpdateMovement();
    34.  
    35.         return sc;
    36.     }
    37.  
    38.     void UpdateMovement()
    39.     {
    40.         velocity += Vector3.up * Gravity * Time.deltaTime;
    41.  
    42.         Vector3 movement = velocity * Time.deltaTime;
    43.  
    44.         Vector3 newPosition = transform.position + movement;
    45.  
    46.         // possible outcomes from impact/contact with a collider:
    47.         //
    48.         //    - don't ricochet off a damage-taker (this might not be necessary)
    49.         //
    50.         //    - case of ricochet:
    51.         //        - choose random speed attenuation
    52.         //        - deflect according to normal
    53.         //        - deflect a bit more randomly
    54.         //        - if below a certain amount, become unreactive
    55.         //
    56.         //    - case of impact and finish:
    57.         //        - destroy
    58.         //
    59.         // If reactive, leave a little splash cloud of particles
    60.         //
    61.         Ray ray = new Ray( transform.position, velocity);
    62.         RaycastHit rch;
    63.         if (Physics.Raycast( ray, out rch, movement.magnitude, ~(1 << MyLayers.i_Player)))
    64.         {
    65.             bool CanRicochet = reactive;
    66.  
    67.             newPosition = rch.point;
    68.  
    69.             var da = rch.collider.GetComponent<ICombatDamageable>();
    70.             if (da != null)
    71.             {
    72.                 da.TakeDamage( 1.0f);
    73.  
    74.                 CanRicochet = false;
    75.  
    76.                 STATE.MissionShotsHit++;
    77.             }
    78.  
    79.             if (reactive)
    80.             {
    81.                 SpaceFlightShotImpact.Create( newPosition, rch.normal);
    82.             }
    83.  
    84.             // chance of carom/ricochet?
    85.             if (CanRicochet)
    86.             {
    87.                 if (Random.Range( 0, 6) == 0)
    88.                 {
    89.                     float attenuate1 = Random.Range( 0.05f, 0.6f);
    90.                     float attenuate2 = Mathf.Min( attenuate1, Random.Range( 0.05f, 0.6f));
    91.                     float attenuate3 = Mathf.Min( attenuate2, Random.Range( 0.05f, 0.6f));
    92.  
    93.                     velocity.x *= attenuate3;
    94.                     velocity.y *= attenuate1;
    95.                     velocity.z *= attenuate3;
    96.  
    97.                     var impactSpeed = Vector3.Dot( velocity, rch.normal);
    98.  
    99.                     var reflect = rch.normal * impactSpeed * Random.Range( 1.8f, 3.0f);
    100.  
    101.                     velocity -= reflect;
    102.  
    103.                     // chance of becoming unreactive: we no longer make ricochet splash visuals
    104.                     if (velocity.magnitude < 30)
    105.                     {
    106.                         // and a sub-chance of just going away when we're this slow
    107.                         if (Random.Range( 0, 3) > 0)
    108.                         {
    109.                             reactive = false;
    110.                         }
    111.                     }
    112.                 }
    113.             }
    114.             else
    115.             {
    116.                 Destroy( gameObject);
    117.             }
    118.         }
    119.  
    120.         Vector3 oldPosition = transform.position;
    121.  
    122.         transform.position = newPosition;
    123.     }
    124.  
    125.     void Update ()
    126.     {
    127.         UpdateMovement();
    128.     }
    129. }
    Here's a visual of what that approach gets you:

     
    Last edited: Oct 31, 2020
    kallifurkan likes this.
  4. kallifurkan

    kallifurkan

    Joined:
    Apr 13, 2015
    Posts:
    6
    Thank you guys, i didnt think kinda solution before. I solved problem changing time step in unity project settings. it will cost performance?
     
  5. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,120
    Yes, definitely. The smaller the timestep, the more work the physics system has to do. If you've only changed it a little, and it's just enough to get your arrow collisions to work, it might not be a big deal. But if you make the fixed timestep faster, you can easily have cases where FixedUpdate is run multiple times per frame, which can create a feedback loop that further lowers performance.

    Anyway, if it's a small change, maybe it's fine, you'll just have to profile it and see. But it means that if you end up deciding the arrows should move any faster, you'd have to further reduce the fixed timestep. I personally wouldn't want to have to change the timestep for reasons like that.
     
    kallifurkan likes this.