Time boiled rain Unity3d realize 2D character Movement-Summary

Source: Internet
Author: User

Series Catalogue

"Unity3d base" lets the object move ①--based on the Ugui mouse click Movement

"Unity3d base" let the object move ②--ugui mouse click Frame

Time boiled rain Unity3d let the object move ③-ugui dotween&unity native2d Realization

Time to boil the rain Unity3d realize 2D character animation ①ugui&native2d sequence frame animation

Time to boil the rain Unity3d realize 2D character animation ②unity2d animation System & Resource Efficiency

Background

Recent research on the implementation of unity3d,2d pathfinding. So again, the problem of role coordinate displacement is involved. The system for this simple problem to organize and summarize. Originally is a simple geometry problem, the results found that there are two small pits, by the way, to do a summary here.

Realize

requirements: through the mouse click, control 2d character Movement, is the point where the role to move to where

problem decomposition: animation decomposition by time, mouse input (animation start), panning (animation), moving end (end of animation)

premise: Here the previous article basically solves some basic knowledge, such as IO acquisition (mouse input), the basic way of moving (position system transform in Unity)

Pit:1, smooth movement in the pan, 2, how to determine the target point moved, and to stop the object

Pit 1: Smooth movement in panning

Supplemental Knowledge , about the role of panning and location updates, unity is nothing more than a few ways

A, transform. Translate (New Vector3 (1, 1, 1) * movespeed * time.deltatime); Translate method movement does not consider a rigid body such as collisions (will directly through the object)

Make sure we're not faster than Maxdistancedelta.
B, Vector3.movetowards (transform.position, targetpos.position, speed * time.deltatime);

//speed will exceed the speed of movement, like a spring
C, Vector3.lerp (transform.position, targetpos.position, speed * time.deltatime);

D, set the transform directly. Positon, the simplest way

This pit, really pit a lot of people, the current online more than half of the tutorial, from the strict sense is wrong, here really want to spit groove (too his mother is not responsible for), this question I asked once in the group, the results are still suspected rookie, in fact, the focus is still I marked the red linear interpolation function, in fact, very simple , is a linear equation. Here you can refer to the following two articles

Unity3d problem Set <2> understanding of Vector3.lerp interpolation

Unity3d Vector3.lerp parsing http://www.cnblogs.com/shenggege/p/5658650.html

Analysis why "speed will exceed the movement speed, like a spring" and linear interpolation function, and then I think carefully, in fact, the knowledge is not thorough enough, we understand the future analysis, the Classic tutorial function

public float movespeed;
public float turnspeed;

Private Vector3 movedirection;
Use this for initialization
void Start () {
Movedirection = Vector3.right;
}

Update is called once per frame
void Update () {

       //1
        Vector3 CurrentPosition = transform.position;
       //2
        if ( Input.getbutton ("Fire1")) {
           //3
             Vector3 Movetoward = Camera.main.ScreenToWorldPoint ( Input.mouseposition);
           //4
             movedirection = movetoward-currentposition;
            movedirection.z = 0;
            movedirection.normalize ();
       }

Vector3 target = movedirection * movespeed + currentposition;
Transform.position = Vector3.lerp (currentposition, Target, time.deltatime);
}
}

Here we look at the red part of the text, here is not the effect of spring movement, the main is that each interpolation is the current point and the frame will move the location of the interpolation, in fact, there is no need to directly set transform.position = Movedirection * Movespeed*time.deltatime + currentposition; (in fact, it is a time-based linear movement)

There are itself Vector3.lerp (transform.position, targetpos.position, speed * time.deltatime); There's a big problem with this.

A, Speed * time.deltatime when the speed setting is very large and the frame rate is very low, this factor is probably all 1, so it is not interpolated at all,

B, when using Ugui coordinate system is a large screen coordinates, so the interpolation will be very not (this is the question I have asked, but no one answered me)

At this point the first pit is filled, and below I list the relevant code that uses different ways to move

First, improved interpolation movement

<summary>///using Vector3 interpolation to update location//</summary>private void Movebyvector3lerp () {//1, get current position Vector3 CU    Renposition = this.transform.position; 2. Get direction if (Input.getbutton ("Fire1")) {Vector3 Movetoward = Camera.main.ScreenToWorldPoint (input.mouseposit        ION);        Movetowardposition = Movetoward;        movetowardposition.z = 0;        Movedirection = movetoward-curenposition;        movedirection.z = 0;    Movedirection.normalize ();   } var distance = Vector3.distance (curenposition, movetowardposition); Debug.Log (String. Format ("curenposition:{0}, Movetowardposition{1},distance:{2},speed:{3}", Curenposition, Movetowardposition,    Distance, speed * time.deltatime));    if (distance < 0.01f) {transform.position = movetowardposition; } else {//3, interpolation move//target position direction plus speed move Vector3 target = movedirection*speed*time.deltatime + Curenpos        ition;        target.z = 0;    Transform.position = target; }}

  

Second, movetowards for mobile updates

