• 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
Question by thanedurey · Mar 19, 2019 at 09:49 PM · c#movement2d gamecharge

Moving 2D Object To New Position With Angle and Distance

I have a player object with a charge ability. What I'm trying to do, is when I use my charge ability, I want to move to that new position in a straight line over time. Maybe this has already been answered, but every answer I found only provided and answer to basically "teleport" your player object to the new position. I don't want to move to my new position immediately, I want to travel over time like. Similiar to:


  1. Barbarian in Diablo 3

  2. Magnus in Dota 2


Here is how my charge ability works. I am tracking the position of the analog (from a controller) or mouse position to capture the current angles. When the ability button is pressed, it calls UseAbility. Then I start a Coroutine, and use an IEnumerator to iterate my position to the newPosition.


Here is my Charge ability

 public override void UseAbility(GameObject player)
     {
         abilityCooldownTimer = new Stopwatch();
         abilityCooldownTimer.Start();
         
         StartCoroutine(ChargeUpdate(player));
     }
 
     public IEnumerator ChargeUpdate(GameObject player)
     {
         // Capture DirectionIndicator for proper angle
         GameObject directionIndicator = GameObject.Find("DirectionIndicator");
         float angle = directionIndicator.transform.eulerAngles.z;
 
         // Calculate the distance we need to travel on x and y
         Vector3 distanceToTravel = new Vector3(baseEffectDistance * Mathf.Cos(angle * Mathf.PI / 180), baseEffectDistance * Mathf.Sin(angle * Mathf.PI / 180), 0);
         Vector3 newPosition = new Vector3(player.transform.localPosition.x + distanceToTravel.x, player.transform.localPosition.y + distanceToTravel.y, 0);
         
         Vector2 input;
         player.GetComponent<Player>().canMove = false;
         isCharging = true;
         collidedWithObject = false;
 
         // Wait .4 second to "prepare" our charge ability
         yield return new WaitForSeconds(baseEffectPreparation);
 
         while (abilityCooldownTimer.IsRunning && newPosition != player.transform.localPosition && isCharging)
         {
             // TODO: fix this, for some reason our x and y position can't make it to the final points. We are always .1 or .2 off.
             // Making a check to see if we are .5 off, if so then we will say our charge is complete
             float safeCheckDistance = .5f;
             if (collidedWithObject ||
                 ((newPosition.x - player.transform.localPosition.x <= safeCheckDistance && newPosition.x - player.transform.localPosition.x >= -safeCheckDistance) &&
                 (newPosition.y - player.transform.localPosition.y <= safeCheckDistance && newPosition.y - player.transform.localPosition.y >= -safeCheckDistance)))
             {
                 isCharging = false;
             }
 
             // Determine X Direction to Move
             if (newPosition.x - player.transform.localPosition.x == 0 ||
                 (newPosition.x - player.transform.localPosition.x <= safeCheckDistance && newPosition.x - player.transform.localPosition.x >= -safeCheckDistance))
                 input.x = 0;
             else if (newPosition.x - player.transform.localPosition.x > 0)
                 input.x = 1;
             else
                 input.x = -1;
 
             // Determine Y Direction to Move
             if (newPosition.y - player.transform.localPosition.y == 0 ||
                 (newPosition.y - player.transform.localPosition.y <= safeCheckDistance && newPosition.y - player.transform.localPosition.y >= -safeCheckDistance))
                 input.y = 0;
             else if (newPosition.y - player.transform.localPosition.y > 0)
                 input.y = 1;
             else
                 input.y = -1;
 
             player.GetComponent<Player>().UpdateMotor(input, baseEffectSpeed, baseEffectSpeed);
 
             yield return null;
         }
 
         player.GetComponent<Player>().canMove = true;
 
         abilityCooldownTimer.Stop();
         abilityCooldownTimer.Reset();
 
         yield return null;
     }



And here is my UpdateMotor function

 public virtual void UpdateMotor(Vector2 input, float motorXSpeed, float motorYSpeed)
     {
 
         // Reset MoveDelta
         moveDelta = new Vector2(input.x * motorXSpeed, input.y * motorYSpeed);
 
         // Move on y axis based on moveDelta
         transform.Translate(0, moveDelta.y * Time.deltaTime, 0);
         myAnimator.SetFloat("yspeed", moveDelta.y);
 
         // Move on x axis based on moveDelta
         transform.Translate(moveDelta.x * Time.deltaTime, 0, 0);
         myAnimator.SetFloat("xspeed", moveDelta.x);
     }


