Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by S_Byrnes · Jun 12, 2015 at 11:51 AM · c#2dspeedacceleration

2D Collect Item C# Increase Acceleration

Hello all, I'm having an issue with collection a speed boosting item, I need to be able to collect a power up that increases my players speed a little more, but I don't want it to be an instant jump like it is now, I need it to accelerate gradually.

Here is what I've tried so-far:

 void OnTriggerEnter2D(Collider2D other) {
 
         if (other.tag == "SpeedBoost") {
             
             transform.position = new Vector2(Mathf.Lerp(minimum, maximum, Time.time));
 
             //transform.position += Vector3.right * horizontalSpeed * Time.deltaTime;
             Destroy (other.gameObject); 
         }
     }

Any ideas? All help is greatly appreciated!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by savlon · Jun 15, 2015 at 08:02 AM

You are incorrectly using Mathf.Lerp. The Unity documentation on this is horrible. Mathf.Lerp takes in 'From', 'To' and 'T' parameters. It interpolates your value From to To over T. The T parameter should be a value between 0 and 1. 0 is equal to your From value and 1 is equal to your To value.

For example:

From = 1

To = 2

Difference = To - From = 1

So if T were equal to 0.5, the returned value would be 1.5

I'm not entirely sure what your exact plans for this idea are, but I have constructed a basic script for you to read over and understand what is happening.

 using UnityEngine;
 using System.Collections;
 
 public class PowerUpTest : MonoBehaviour 
 {
     public float minSpeed = 1.0f;    //Minimum powerup speed 'From'
     public float maxSpeed = 10.0f;    //Maximum powerup speed 'To'
     public float incrementRate = 0.1f;    //The rate you want the speed to change
     public string powerUpName = "SpeedBoost";    //The tag of the powerup gameobject
 
     private bool executePowerUp = false;  //Checks whether to execute the powerup 
     private float currentSpeed;    //The current speed of your powerup boost value
     private float lerpTime;  //The lerp time 'T'
 
     void Start () 
     {
         currentSpeed = minSpeed; //Set current speed to equal the minimum speed
     }
     
     void Update () 
     {
         if (executePowerUp) //If the executePowerUp bool is true
         {
             if (lerpTime <= 1) //If the lerp time has not reached the maximum value ('To')
             {
                 lerpTime += Time.deltaTime * incrementRate; //Increase the lerp time by deltaTime multiplied by the rate
                 currentSpeed = Mathf.Lerp (minSpeed, maxSpeed, lerpTime); //Set the current speed to the current lerped value
                 print (currentSpeed); //print the current speed for you to see the change in the value
             }
             else //If the lerp time has exceeded the 'To' value
             {
                 executePowerUp = false; //Turn execute powerup to false
                 lerpTime = 0; //Reset the lerp time
             }
         }
     }
 
     void OnTriggerEnter2D (Collider2D other)
     {
         if (other.CompareTag (powerUpName)) //If the trigger object tag is equal to the powerup tag
         {
             executePowerUp = true; //Set execute power to true to initiate the lerp code
             Destroy (other.gameObject); //Remove the collided object
         }
     }
 }

The code is fully commented. If you don't understand something, post a comment.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image S_Byrnes · Jun 15, 2015 at 08:38 AM 0
Share

Thank you very much savlon, I actually managed to work out a similar solution a few hours ago, it involves almost the same principles only this one I have it connected to the power up item and having it reference the player ins$$anonymous$$d, here is what I ended up with:

     void OnTriggerEnter2D(Collider2D other) {
 
         if (other.gameObject.tag == "Player") 
         {
             collected = true;
             GameObject.FindGameObjectWithTag("Player").GetComponent<Player$$anonymous$$ove>().forwardsSpeed+=bonusGain;
             gameObject.renderer.enabled = false;
         }
         if (other.gameObject.tag == "Bounds") {
                         Destroy (gameObject);
                 }
     }
     
     void Update()
     {
         if (collected == true) {
                         timer += Time.deltaTime;
                         if (timer >= bonusTime) {
                                 GameObject.FindGameObjectWithTag ("Player").GetComponent<Player$$anonymous$$ove> ().forwardsSpeed = speedReset;
                                 Destroy (gameObject);
                                 collected = false;
                         }
         if (collected == false){
             GameObject.FindGameObjectWithTag ("Player").GetComponent<Player$$anonymous$$ove> ().forwardsSpeed = speedReset;
                 }
     }
         transform.position -= Vector3.right * speedItemLocation * Time.deltaTime;
 }
 }

Let me know if you think it is inefficient or anything and if there is something I should change to make it more efficient.

I've marked your answer as correct anyway since I believe it would have easily worked/led me to the answer, so thanks again!

avatar image savlon · Jun 15, 2015 at 09:22 AM 0
Share

