Search Unity

Moving platform causes player to grow

Discussion in '2D' started by devonjacobsen, Feb 15, 2016.

  1. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    Hello, a quick problem I'm having in my game is that, I followed a youtube tutorial on how to make a moving platform and the platform works, and does everything properly in terms of moving, but when I touch it and move on it, it stretches the player, and I cannot flip on it, as I can in the rest of the level. Here's the entire Moving Platform Script, and the script that's supposed to keep the player in place with it as it moves, which I think it also doesn't do still.
    Code (CSharp):
    1. // Moving Platform Script
    2.  
    3. public Transform movingPlatform;
    4.     public Transform Pos1;
    5.     public Transform Pos2;
    6.     public Vector2 newPosition;
    7.     public string currentState;
    8.     public float smooth;
    9.     public float resetTime;
    10.  
    11.     // Use this for initialization
    12.     void Start ()
    13.     {
    14.         ChangeTarget();
    15.     }
    16.    
    17.     // Update is called once per frame
    18.     void FixedUpdate ()
    19.     {
    20.         movingPlatform.position = Vector2.Lerp(movingPlatform.position, newPosition, smooth * Time.deltaTime);
    21.     }
    22.  
    23.     void ChangeTarget()
    24.     {
    25.         if (currentState == "Moving To Position 1")
    26.         {
    27.             currentState = "Moving To Position 2";
    28.             newPosition = Pos2.position;
    29.  
    30.         }
    31.         else if (currentState == "Moving To Position 2")
    32.         {
    33.             currentState = "Moving To Position 1";
    34.             newPosition = Pos1.position;
    35.         }
    36.         else if(currentState == "")
    37.         {
    38.             currentState = "Moving To Position 2";
    39.             newPosition = Pos2.position;
    40.         }
    41.  
    42.         Invoke("ChangeTarget", resetTime);
    43.     }
    44.  
    Code (CSharp):
    1. //Hold Character Script
    2.  
    3. void OnTriggerEnter2D(Collider2D col)
    4.     {
    5.         col.transform.parent = gameObject.transform; // when something collides, making object move with object with parenting
    6.     }
    7.  
    8.     void OnTriggerExit2D(Collider2D col)
    9.     {
    10.         col.transform.parent = null; // unparent object when exiting collider
    11.     }
     
  2. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    This probably is not a good way to handle this, as it is assigning the parent of your character as the platform. This does allow the characters position to move along with the platform as it moves, but creates the issue of warping around values of the characters original transform. I suppose I can't say for sure what would work without knowing how the character is setup, but what you probably need to do, is instead of changing the parent in ontriggerenter and ontriggerexit, set a bool to true (like _isOnPlatform) within the characterscript, and then set it as false when on trigger exit is called. Then in your characters update, if your on the platform, add the platforms motion on top of whatever motion is already happening. I can't really share an example script of this, but basically you could calculate the speed your platform, and then manually add or subtract that amount from the position of your character for as long as they are still on the platform.
     
    Last edited: Feb 15, 2016
  3. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    I did the first part of what you said, but I'm a bit too beginner to do the second part without any code examples. So when you say, "characters update" , do you mean my character controller scripts update function? And do you have any guidance or anything on how I could go about adding the platforms motion, and calculating it and all that? Sorry, I know you said you couldn't really give an example, but any more guidance could go a long way! Thanks again!

    Edit: Would posting my character controller script help?
     
  4. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Yes the characters script, in the update method, keep track of your bool (IDK why today I am using underscores as examples) _isOnPlatform, and if it becomes true, then maybe add just a hardcoded amount to his position. Sorta like this (probably won't work without modification):

    Code (csharp):
    1.  
    2. // inside Update method of characters script ***
    3. float platformMoveSpeed = 0.5f; // adjust this until it mostly seems accurate
    4.  
    5. if(_isOnPlatform) // we are in the trigger zone for the platform! react!
    6. {
    7. // NOTE: your going to have to determine which way the platform is moving, either by keeping track of that in the platform
    8. // script, or literally measuring it through some comparison math, so you can decide to either add or subtract this amount!
    9.   transform.position = Quaternion.Euler(transform.position.x + platformMoveSpeed, transform.position.y, transform.position.z);
    10. // in the above example we are adding to the X position of the character object, and that means we look like we are
    11. // moving to the right, assuming the character moves on his x axis, and the camera faces positive z axis.
    12. }
    13.  
    14. // then continue the normal update stuff after this check...
    15.  
     
  5. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    Ok I'm sorry, probably very stupid question but, just so I dont get mixed up. Do you mean put it in the character holder script, moving platform script, or (if im right in thinking this) put it in the characters controller script, as in the script that controls his movements and stuff like that? And I'm guessing to use isOnPlatform in that I'd have to create it? I hope you understand, thanks. lol
     
  6. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    The _isOnPlatform variable, and the update part in the character "movement" script, whatever you want really that is attached to the character, ideally wherever your doing movement code to begin with.

    I suppose you already have the part with the trigger code in the right place, but need to change the lines that make the parent of the characters object the platform object, and instead set _isOnPlatform to true, or to false when leaving the trigger.
     
  7. Ferb

    Ferb

    Joined:
    Jan 4, 2014
    Posts:
    25
    I'd suggest that you change your platform update function to something more like this:

    Code (CSharp):
    1. void FixedUpdate()
    2. {
    3.     movingPlatform.getComponent<Rigidbody2d>().movePosition(Vector2.Lerp(movingPlatform.position, newPosition, smooth * Time.deltaTime));
    4. }
    (Ideally you should store the Rididbody2d variable during the Start() function for better performance, but this is just for demonstration.) Theoretically, moving it using the movePosition function of the rigidbody means that physics will be taken into account, whereas just assigning to the position of the transform means it will ignore physics while moving the object. By having physics taking into account while moving your platform, it should exert some force on your character automatically - depending on what shape and materials the character and platform have (i.e. how much friction there is between them), that may have the desired effect without you needing to do any further work.
     
  8. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30

    Thank you for the help Ferb, trying to put in your code, but it shows an error message at the getComponent<Rigidbody2D> and this is the error:

    Error CS1061 'Transform' does not contain a definition for 'getComponent' and no extension method 'getComponent' accepting a first argument of type 'Transform' could be found (are you missing a using directive or an assembly reference?) Rectangular Space.CSharp C:\Users\Devon\Documents\Unity Games\Rectangular Space\Assets\Scripts\MovingPlatform.cs 24 Active
     
  9. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Try this:

    Code (CSharp):
    1. void FixedUpdate()
    2. {
    3.     movingPlatform.gameObject.getComponent<Rigidbody2d>().movePosition(Vector2.Lerp(movingPlatform.position, newPosition, smooth * Time.deltaTime));
    4. }
     
  10. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    MD, now movePosition shows an error : upload_2016-2-16_12-30-28.png
     
  11. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Code (CSharp):
    1.     void FixedUpdate()
    2.     {
    3.         movingPlatform.gameObject.GetComponent<Rigidbody2D>().MovePosition(Vector2.Lerp(movingPlatform.position, newPosition, smooth * Time.deltaTime));
    4.     }
    That should work, sorry was doing that offhand and didn't notice capitalization problems!
     
  12. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    Hey guys it works, but the platform is super slow and shaky, and wants to move up and down? But kinda also moves to the left? Any ideas?
     
  13. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Maybe change the value of "smooth" and see if higher or lower values change the... smoothness? I didn't actually try out the code so I'm not sure how it acts, but let's see what changing the values does...

    Oh also make sure gravity doesn't have an effect on the rigidbody of the platform!

    FYI the smooth and delta time part is what dictates how fast it transitions from the current position, to the "lerped" position. If that value comes out higher than 1, it's one, and if lower than 0, it's 0. 1 would be very fast, 0 almost not moving.

    I'll just ramble some more... let's see, you should have an if statement that checks if it's reached "newPosition" yet, and if so, reverse and go back to the other direction (if you want that). And as you should always do, use debug statements to find problems, like do "Debug.Log (smooth * Time.deltaTime);" to see what it's coming out as, and you'd put that in right after you actually use the values so you are current.
     
    Last edited: Feb 17, 2016
  14. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30

    Ok so, I got it to move and go perfectly, but it won't go back, and obviously I need an if statement, but I'm a bit confused, my if statement has no errors, but its not doing anything, if you could just help with this last part it'd be a life saver thanks!
    Code (CSharp):
    1. if (movingPlatform.position.x == 8.5)
    2.         {
    3.             movingPlatform.gameObject.GetComponent<Rigidbody2D>().MovePosition(Vector2.Lerp(-movingPlatform.position, -newPosition, -smooth / -Time.deltaTime));
    4.         }
     
  15. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    I think I see the problem, your checking if the x is exactly equal to 8.5, however, it probably never exactly hits 8.5, so check instead if it's equal or greater than 8.5 ( use >= instead of == ) and that will probably work! Oh also, 8.5 is a double, while 8.5f is a float, and you should probably use a float! Good luck!

    Edit: oh also, you shouldn't need negative numbers for delta time and stuff, the same positive logic should work both ways.... I think... just make sure the "go to" position changes to the opposite direction. Like a way point at the far left and far right of the platforms movement path, maybe called leftNewPosition, and rightNewPosition. Definitely don't use a negative transform.position for the platform as that'll give you... strange results...

    Example:

    Code (CSharp):
    1.  // NOTICE: Non working code! :D
    2.        
    3.         if (movingPlatform.position.x >= 8.5f)
    4.         {
    5.             movingPlatform.gameObject.GetComponent<Rigidbody2D>().MovePosition(Vector2.Lerp(movingPlatform.position, newPosition, smooth * Time.deltaTime));
    6.         }
    7.         else if (movingPlatform.position.x <= -8.5f)
    8.         {
    9.             movingPlatform.gameObject.GetComponent<Rigidbody2D>().MovePosition(Vector2.Lerp(movingPlatform.position, otherNewPosition, smooth * Time.deltaTime));
    10.         }
    11.  
    Edit2: and to explain that "Lerp" method further, the first argument is the starting position, the second argument is the destination (go to) position, and the third argument is how fast to get there... so it's clamped between 0 and 1, with 0 being almost no movement at all, and 1 being very very fast movement, almost instantly. When you use that method in fixedupdate like we're using it in these examples, where you multiply the last argument with delta time, what that basically does is take the "smooth" value, and multiply it by the fixed time step (because your doing it in fixed update, which happens once every fixed timestamp) and if you did it in the Update method instead, it would be multiplying by how much time has passed since the last frame... it's hard to explain but basically it's giving you smooth movement because it's "lerping" between the actual objects position, and fractionally closer to the destination each frame, eventually reaching (or very close to) the destination.

    Edit3: it's occuring to me I'm thinking about it backwards and that example above won't work, because it's trying to move it on above 8.5f or below -8.5f, when in fact we want to "switch" directions once it reaches those positions. Give me a few minutes to run to the store here, and I'll give you a working example.
     
    Last edited: Feb 19, 2016
  16. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    Ok thanks so much for your explanation! I really understand now, and it will definitely help in the future with similar problems! Can't wait to finally have this platform up and running properly! One problem I've run into still is it still doesn't keep the player stuck to it but, I could just make that a game mechanic, but if you had any tips on fixing it, that'd about solve every platform problem I have, thanks again!
     
  17. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Ok, I think this might do the trick:

    Code (CSharp):
    1.  
    2. // these parts at the top of the script
    3.         Vector3 targetPositionLeft;
    4.         Vector3 targetPositionRight;
    5.         bool switchDirection = false;
    6.         Rigidbody2D platformRigidbody;
    7.  
    8. // this part in the Start() method obviously (just to keep from needing to get this reference every frame)
    9.     void Start()
    10.     {
    11.        platformRigidbody = movingPlatform.gameObject.GetComponent<Rigidbody2D>();
    12.        targetPositionLeft = new Vector3(-5, transform.position.y, transform.position.z); // here you wanna change the -5 value to be your "ending" positions of its movement far left
    13.        targetPositionRight = new Vector3(5, transform.position.y, transform.position.z; // and here it would be the spot far right where you want it to stop
    14.     } // GetComponent is costly performancewise, because it has to go and "find" this rigidbody anytime you call this, so instead lets keep a reference to it like this ^
    15.  
    16.  
    17. // these parts inside FixedUpdate() or Update()
    18.         if (movingPlatform.position.x >= targetPositionRight.x && !switchDirection)
    19.         {
    20.             switchDirection = true;
    21.         }
    22.         else if (movingPlatform.position.x <= targetPositionLeft.x && switchDirection)
    23.         {
    24.             switchDirection = false;
    25.         }
    26.  
    27.         if(switchDirection) // were going to the left!
    28.             platformRigidbody.MovePosition(Vector2.Lerp(movingPlatform.position, targetPositionLeft, smooth * Time.deltaTime));
    29.         else
    30.             platformRigidbody.MovePosition(Vector2.Lerp(movingPlatform.position, targetPositionRight, smooth * Time.deltaTime));
    31.  
    Now as far as moving the character to match... let me think a bit, I might have an idea that could work for that. Let's see if this part works first.

    EDIT: I made some changes to cache a reference to the rigidbody, so make sure your using the latest edit!
     
    Last edited: Feb 19, 2016
  18. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    upload_2016-2-18_22-22-14.png

    I inserted your code but I got this error!
     
  19. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Ooops, my bad, the variables should not be assigned from the top of the script (the target position ones). Instead they have to be assigned once the script is running...

    So just make that part end after the name (like "Vector3 targetPositionLeft;") and then in the Start method, put "targetPositionLeft = ..." and the right one as well. My fault - didnt actually test any of that code :p

    EDIT: Oh and because your actually using this on the moving platform, you don't need to use "movingPlatform.position", but rather just transform.position!

    EDIT2: I went ahead and updated the last post with correct code... which.... should work :D
     
    Last edited: Feb 19, 2016
  20. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    Ok I inserted your code, and no errors, but it still doesn't move back.

    Edit: would it possibly be the vector3 because Im making a 2D game and use all vector2's? I don't think it would since it still has x, and y that can be moved, and it doesn't matter as long as the z isn't changed(?)
     
    Last edited: Feb 19, 2016
  21. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Vector3's get along with most 2d methods ive used, I suppose it couldn't hurt to make them V2's instead just for simplicity sake.

    Anyway so it does transition to one side of the "path", stops, but doesn't come back to the other side? Ok well then, seems we need to Debug.Log! Try this first:

    Code (CSharp):
    1. if (movingPlatform.position.x >= targetPositionRight.x && !switchDirection)
    2.         {
    3.             switchDirection = true;
    4.            Debug.Log("switchDirection = " + switchDirection);
    5.         }
    6.         else if (movingPlatform.position.x <= targetPositionLeft.x && switchDirection)
    7.         {
    8.             switchDirection = false;
    9.            Debug.Log("switchDirection = " + switchDirection);
    10.         }
    11.         if(switchDirection) // were going to the left!
    12.             platformRigidbody.MovePosition(Vector2.Lerp(movingPlatform.position, targetPositionLeft, smooth * Time.deltaTime));
    13.         else
    14.             platformRigidbody.MovePosition(Vector2.Lerp(movingPlatform.position, targetPositionRight, smooth * Time.deltaTime));
    This will tell us what's going on with that boolean, and tell us if it is switching properly. What do you set the target positions to? And where does the platform start at? If it starts somewhere between the targets for its X position, it should work, doesn't have to be the perfect middle or anything, just so that it'll work. And obviously to put these into many places in a game, your gonna want to make the targets public variables probably... they don't need to be vectors at all, could just be floats or even integers, then you position it wherever, and add or subtract from the starting position to make it much easier to create more without hard coding each one :D
     
  22. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    I put in the debug, but nothing is showing up in the debug part! .-. And the platform starts off at -2.5, so maybe that affects it? I want it to go from -2.5, over to 8.5, and back basically over, and over obviously. Thanks for all the explanations and help! Finding a modern version of building anything in Unity 5 is getting more and more difficult with each update!
     
  23. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    Update: Ok I swapped the values, since it starts at a negative, and the debug started to work, so I think it's just the values lemme play around and see if it fixes itself, the bool seems to be working right even with the values messed up! We may have got it!

    Update 2: Nevermind still confused of course! If you could help fix the code for going from my certain points thatd be great! I think I've almost got it!
     
    Last edited: Feb 19, 2016
  24. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    I think this would allow it to work regardless of where you put the initial positions:

    Code (CSharp):
    1.  
    2. // these parts at the top of the script
    3. // this top variable appears in the inspector in unity, so you can change it for each platform
    4.     public float MoveDistance = 5.0f; // can be changed in inspector, if its changed here, objects with the script already attached won't update the value!
    5.     private Vector3 targetPositionLeft;
    6.     private Vector3 targetPositionRight;
    7.     bool switchDirection = false;
    8.     Rigidbody2D platformRigidbody;
    9.  
    10.     // this part in the Start() method obviously (just to keep from needing to get this reference every frame)
    11.     void Start()
    12.     {
    13.         platformRigidbody = GetComponent<Rigidbody2D>();
    14.         targetPositionLeft = new Vector3(transform.position.x - MoveDistance, transform.position.y, transform.position.z); // here you wanna change the -5 value to be your "ending" positions of its movement far left
    15.         targetPositionRight = new Vector3(transform.position.x + MoveDistance, transform.position.y, transform.position.z; // and here it would be the spot far right where you want it to stop
    16.     } // GetComponent is costly performancewise, because it has to go and "find" this rigidbody anytime you call this, so instead lets keep a reference to it like this ^
    17.  
    18.  
    19.     // these parts inside FixedUpdate() or Update()
    20.     void FixedUpdate()
    21.     {
    22.         // this section hasn't changed since last posted version
    23.         if (transform.position.x >= targetPositionRight.x && !switchDirection)
    24.         {
    25.             switchDirection = true;
    26.         }
    27.         else if (transform.position.x <= targetPositionLeft.x && switchDirection)
    28.         {
    29.             switchDirection = false;
    30.         }
    31.  
    32.         if (switchDirection) // were going to the left!
    33.             platformRigidbody.MovePosition(Vector2.Lerp(transform.position, targetPositionLeft, smooth * Time.deltaTime));
    34.         else
    35.             platformRigidbody.MovePosition(Vector2.Lerp(transform.position, targetPositionRight, smooth * Time.deltaTime));
    36.     }
     
  25. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    Now it doesn't move at all??
     
  26. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Hrmmm.... try this:

    Code (CSharp):
    1.  
    2. // these parts at the top of the script
    3.     // this top variable appears in the inspector in unity, so you can change it for each platform
    4.     public float MoveDistance = 5.0f;
    5.     private Vector3 targetPositionLeft;
    6.     private Vector3 targetPositionRight;
    7.     bool switchDirection = false;
    8.     Rigidbody2D platformRigidbody;
    9.  
    10.     private float smooth = 5.5f; // perhaps adjust? - math is: 5.5 * 0.02 (default unity Fixed Timestep) = 0.11f - which moves slowly
    11.  
    12.     // this part in the Start() method
    13.     void Start()
    14.     {
    15.         platformRigidbody = GetComponent<Rigidbody2D>();
    16.         targetPositionLeft = new Vector3(transform.position.x - MoveDistance, transform.position.y, transform.position.z); // here you wanna change the -5 value to be your "ending" positions of its movement far left
    17.         targetPositionRight = new Vector3(transform.position.x + MoveDistance, transform.position.y, transform.position.z); // and here it would be the spot far right where you want it to stop
    18.     } // GetComponent is costly performancewise, because it has to go and "find" this rigidbody anytime you call this, so instead lets keep a reference to it like this ^
    19.  
    20.  
    21.     // these parts inside FixedUpdate() or Update()
    22.     void FixedUpdate()
    23.     {
    24.         // this section hasn't changed since last posted version
    25.         if (transform.position.x >= targetPositionRight.x && !switchDirection)
    26.         {
    27.             switchDirection = true;
    28.             Debug.Log("Setting switchDirection to TRUE");
    29.         }
    30.         else if (transform.position.x <= targetPositionLeft.x && switchDirection)
    31.         {
    32.             switchDirection = false;
    33.             Debug.Log("Setting switchDirection to FALSE");
    34.         }
    35.  
    36.         if (switchDirection) // were going to the left!
    37.         {
    38.             Debug.Log("Moving Left");
    39.             platformRigidbody.MovePosition(Vector2.Lerp(transform.position, targetPositionLeft, smooth * Time.deltaTime));
    40.         }
    41.         else
    42.         {
    43.             platformRigidbody.MovePosition(Vector2.Lerp(transform.position, targetPositionRight, smooth * Time.deltaTime));
    44.             Debug.Log("Moving Right");
    45.         }
    46.     }
    47.  
     
  27. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    Now it says "Moving Right" forever. From beginning and doesn't change, but the platform now only moves a cenimeter and stops, but it still says moving right. Well I don't know if it truly stops moving but, I hope you understand.
     
  28. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    Here's my code, don't mind the random commented variables, I'm just commenting them out until I final get this working in case I end up needing them or something:

    Code (CSharp):
    1. public float MoveDistance = 5.0f;
    2.     public Transform movingPlatform;
    3.     // these parts at the top of the script
    4.     private Vector2 targetPositionLeft;
    5.     private Vector2 targetPositionRight;
    6.     bool switchDirection = false;
    7.     Rigidbody2D platformRigidbody;
    8.     //public Transform Pos1;
    9.     //public Transform Pos2;
    10.     //public Vector2 newPosition;
    11.     //public string currentState;
    12.     //public float resetTime;
    13.     //public Transform movePosition;
    14.     private float smooth = 5.5f; // perhaps adjust? - math is: 5.5 * 0.02 (default unity Fixed Timestep) = 0.11f - which moves slowly
    15.  
    16.     // Use this for initialization
    17.     void Start()
    18.     {
    19.         platformRigidbody = GetComponent<Rigidbody2D>();
    20.         targetPositionLeft = new Vector2( transform.position.x - MoveDistance, transform.position.y); // here you wanna change the -5 value to be your "ending" positions of its movement far left
    21.         targetPositionRight = new Vector2( transform.position.x + MoveDistance, transform.position.y); // and here it would be the spot far right where you want it to stop
    22.     } // GetComponent is costly performancewise, because it has to go and "find" this rigidbody anytime you call this, so instead lets keep a reference to it like this ^
    23.  
    24.     void FixedUpdate() {
    25.      
    26.         // these parts inside FixedUpdate() or Update()
    27.         if (transform.position.x >= targetPositionRight.x && !switchDirection)
    28.         {
    29.             switchDirection = true;
    30.             Debug.Log("Setting switchDirection to TRUE" + switchDirection);
    31.         }
    32.         else if (transform.position.x <= targetPositionLeft.x && switchDirection)
    33.         {
    34.             switchDirection = false;
    35.             Debug.Log("Setting switchDirection to FALSE" + switchDirection);
    36.         }
    37.  
    38.         if (switchDirection) // were going to the left!
    39.         {
    40.             Debug.Log("Moving Left");
    41.             platformRigidbody.MovePosition(Vector2.Lerp(transform.position, targetPositionLeft, smooth * Time.deltaTime));
    42.         }
    43.         else
    44.         {
    45.            
    46.             platformRigidbody.MovePosition(Vector2.Lerp(transform.position, targetPositionRight, smooth * Time.deltaTime));
    47.             Debug.Log("Moving Right");
    48.         }
    49.     }
    50.  
    51.     }
     
  29. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Ok, try this, I added a little bit of a offset for the comparison of positions, so maybe that'll work. Be sure to try changing smooth, and distance values, to see if that gets it moving...

    Code (CSharp):
    1.     public float MoveDistance = 5.0f;
    2.     public Transform movingPlatform;
    3.     // these parts at the top of the script
    4.     private Vector2 targetPositionLeft;
    5.     private Vector2 targetPositionRight;
    6.     bool switchDirection = false;
    7.     Rigidbody2D platformRigidbody;
    8.     //public Transform Pos1;
    9.     //public Transform Pos2;
    10.     //public Vector2 newPosition;
    11.     //public string currentState;
    12.     //public float resetTime;
    13.     //public Transform movePosition;
    14.     private float smooth = 5.5f; // perhaps adjust? - math is: 5.5 * 0.02 (default unity Fixed Timestep) = 0.11f - which moves slowly
    15.  
    16.     // Use this for initialization
    17.     void Start()
    18.     {
    19.         platformRigidbody = GetComponent<Rigidbody2D>();
    20.         targetPositionLeft = new Vector2(transform.position.x - MoveDistance, transform.position.y); // here you wanna change the -5 value to be your "ending" positions of its movement far left
    21.         targetPositionRight = new Vector2(transform.position.x + MoveDistance, transform.position.y); // and here it would be the spot far right where you want it to stop
    22.     } // GetComponent is costly performancewise, because it has to go and "find" this rigidbody anytime you call this, so instead lets keep a reference to it like this ^
    23.  
    24.     void FixedUpdate()
    25.     {
    26.  
    27.         // these parts inside FixedUpdate() or Update()
    28.         if (transform.position.x >= targetPositionRight.x - 0.01f && !switchDirection)
    29.         {
    30.             switchDirection = true;
    31.             Debug.Log("Setting switchDirection to TRUE" + switchDirection);
    32.         }
    33.         else if (transform.position.x <= targetPositionLeft.x + 0.01f && switchDirection)
    34.         {
    35.             switchDirection = false;
    36.             Debug.Log("Setting switchDirection to FALSE" + switchDirection);
    37.         }
    38.  
    39.         if (switchDirection) // were going to the left!
    40.         {
    41.             Debug.Log("Moving Left");
    42.             platformRigidbody.MovePosition(Vector2.Lerp(transform.position, targetPositionLeft, smooth * Time.deltaTime));
    43.         }
    44.         else
    45.         {
    46.  
    47.             platformRigidbody.MovePosition(Vector2.Lerp(transform.position, targetPositionRight, smooth * Time.deltaTime));
    48.             Debug.Log("Moving Right");
    49.         }
    50.     }
     
  30. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    Ok I figured out the problem, I had it inside the MovingPlatform game object still, and it was only moving the object, not the platform, but the problem now, is the character holder that I previous had attached,a invisible box collider, will no longer work attached to the platform, so I obviously need a way to keep the player attached, but still able to move and jump and flip on it. Thanks for all the help! Sorry for all the stupid mistakes and things. Getting this last part to work would cement me for everything.

    Update: How do I set where it lands back after going back to the left. The distance moves it to the right? So what sets where it goes back to the left?
     
  31. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    I don't totally understand, do you mean the character isn't colliding with the platform? Or just that the character isn't moving along with it?
     
  32. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    Never mind I fixed it, it was my own mistake. Anyhow, how would I go about making the character tag along with the platform, but still be able to do all his functions, and things while on the platform?
     
  33. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Is your character based on a rigidbody2d? You use forces to move left and right? Or character controller of some kind?
     
  34. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    My character has a rigidbody 2d, and a script that controls it's movement, so I'm not sure what you mean, but here is the character controller script:
    Code (CSharp):
    1. //private float direction = 1; //  or -1, depending which way you want the sprite pointing.
    2.  
    3.     private Vector2 localScale;
    4.  
    5.     //Movement
    6.     public float speed;
    7.     public float jump;
    8.     float moveVelocity;
    9.     bool _isStanding = true;
    10.  
    11.     //bool isOnPlatform = false;
    12.     public float platformMoveSpeed = 0.5f; //for platform
    13.  
    14.     //Grounded Variables
    15.     bool grounded = true;
    16.  
    17.     // Update is called once per frame
    18.     void Update()
    19.     {
    20.         //Jumping
    21.         if (Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.W))
    22.         {
    23.             if (grounded)
    24.             {
    25.                 GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x, jump);
    26.             }
    27.         }
    28.  
    29.         moveVelocity = 0;
    30.  
    31.         //Left & Right Movement
    32.  
    33.         if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A))
    34.         {
    35.             moveVelocity = -speed;
    36.         }
    37.  
    38.         if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D))
    39.         {
    40.             moveVelocity = speed;
    41.         }
    42.  
    43.         GetComponent<Rigidbody2D>().velocity = new Vector2(moveVelocity, GetComponent<Rigidbody2D>().velocity.y);
    44.  
    45.         // Flip
    46.  
    47.  
    48.         if (Input.GetKeyDown(KeyCode.F))
    49.         {
    50.  
    51.             if(_isStanding)
    52.             {
    53.                 GetComponent<Transform>().eulerAngles = new Vector3( 0, 0, 0);
    54.                 _isStanding = false;
    55.                 //Debug.Log("1");
    56.             }
    57.             else
    58.             {
    59.                 GetComponent<Transform>().eulerAngles = new Vector3(0, 0, 90);
    60.                 _isStanding = true;
    61.                 //Debug.Log("2");
    62.             }
    63.        }
    64. }
    65.      
    66.     // Check If Grounded
    67.  
    68.     void OnTriggerEnter2D()
    69.     {
    70.         grounded = true;
    71.  
    72.     }
    73.  
    74.     void OnTriggerExit2D()
    75.     {
    76.         grounded = false;
    77.  
    78.     }
     
  35. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Okay, well you are setting the velocity of the rigidbody, which is sort of what I thought you might have going on. Since you use triggers for grounding your player (probably not the best idea, as you'll have to put triggers everywhere in you game that you can walk...) there is something you could do to just add some more speed when your on a platform.

    Try putting a tag on the platforms (create a tag by selecting a platform, and in the inspector top right, there's a drop down for tags, hit create or edit tags or something there) that identifies it, could just be "platform", then make sure to set all platforms to have that tag.

    Once it's tagged, when your checking for whether or not your grounded, also check if the trigger your entered in has the platform tag, and if it does, add it's velocity to your character. I'm not sure it'll work perfectly but it's worth a shot.

    (I'll edit and add some code here in a minute)
     
  36. devonjacobsen

    devonjacobsen

    Joined:
    Nov 12, 2015
    Posts:
    30
    Ok thanks! c:
     
  37. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Alright I don't know if this will work, but here try changing this:

    Code (CSharp):
    1.     void OnTriggerEnter2D(Collider2D other)
    2.     {
    3.         grounded = true;
    4.         if(other.gameObject.tag == "platform")
    5.         {
    6.             moveVelocity = moveVelocity + other.gameObject.GetComponent<Rigidbody2D>().velocity.x; // add the velocity off the rigidbody
    7.         }
    8.     }
    You will have to "tag" the platform with the "platform" tag, for this to work (without the quotes when you create the tag)

    EDIT: it is occurring to me, this will probably keep accelerating the velocity of your character. If this works I'll change it to first compare the speeds and see if they match.

    EDIT2: might try just doing moveVelocity.x = the velocty.x of the rigidbody...
     
    Last edited: Feb 20, 2016
  38. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Any luck?
     
  39. Pkbiggums

    Pkbiggums

    Joined:
    Mar 19, 2013
    Posts:
    12
    I don't know if you guys have figured this out yet, but I actually just made a moving platform script today, I'll post it for you if you need it.

    Platform Script:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class MovingPlatform : MonoBehaviour {
    5.  
    6.     public Transform[] spots;
    7.     private int numberOfSpots;
    8.     public bool moveFrontToBack;
    9.     public float moveSpeed;
    10.     public float waitTime;
    11.     private float delay;
    12.     private int nextSpot;
    13.     private bool goForward;
    14.  
    15.     void Start()
    16.     {
    17.         gameObject.transform.position = spots [0].transform.position;
    18.         numberOfSpots = spots.Length;
    19.         nextSpot = 0;
    20.         delay = waitTime;
    21.         goForward = true;
    22.     }
    23.     void Update()
    24.     {
    25.         // moves object to next point
    26.         gameObject.transform.position = Vector3.MoveTowards (gameObject.transform.position, spots[nextSpot].transform.position, moveSpeed * Time.deltaTime);
    27.  
    28.         // starts delay timer when at assigned point
    29.         if (gameObject.transform.position == spots [nextSpot].transform.position && delay > 0)
    30.         {
    31.             delay -= Time.deltaTime;
    32.         }
    33.         // Move from point a to b to c to b to a
    34.         if (moveFrontToBack) {
    35.             // assigns next point
    36.             if (delay <= 0 && gameObject.transform.position == spots [nextSpot].transform.position && goForward) {
    37.                 nextSpot += 1;
    38.                 delay = waitTime;
    39.             }
    40.  
    41.             if (delay <= 0 && gameObject.transform.position == spots [nextSpot].transform.position && !goForward) {
    42.                 nextSpot -= 1;
    43.                 delay = waitTime;
    44.             }
    45.             // checks if at the end of trail or beginging
    46.             if (nextSpot == numberOfSpots - 1) {
    47.                 goForward = false;
    48.             }
    49.             if (nextSpot == 0) {
    50.                 goForward = true;
    51.             }
    52.         }
    53.         // once the platform reaches the final spot, go back to the first spot
    54.         if (!moveFrontToBack)
    55.         {
    56.             // assigns next point
    57.             if (delay <= 0 && gameObject.transform.position == spots [nextSpot].transform.position) {
    58.                 nextSpot += 1;
    59.                 delay = waitTime;
    60.             }
    61.             if (nextSpot == numberOfSpots)
    62.             {
    63.                 nextSpot = 0;
    64.             }
    65.         }
    66.     }
    67. }
    68.  
    Put that on your platform (Note, make sure the scale on the object is 1,1,1)

    Then you need to put this on your player:
    Code (CSharp):
    1.     void OnTriggerEnter2D(Collider2D other)
    2.     {
    3.         if (other.gameObject.CompareTag ("Platform"))
    4.         {
    5.             transform.parent = other.transform;
    6.         }
    7.     }
    8.     void OnTriggerExit2D(Collider2D other)
    9.     {
    10.         if (other.gameObject.CompareTag ("Platform"))
    11.         {
    12.             transform.parent = null;
    13.         }
    14.     }
    Then just set the tag for the platform to "Platform" and you should be clear!

    Quick explanation on how to use my script.



    Be sure to have the scale of the object set to 1 1 1, if you want to scale it put your graphics in the children with no colliders.

    Set the size to how ever many places you want your platform to move to, then drag them into place in order.

    Untick move front to back if you want the platform to move to the first point after reaching the last.

    Set your move speed and wait time to how ever much you like and enjoy!

    Hope I could help.
     
  40. Pkbiggums

    Pkbiggums

    Joined:
    Mar 19, 2013
    Posts:
    12
    Oh and the trigger should the area above the platform, make that as large as you want, if your player is in it it will move with the platform.
     
  41. FlavioVolpeJr

    FlavioVolpeJr

    Joined:
    Jun 11, 2020
    Posts:
    7
    I improved the code of the Pkbiggums. Attach Player is now built into the script.


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class MovePlatformWaypoints1 : MonoBehaviour
    4. {
    5.    
    6.     [Tooltip("Object Active?")]
    7.     public bool activated;
    8.     [Tooltip("Attaches the player to the platform.")]
    9.     public bool attachPlayer;
    10.     public Transform[] spots;
    11.     private int numberOfSpots;
    12.     public bool moveFrontToBack;
    13.     public float moveSpeed;
    14.     public float waitTime;
    15.     private float delay;
    16.     private int nextSpot;
    17.     private bool goForward;
    18.  
    19.     new void Start()
    20.     {
    21.         gameObject.transform.position = spots[0].transform.position;
    22.         numberOfSpots = spots.Length;
    23.         nextSpot = 0;
    24.         delay = waitTime;
    25.         goForward = true;
    26.     }
    27.     void FixedUpdate()
    28.     {
    29.         // moves object to next point
    30.         if (activated == true)
    31.            gameObject.transform.position = Vector3.MoveTowards(gameObject.transform.position, spots[nextSpot].transform.position, moveSpeed * Time.deltaTime);
    32.  
    33.         // starts delay timer when at assigned point
    34.         if (gameObject.transform.position == spots[nextSpot].transform.position && delay > 0)
    35.         {
    36.             delay -= Time.deltaTime;
    37.         }
    38.         // Move from point a to b to c to b to a
    39.         if (moveFrontToBack)
    40.         {
    41.             // assigns next point
    42.             if (delay <= 0 && gameObject.transform.position == spots[nextSpot].transform.position && goForward)
    43.             {
    44.                 nextSpot += 1;
    45.                 delay = waitTime;
    46.             }
    47.  
    48.             if (delay <= 0 && gameObject.transform.position == spots[nextSpot].transform.position && !goForward)
    49.             {
    50.                 nextSpot -= 1;
    51.                 delay = waitTime;
    52.             }
    53.             // checks if at the end of trail or beginging
    54.             if (nextSpot == numberOfSpots - 1)
    55.             {
    56.                 goForward = false;
    57.             }
    58.             if (nextSpot == 0)
    59.             {
    60.                 goForward = true;
    61.             }
    62.         }
    63.         // once the platform reaches the final spot, go back to the first spot
    64.         if (!moveFrontToBack)
    65.         {
    66.             // assigns next point
    67.             if (delay <= 0 && gameObject.transform.position == spots[nextSpot].transform.position)
    68.             {
    69.                 nextSpot += 1;
    70.                 delay = waitTime;
    71.             }
    72.             if (nextSpot == numberOfSpots)
    73.             {
    74.                 nextSpot = 0;
    75.             }
    76.         }
    77.     }
    78.  
    79.     private void OnCollisionEnter(Collision c)
    80.     {
    81.         if (attachPlayer && c.gameObject.CompareTag("Player1"))
    82.             c.transform.parent = transform;
    83.     }
    84.  
    85.     private void OnCollisionExit(Collision c)
    86.     {
    87.      
    88.         //if (attachPlayer && c.gameObject.CompareTag("Player1"))
    89.  
    90.         c.transform.parent = null;
    91.  
    92.         //c.transform.parent = GameObject.FindWithTag("Player").transform;
    93.     }
    94.  
    95. }