Two points to mention: 1. You'll notice the first thing in my while loop, I have a TODO. My UpdateMotor function for some reason doesn't move my character smoothly and accurately to the new position. I'm always .5 to 1.5-ish away from my final position. Meaning, when I call my UpdateMotor, and my final position is (3.5, 4.3), I'll get really close to 3.5 on the x axis, but will never get exactly (to the tenth decimal, obviously don't need to be float accurate). This is the same for the y-axis. 2. My UpdateMotor function works, and gets me to my location, but as you'll see in the image below, I travel to my x and y position at the same speeds. This is a problem, because when I have reached the x or y position I stop traveling on that axis. This gives an awkward movement to the player and looks funny.

Untiy Postion Question

With all of this, I'm trying to figure out: 1. Given an angle, how can I move my player object to the new position over time 2. Additionally, having the player move to the exact position (since I know my new x,y position)

Thank you all in advance for any help you can provide.

unityquestion.png (16.0 kB)
Comment

People who like this

0 Show 9
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 mchts · Mar 17, 2019 at 05:09 PM 0
Share

If i get it right you want to point a direction with a controller or sth and move your player to new position according to new direction and your baseEffectDistance in given time. So this is what you can do:

 void Update () {
         if (Input.GetKeyDown(KeyCode.Space)) { //this is just for testing. You could modify it as your needs 
             StartCoroutine(MoveToPosition(1f));
         }
     }
 
     public Vector3 GetDirection(Vector3 relative, Vector3 reference) {
         var heading = relative - reference;
         var direction = heading.normalized;
     
         return direction;
     }
     
     public IEnumerator MoveToPosition(float timeToMove) {
         //this is where you want to do your preparations
         yield return new WaitForSeconds(baseEffectPreparation);
     
         var t = 0f;
         var target = GetDirection(relative.transform.position, transform.position);
         var initialPos = transform.position;
         while (t < 1) {
             t += Time.deltaTime / timeToMove;
             transform.position = Vector3.Lerp(transform.position,
                                                       initialPos + target * baseEffectDistance, t);
             yield return null;
         }
        //this line ensures that to get exactly the target position 
         transform.position = initialPos + target * baseEffectDistance;
     }

Here is some walkthrough: In GetDirection method reference is the position you pointed to move your player and relative is your players positon. I tested script before posting and it works as expected (at least what i understood from your question). Hope this helps.

avatar image thanedurey mchts · Mar 17, 2019 at 06:46 PM 0
Share

Thanks for answering.

I don't want to charge based on time (like what you have in your while). I want to charge until I reach my new position (which is based on the angle and the variable baseEffectDistance). This way I can reuse the charge ability, and the total distance to travel will be determined by baseEffectDistance.

Additionally, the speed it takes to travel to that distance will be based on the variable baseEffectSpeed. So this will either make us charge really quickly, or it might be a slower charge. But time itself is not a part of the movement.

Is there anyway I can charge, and move to my new position without time? My UpdateMotor function is currently what I'm using to actually move my player using WASD on keyboard, and analog with controller. This works fine to move, but as I mentioned using my image, its not ideal because it will look weird.

Edit 1: I do have checks to see if I need to stop charging, which is why I have the variable isCharging. I have a few checks that say "if this happens, isCharging = false". All that works, I just want a better way to charge in a straight line to my new position.

avatar image thanedurey mchts · Mar 27, 2019 at 12:21 AM 0
Share

Time can't be the only way to make this work, right?

avatar image mchts thanedurey · Mar 28, 2019 at 06:24 AM 0
Share

Ofc not. But i cant say i got what you want to achieve completely. Is there a sample video, gif or sth. to visualize it?

Show more comments

0 Replies

  • Sort: 

Unity Answers is in Read-Only mode

Unity Answers content will be migrated to a new Community platform and we are aiming to launch a public beta by June 9. Please note, Unity Answers is now in read-only so we can prepare for the final data migration.

For more information and updates, please read our full announcement thread in the Unity Forum.

Follow this Question

Answers Answers and Comments

174 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 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 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 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 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 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 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 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

Making a bubble level (not a game but work tool) 1 Answer

Move 2D Sprite Horizontally With Mouse 1 Answer

How to move along a few path follow ? 1 Answer

How can I stop the player movement from being too fast while moving diagonally in my 2D game? 2 Answers

Multiple enemy prefabs moving towards a single goal. Need help! 1 Answer


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