You don't have to search the scene for the Player when the trigger is fired when you want to change the forwardsSpeed You can obtain a Player$$anonymous$$ove reference from the collided GameObject by using other.gameObject.GetComponent (); ins$$anonymous$$d of GameObject.FindGameObjectWithTag("Player").GetComponent() Obviously you'd need to check if that reference is not equal to null before you attempted to change the forwardsSpeed. Other than that, if it works and there are no issues then its fine. If later on you start seeing performance issues, then you can refactor it. Nice work.

avatar image S_Byrnes · Jun 15, 2015 at 09:56 AM 0
Share

Thank you! Yeah I'll just leave it for now, this is going to be for mobile, so once I start testing on that, if I find performance issues, then I'll tweak some things. Good to know you don't need to reference the player's tag when colliding though, that'll help save time for projects in the future.

Thanks again salvon, appreciate it!

avatar image
2

Answer by HarshadK · Jun 12, 2015 at 12:22 PM

Firstly Mathf.Lerp inside OnTriggerEnter2D() should actually be places inside the Update() method as OnTriggerEnter2D() will be executed for one frame only which is undesired for lerping. Also Lerp using Time.deltaTime instead of Time.time. Since as time passes after you started playing game the value of Time.time will be higher resulting in a jump inside of Lerp.

For position you should provide two values as you are using Vector2 where as currently you are using only one which is lerped.

And you can set the value of maximum inside OnTriggerEnter2D(), considering maximum is your maximum speed of player.

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image S_Byrnes · Jun 12, 2015 at 12:50 PM 0
Share

Alright, I've fixed some of those things you've mentioned about the 2 values and the Time.deltaTime, but I'm not sure how I would go about moving half of this to update with the other half in this OnTriggerEnter2D function..

 transform.position = new Vector2($$anonymous$$athf.Lerp($$anonymous$$imum, maximum, Time.deltaTime),0);

avatar image HarshadK · Jun 12, 2015 at 12:56 PM 0
Share

This is where the last part of the answer comes in. You can put Lerp inside Update and set the value of maximum inside OnTriggerEnter2D.

As:

  void OnTriggerEnter2D(Collider2D other) {
      if (other.tag == "SpeedBoost") {
          maximum += 5f; // Just added 5 to the maximum speed
          Destroy (other.gameObject); 
      }
  }

And now put that Lerp inside Update().

avatar image S_Byrnes · Jun 12, 2015 at 01:09 PM 0
Share

Alright thanks, I've tried it now and my character and also the speed boost, both disappear immediately when I hit play, this is for a 2D game and I'm trying to get it to go to the right, am I doing it correctly? Or is both my player and my speed boost getting destroyed instantly or something?

avatar image HarshadK · Jun 12, 2015 at 01:27 PM 0
Share

You are actually setting the position of the player equal to the value returned by your lerp for speed.

You should update the position of the player based on current position plus the delta in the position based on the speed. Something like:

 // Get the speed value for the player using lerp for acceleration
 float speed = $$anonymous$$athf.Lerp($$anonymous$$imum, maximum, Time.deltaTime);
 // Update position of player using the current position and speed
 Vector2 pos = transform.position;
 pos.x += speed * Time.deltaTime;  // Just added the delta position to the current position of player
 transform.position = pos;

avatar image S_Byrnes · Jun 12, 2015 at 02:03 PM 0
Share

Alright, well at least my character isn't disappearing instantly now, but now he's just accelerating off of the screen rapidly, changing float variables isn't changing anything either.

         public float $$anonymous$$imum = 0.0f;
         public float maximum = 20.0f;
         public float acceleration = 2.0f;
 
     void Update() {
         
                 //transform.position = new Vector2($$anonymous$$athf.Lerp($$anonymous$$imum, maximum, Time.deltaTime),0);
         
                 // Get the speed value for the player using lerp for acceleration
                 float speed = $$anonymous$$athf.Lerp ($$anonymous$$imum, maximum, Time.deltaTime);
                 // Update position of player using the current position and speed
                 Vector2 pos = transform.position;
                 pos.x += speed * Time.deltaTime;  // Just added the delta position to the current position of player
                 transform.position = pos;
         
                 if (Input.Get$$anonymous$$ey ($$anonymous$$eyCode.F)) {
                         transform.position += Vector3.right * horizontalSpeed * Time.deltaTime;
                 } else { 
                         transform.position -= Vector3.right * backwardsSpeed * Time.deltaTime;
                 }
         }
 
     void OnTriggerEnter2D(Collider2D other) {
 
         if (other.tag == "$$anonymous$$iniFish") {
 
             maximum += 5f; // Just added 5 to the maximum speed
 
             //transform.position = new Vector2($$anonymous$$athf.Lerp($$anonymous$$imum, maximum, Time.deltaTime),0);
 
             //transform.position += Vector3.right * horizontalSpeed * Time.deltaTime;
             Destroy (other.gameObject); 
         }
     }
 }

Is there something I'm missing or not doing here?

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

22 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to Set the Game Speed Based on the Player's Current Score? 1 Answer

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Even / Constant Speed and Jumping 2D 1 Answer

Bullet not moving from script 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges