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

get component of closest object

Discussion in 'Scripting' started by Mattyerial, Sep 29, 2021.

  1. Mattyerial

    Mattyerial

    Joined:
    Oct 5, 2018
    Posts:
    51
    How would i get the component of the closest object, say i have loads of cars
    i can get in. If i get in one it will control them all or mess up the whole thing,
    When my player is colliding with a tag car it will StartCoroutine to turn on a component on the car.
    i only want it to turn on that component of the closest car.

    I tried with accessing the code directing of the car script, but failed.
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,150
    If your player is colliding with a collider, then you can easily get the object you are colliding with. If your code is triggering all of them, then you have something set up incorrectly. If you have an OnCollisionEnter or OnTriggerEnter method, then you should be able to easily get what you collided with and run the code only on that instance.
     
    Joe-Censored likes this.
  3. Mattyerial

    Mattyerial

    Joined:
    Oct 5, 2018
    Posts:
    51
    I think posting the script will be easier to understand what i`m doing,
    My player becomes a child as it follows the car, this will be a problem if i have multiple cars; my current issue.
    Code (CSharp):
    1.    public void OnCollisionEnter2D(Collision2D collision)
    2.     {
    3.         if (collision.gameObject.tag == "Car")
    4.         {
    5.             byCar = true;
    6.         }
    7.     }
    8.  
    9.     public void OnCollisionExit2D(Collision2D collision)
    10.     {
    11.         if (collision.gameObject.tag == "Car")
    12.         {
    13.             byCar = false;
    14.         }
    15.     }
    16.  
    17.     IEnumerator Getincar()
    18.     {
    19.         transform.parent = thisisparent.transform;
    20.         rb.isKinematic = true;
    21.         sr.GetComponent<SpriteRenderer>().enabled = false;
    22.         bc.GetComponent<BoxCollider2D>().enabled = false;
    23.         moveSpeed = 0;
    24.         Drive.instance.StartCar();
    25.  
    26.         yield return new WaitForSeconds(1f);
    27.  
    28.         incar = true;
    29.  
    30.     }
    31.  
    32.     IEnumerator Getoutcar()
    33.     {
    34.         transform.SetParent(null);
    35.         rb.isKinematic = false;
    36.         sr.GetComponent<SpriteRenderer>().enabled = true;
    37.         bc.GetComponent<BoxCollider2D>().enabled = true;
    38.         moveSpeed = .4f;
    39.         Drive.instance.StopCar();
    40.  
    41.         yield return new WaitForSeconds(1f);
    42.  
    43.         incar = false;
    44.  
    45.     }
    46.  
    47. }
    as you can see im accessing a script on the car called, Drive.
    So when i use multiple cars it messes everything up.
    I hope theres a easy workaround, making a bunch of scripts for each car
    is too extreme lol.
     
  4. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,510
    It looks like you're accessing Drive as a singleton, which you definitely don't want to do if there are multiple cars and you only want to be driving one at a time. Instead, what you should be doing when entering a car is getting a reference to that specific car object and using GetComponent<Drive>() on it to get access to the methods that make just that car drive.

    Seems to me you're running into a lack of understanding how to architect the whole thing. Can you maybe walk us through some of your other code (Drive, specifically) and explain why you're doing things that way? This way we can give you answers that will work for you rather than just telling you to do things the way we would.
     
    Joe-Censored likes this.
  5. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,150
    Well, I do see that, but you're using Drive like it's a singleton to StartCar. If Drive is a singleton that is meant to manage only the drive system, that would be ok, but how does StartCar know which car you are targeting?

    A bunch of scripts for each car? You should have 1 script that is used for all cars on their own. Each car should have it's own instance of that script. Just like when you have a horde of enemies, you have an Enemy script that is a component on each enemy. Then when you shoot an enemy, you grab the component from that enemy and deal damage to it.

    OnCollisionEnter2D could easily assign the car you are next to to a variable, which would allow you to get the Component off that particular car.
     
    Joe-Censored likes this.
  6. Mattyerial

    Mattyerial

    Joined:
    Oct 5, 2018
    Posts:
    51
    Yes im using ride, which is a script on the car. I`m instancing it to start a function (start car)
    i`m a novice at coding, but have a good understanding of how it work.
    Would making the player the car movement work ?. so the player render is disabled.
    Then the drive script on the player works, so if i collide with tag car. the car will parent to the
    player and turn off walking script ?
     
  7. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,510
    Do you, though? Is Drive a singleton class? Because if so, that's a clear design flaw with how you're describing the way the system should work.

    Please understand that our comments aren't meant to be a criticism or anything... If you're new to development and not really understanding how stuff works, that's totally fine. It's more dangerous to assume you do know everything you need to know in this situation, because it suggests you're not open to learning how to better architect your systems.

    Could you please share your code for Drive.cs? I think the issue will be clear as day if we can see that code.
     
  8. Mattyerial

    Mattyerial

    Joined:
    Oct 5, 2018
    Posts:
    51
    Yes it is as i`m instancing it, its not a good idea really rookie mistake.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Drive : MonoBehaviour
    6. {
    7.  
    8.     public Rigidbody2D rb;
    9.     public Animator anim;
    10.     public static Drive instance;
    11.  
    12.     public float moveSpeed = 0;
    13.     private float speedinput;
    14.     public float x, y;
    15.  
    16.     public bool moving = false;
    17.     public bool startcar = false;
    18.  
    19.     private Vector3 moveDir;
    20.  
    21.     private void Start()
    22.     {
    23.         rb = GetComponent<Rigidbody2D>();
    24.  
    25.         if (instance != null)
    26.         {
    27.         }
    28.         else
    29.         {
    30.             instance = this;
    31.         }
    32.     }
    33.  
    34.     public void StartCar()
    35.     {
    36.         moveSpeed = 1;
    37.         startcar = true;
    38.     }
    39.  
    40.     public void StopCar()
    41.     {
    42.         moveSpeed = 0;
    43.         startcar = false;
    44.     }
    45.  
    46.     #region Checks and updates
    47.  
    48.     private void LateUpdate()
    49.     {
    50.         if (startcar)
    51.         {
    52.  
    53.             x = Input.GetAxis("Horizontal");
    54.             y = Input.GetAxis("Vertical");
    55.             speedinput = 0;
    56.  
    57.             moveDir = new Vector3(x, y).normalized;
    58.  
    59.             if (x != 0 || y != 0)
    60.             {
    61.                 anim.SetFloat("X", x);
    62.                 anim.SetFloat("Y", y);
    63.  
    64.  
    65.                 if (x > .0)
    66.                 {
    67.                     speedinput = moveSpeed * 100f;
    68.                     moving = true;
    69.                     anim.SetBool("isMoving", moving);
    70.                 }
    71.  
    72.                 if (x < -.0)
    73.                 {
    74.                     speedinput = moveSpeed * 100f;
    75.                     moving = true;
    76.                     anim.SetBool("isMoving", moving);
    77.                 }
    78.  
    79.                 if (y > .0)
    80.                 {
    81.                     speedinput = moveSpeed * 100f;
    82.                     moving = true;
    83.                     anim.SetBool("isMoving", moving);
    84.  
    85.                 }
    86.  
    87.                 if (y < -.0)
    88.                 {
    89.                     speedinput = moveSpeed * 100f;
    90.                     moving = true;
    91.                     anim.SetBool("isMoving", moving);
    92.                 }
    93.  
    94.  
    95.             }
    96.             else
    97.             {
    98.                 Invoke("StopMoving", 1f);
    99.             }
    100.  
    101.             Vector2 S = gameObject.GetComponent<SpriteRenderer>().sprite.bounds.size;
    102.             gameObject.GetComponent<BoxCollider2D>().size = S;
    103.             gameObject.GetComponent<BoxCollider2D>().offset = new Vector2(0, 0);
    104.         }
    105.  
    106.     }
    107.  
    108.     private void FixedUpdate()
    109.     {
    110.         if (Mathf.Abs(speedinput) > 0 && moving == true)
    111.         {
    112.         rb.velocity = moveDir * speedinput * Time.deltaTime;
    113.         }
    114.     }
    115.  
    116.     private void StopMoving()
    117.     {
    118.         rb.velocity = Vector3.zero;
    119.         rb.Sleep();
    120.         moving = false;
    121.     }
    122.  
    123. }
    124.  
    125. #endregion
    126.  
     
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,951
    As long as you use the above construct, coupled with the partially-implemented lockout mechanism you have in Start(), you are always going to have a tough time doing what you describe in your first post.

    What you probably want is a NON-static reference in the player to give you a reference to the car they are presently driving.

    But as I said to you in the other post, you are seriously doing yourself a disservice by not working through some of the MILLIONS of tutorials out there on racing.

    https://forum.unity.com/threads/car-2d-movement-help.1175873/#post-7531025

    If you prefer to work in the dark trying random combinations, be my guest. Just understand that with every layer of complexity the confusion is only going to compound itself more and more, causing more confusion and mayhem.
     
  10. Mattyerial

    Mattyerial

    Joined:
    Oct 5, 2018
    Posts:
    51
    @Kurt-Dekker
    Thank you. I`m not making a racing game and they dont explain how to use multiple cars and go
    in and out of them.
    I did watch a jvegas vide on a gta style and he references the player from the car not player to the car.
    I have done it now and added a teleport system instead of parenting player to the car and works how i
    wanted it.
    If there is another way to do it, please put your input as i said i`m a novice not a pro.
    Here is my finished code for anybody intrested.in helping it or can improve i
     
    Last edited: Sep 30, 2021
  11. Mattyerial

    Mattyerial

    Joined:
    Oct 5, 2018
    Posts:
    51
    Can this thread be deleted now as i have figured it out myself and its resolved.
     
  12. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,150
    The point of the forums is to not delete stuff. It's to present questions and have solutions shown. That way future people who run into the same issue can hopefully just find the same forum post to read up on. They don't just go through deleting post just because they get solved.