<summary>///use Vector3 's movetowards to directly update the location///</summary>private void Movebyvector3movetowards () {    ///1, get the current position    Vector3 curenposition = this.transform.position;    2. Get Direction    if (Input.getbutton ("Fire1"))    {        movetowardposition = Camera.main.ScreenToWorldPoint ( input.mouseposition);        Movetowardposition.z =0;    }    if (Vector3.distance (curenposition, movetowardposition) < 0.01f)    {        transform.position = movetowardposition;    }    else    {        //3, the interpolation move        //Distance equals the interval time multiplied by the speed to        float Maxdistancedelta = time.deltatime * speeds;        Transform.position = Vector3.movetowards (curenposition, movetowardposition, Maxdistancedelta);}    }

  

The third kind, transform. Translate

<summary>///use Vector3 's translate to directly update the location///</summary>private void Movebytransformtranslate () {    1, obtain the current position    Vector3 curenposition = this.transform.position;    2. Get Direction    if (Input.getbutton ("Fire1"))    {        movetowardposition = Camera.main.ScreenToWorldPoint ( input.mouseposition);        movetowardposition.z = 0;        Movedirection = movetowardposition-curenposition;        movedirection.z = 0;        Movedirection.normalize ();    }    3, interpolation mobile    Vector3 target = movedirection * Speed * time.deltatime + curenposition;    target.z = 0;    if (Vector3.distance (curenposition, movetowardposition) < 0.01f)    {        transform.position = movetowardposition;    }    else    {        transform. Translate (target-curenposition);    }}

  

Pit 2: How to make sure the target point is moved and stop the object

Supplementary Knowledge: In fact, Pit 1 listed in the three kinds of translation methods, in fact, not what routines, not what the standard animation moving way, although they are also based on time, can only be summed up into a simple sequence of frame movement, here I looked at a lot of data and a time line based on the movement.

problem Description: here first said Pit 2 is how the matter, is that we want to move the role of the mouse click on the point after the stop, the results found to stop, through the debug log the main problem in this line (this is also my previous question, but no answer)

if (Vector3.distance (curenposition, movetowardposition) < 0.01f)

In fact, this line of code is very unreliable, at least two points

A, the unit difference, Ugui is the screen coordinates is also localpositon pixels, native is the unit two units different judgment of this distance constant is not the same

B, because the speed * time.deltatime each frame movement distance is related to velocity and frame rate, this constant (0.01) must match with the need to set a reasonable value

C, using interpolation to calculate the 3-dimensional coordinate error will be enlarged, here I use "the first, improved interpolation move", "the Third Kind, transform." Translate "There has been a large error, and" The second, movetowards for mobile updates ", it is very accurate.

So the system gives the function

Vector3.movetowards (Curenposition, movetowardposition, Maxdistancedelta);

Not for nothing, which is why many people recommend using this function (but don't tell us why)

Finally, I wrote my own. Time-line based displacement implementation

<summary>///mouse click to move, Target point///</summary> private Vector3 movetowardposition = Vector3.zero;    Private Vector3 movestartposition = Vector3.zero;    private float totaltime = 0.0f;    private float costtime = 0.0f;    private float timeprecent = 0.0f;    private bool _isruning = false;        <summary>///Whether you are moving///</summary> public bool Isruning {get {return _isruning;}    set {_isruning = value;}         The private void Movebytimeline () {/* * Gets the final destination of the move, and the total time required to move according to the movement speed TotalTime * each frame,          * 1, accumulate the elapsed time, and get costtime, and get the percentage of movement precent = Costtime/totaltime * 2, get the position of the current sprite, according to the position interpolation of precent, get the position that this frame should move         * 3, using the Set move * 4, through the precent to determine whether <1 to determine whether to move to the target location * 5, if completed, then call the last move implementation, the end of the movement error, and set to some flag bit        *///Get current position Vector3 curenposition = this.transform.position; if (Input.getbutton ("Fire1")) {movestartposition = CurenpositIon            Get the mobile end position movetowardposition = Camera.main.ScreenToWorldPoint (input.mouseposition);            movetowardposition.z = 0;            Costtime = 0.0f;            Calculate the record var SubVector3 = movetowardposition-curenposition;            Calculate the total time required to move totaltime = Subvector3.magnitude/speed;        _isruning = true;            }//If you have moved if (_isruning) {///If the percentage of time is less than 1 the description has not been moved to the end if (Timeprecent < 1)                {//cumulative time Costtime + = Time.deltatime;                Timeprecent = Costtime/totaltime;                Vector3 target = Vector3.lerp (Movestartposition, movetowardposition, timeprecent);              Transform.position = target;                } else//greater than or equal to 1 indicates that the last move {transform.position = movetowardposition;                _isruning = false;                Movetowardposition = Vector3.zero; Timeprecent = 0.0f;               Costtime = 0.0f; }        }    }

  

This method basically excludes, moving to the end of the displacement error problem, the disadvantage is that the use of a lot of temporary variables (I do not like), and "The second, movetowards for mobile updates" can basically not use temporary variables. Timeline animation Actually this is also the core principle of some small translation components and itween (why, further exploration, perhaps more extensibility)

Summarize

Anyway by the pit very uncomfortable, but also blame others, or their own caishuxueqian (not genius, hard to do). Move to the next series of target points to explore roles

Time boiled rain Unity3d realize 2D character Movement-Summary

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.