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

Many objects with the same script do the same thing - I want, to control them individually

Discussion in 'Getting Started' started by Avenged90x, Sep 25, 2018.

  1. Avenged90x

    Avenged90x

    Joined:
    Sep 6, 2017
    Posts:
    35
    Hi there!

    I have basic, maybe stupid trouble..
    I made script of movement to objects. Movement is simply - swipe gestures in 4 directions, and object is moving by for example 5f in specified axis (direction). I have 2 objects, exactly the same objects. These objects has the same script of movement. And now, when 1 object collides with second object - I want to move it above that second object, like jumping on it. And I made simply code like: OnTriggerEnter (collider other), if (other) -> transform.position.y + 1f. But when the collision happens, both objects goes up..

    How can I make that script, to move only that first object, which has movement ?

    I don't want to make many, individual objects, with different tags like square1, square2, square3 etc.. :)

    Maybe everything goes wrong because i use OnTriggerEnter?.. ? .. ?
     
    Last edited: Sep 25, 2018
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Well if you want different behavior you'll need to differentiate the two objects in some manner. It can be different scripts, different settings on the same script that make the script behave differently, etc.
     
  3. BoogieD

    BoogieD

    Joined:
    Jun 8, 2016
    Posts:
    236
    OnTriggerEnter is being called for both GameObjects when they collide so the same thing happens to each GameObject according to your script.
    If it is the first GameObject that has moved that you wish to jump up then create a static GameObject variable in the script set to null and when a GameObject first moves set the variable to that GameObject only if it is null so only the first one that moves will set it.
    When OnTriggerEnter is called compare the colliding GameObject to that static variable so you know to make it jump up or not.

    If you don't want to use a static variable, it will have to be a variable in a single script elsewhere.
     
    Last edited: Sep 26, 2018
    Avenged90x likes this.
  4. Avenged90x

    Avenged90x

    Joined:
    Sep 6, 2017
    Posts:
    35
    @BoogieD, Could you explain me that in code? Because I tried to do something like you wrote.. but with no results..
    Yes, I need to make a code, that only moving object / marked / clicked by mouse can jump over object, which it will encounter.
     
  5. BoogieD

    BoogieD

    Joined:
    Jun 8, 2016
    Posts:
    236
    In your script create a static variable so you can establish the GameObject that first moves. Being static, it will be a common variable to all objects that use the script.

    Code (CSharp):
    1. static GameObject firstMoved = null;
    Wherever your input code is to move the GameObject which is probably in Update(), set the static variable to the GameObject that has the script by using the variable 'gameObject' only if it has not already been set. This will ensure that only the first GameObject that moves will set the static variable.

    Code (CSharp):
    1. if (firstMoved  == null){
    2.    firstmoved = gameObject;  //gameObject has this script as a component.
    3. }
    Then in OnTriggerEnter() you need to test if gameObject is the same as the one in the static variable and if it is make it jump.

    Code (CSharp):
    1. if( gameObject == firstMoved ){
    2.    //make gameObject jump;
    3. }
     
    Avenged90x likes this.
  6. Avenged90x

    Avenged90x

    Joined:
    Sep 6, 2017
    Posts:
    35
    I know, that I'm weak at programming, but this mechanic blocking me for few days :(.. I tried that, what you suggested to me in my topic - but with no results.. Maybe I tried that in wrong places?
    I'll explain shortly how it works in my project:

    I have 2 scripts of movement. 1 script is only for detecting swipe gesture by mouse - for now, it detects only 4 directions. If it detect movement up (from down to the up, in Z axis [I have bird view in my game]) than swipe script assign MoveLeft to that swipe move(SwipeDirection.Left).

    Next, I have MovementControl script, where I have code, and mechanics of movement of my object (which have these scripts attached):

    Code (CSharp):
    1. if (SwipeMovement.Instance.IsSwiping(SwipeDirection.Right) && Tap == true)
    2.         {
    3.             newPosition = MoveRight;
    4.         }
    5.  
    6. Vector3 MoveRight = new Vector3(transform.position.x - 20f, transform.position.y, transform.position.z);
    7. transform.position = Vector3.Lerp(transform.position, newPosition, Time.deltaTime * smoothP);
    So it uses "SwipeDirection.Right" to activate Vector3 MoveRight function.

    Object goes right smooth (by using lerp) and correctly.

    And than, I have 3rd script, which is called SortingStack.cs. In this script Im trying to make that jumping mechanics with correct order - Like in Solitare game, or Building Lego by using flat bricks.. or whatever (I have idea for my game :)).

    I pasted your code lines, in that places:

    static GameObject firstMoved = null;
    -> in MovementControl.cs

    next in that script:


    if (SwipeMovement.Instance.IsSwiping(SwipeDirection.Right) && Tap == true && firstMoved == null)
    {
    newPosition = MoveRight;
    firstMoved = gameObject;
    }

    In SortingStack.cs scirpt:

    Code (CSharp):
    1. MovementControl3 firstMoved;
    2.  
    3. void OnTriggerEnter(Collider other)
    4.     {
    5.         if (other)
    6.         {
    7.             if (gameObject == firstMoved)
    8.                 {
    9.                    transform.position = new Vector3(transform.position.x, transform.position.y + 1.2f, transform.position.z);
    10.                    Debug.Log("Jump on Object");
    11.                 }
    12.         }
    13.     }
    But it doesn't work.. Probably i pasted that in wrong places.. :(
     
  7. Bill_Martini

    Bill_Martini

    Joined:
    Apr 19, 2016
    Posts:
    445
    You are using Lerp incorrectly. You seem to be struggling with coding, you might want to get a better grip on this subject before attempting your game. Also try this.gameObject instead of gameObject in your OnTriggerEnter function.
     
    Avenged90x likes this.
  8. BoogieD

    BoogieD

    Joined:
    Jun 8, 2016
    Posts:
    236
    Now I can see your code. it is probably the most recent GameObject that you swipe with mouse that you only want to be able to jump with a collision, not necessarily the first one that moves in the game. I renamed the static variable to 'selectedObject'. Keep it all in one script attached to the GameObject for simplicity.

    Code (CSharp):
    1.  
    2. public static GameObject selectedObject;
    3.  
    4. void Update()
    5. {
    6.     if (SwipeMovement.Instance.IsSwiping(SwipeDirection.Right) && Tap == true)
    7.     {
    8.         selectedObject = gameObject;    //Set the static variable to the gameObject that has this script.
    9.         newPosition = MoveRight;
    10.     }
    11.     Vector3 MoveRight = new Vector3(transform.position.x - 20f,
    12.     transform.position.y, transform.position.z);
    13.     transform.position = Vector3.Lerp(transform.position,
    14.     newPosition, Time.deltaTime * smoothP);
    15. }
    16.  
    17. void OnTriggerEnter(Collider other)
    18. {
    19.     if (other)
    20.     {
    21.         if (gameObject == selectedObject)
    22.         {
    23.             transform.position = Vector3(transform.position.x, transform.position.y + 1.2f, transform.position.z);
    24.             Debug.Log("Jump on Object");
    25.         )
    26.     }
    27. }
    28.  
    29.  
    You could make what you have with several scripts function as in your last code post by changing the line to:
    'if (gameObject == firstMoved.firstMoved)'
    Your naming creates confusion.

    You have an instance of the script object 'MovementControl3' named 'firstMoved' so change it's name to 'movementControl3' (lowercase 'm' in front) and make it public so you can drag the required GameObject with the same script into the Inspector field. Then access the static member variable via it. Also define the static variable public so you can access it from outside the object.
     
    Last edited: Oct 2, 2018
    Avenged90x likes this.
  9. Avenged90x

    Avenged90x

    Joined:
    Sep 6, 2017
    Posts:
    35
    Thank you BoogieD very much! Finally it works as i wanted :) ! I'm just want to make a little difficult stack system : For example, I have 3-4 objects on the scene / level And I can move any objects separately. When I move 1 if them to collide with another - that, which I moved (object 1) jumps on that object 2 (like you cover 1 card by another one). Then, when I move that object 1 back (out of collision space of object 2) it goes back to his previous position in Y axis.
    I made that using OnTriggerExit with if(gameObject == selectedObject) condition and it works perfectly :) !!!!
    But I'll try with more objects how it gonna work.

    Bill Martini.. right.. I had many issues with that lerp, like - object does'nt move for the same distance in every move, but it should :/ so for no i deleted that lerp. I will try LeanTween, which I'm using to smooth rotates for my object while moving them.
     
    Last edited: Oct 2, 2018
  10. BoogieD

    BoogieD

    Joined:
    Jun 8, 2016
    Posts:
    236
    I'm glad I could help.

    The last argument in lerp is a range from 0~1 to represent the progress between the start to end arguments.
    Lerp used in the way you are using it above will always just ease in to the target because as the remaining distance becomes less it will move a lesser amount each time with the same progress amount specified.

    Although more complex, you can use formulas to provide the progress amount.
    Smooth lerp which provides an 'ease out ~ ease in' is very useful.

    https://chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro/
     
    Bill_Martini likes this.
  11. Avenged90x

    Avenged90x

    Joined:
    Sep 6, 2017
    Posts:
    35
    Ok.. It works but...only with 2 objects :D .. So I can make stack from only 2 squares.. When I addes third square object.. it goes to the same position as second on on that stack.. I made void ontriggerExit, when objects goes back to begining position in Y axis, and it works properly, but I have to figure out, how to make stack from more objects :0..

    BoodieD, thank you :) I'll try that about lerp .. or just try with LeanTween, which i used to rotate these objects while moving.
     
    Last edited: Oct 2, 2018
  12. Bill_Martini

    Bill_Martini

    Joined:
    Apr 19, 2016
    Posts:
    445
    You should never use the value being Lerped within the Lerp arguments (in your case 'transform.position').

    In your jump code you only jump 1.2f above the object to be jumped. You need to calculate the number of blocks in the stack, multiply by block height, then add 1.2f or keep a reference to the top block in the stack, use it's height and then add the 1.2f.
     
  13. Avenged90x

    Avenged90x

    Joined:
    Sep 6, 2017
    Posts:
    35
    Bil_Martini I used 1.2f value for test, I changed it to 0,04f (thickness of the block is 0,05f) so now the block jumps almost on the block above him, to keep collision, and when I move it out - I use OnTriggerExit - and the block jumps off, back to the beginning position. But When I have stack of 2 objects, the third block don't wanna jump above the highest.. it just jump to the same position as second. I think its is something wrong with my script about collision / detecting collision. Calculating the number of blocks in stack is good way, but I will have more than 1 stack in my game.. So i think I sholud maybe try something easier - like "If blockA get collision with another object(blockB): move blockA to the position blockB.transform.position.y + 0.04f, then if blockA get another collision with new blockC (which is above/on the blockB) after first collision - move blockA above/on the blockC (blockC.transform.position.y + 0.04f). But for now I'm missing that second collision..

    edit. Now I checked: When I turn off TriggerExit - I can make stack of 3 objects..

    edit 2: I think, I did it! :) I made IsCollision bool, and as default - it is on false. But when OnTriggerStay -> IsCollision = true; And next, when OnTriggerExit -> IsCollision = false.
    And in Update func I made:

    if (IsCollision == false)
    {
    transform.position = new Vector3(transform.position.x, -980, transform.position.z);
    }


    And it works perfetcly !!! :) I can make stack with more than 2 objects!!! :D :D :D
     
    Last edited: Oct 3, 2018