Copter movement

At present I am trying to behavior some thing like following game
https://play.google.com/store/apps/details?id=com.rovio.retry&hl=en

Basically above game contains following type of movement. I have taken snapshot for that
1861771--119450--flight1.png 1861771--119451--flight2.png 1861771--119452--flight3.png

I can’t able to figure out starting point for this. Right now I am considering, I have to choose some point far from copter and based on that point rotate copter around that point.

I don’t know whether I am right in this. So that I need some suggestion from your side because this type of movement I have seen first time in copter game.

Please give some suggestions and tips in this.

You could just use cos and sin just like when plotting a circle. That is not how I would do it but it is probably how many people would solve this problem and I think it actually might work well here.

This is how I approach problems (this one or any other):

  1. Look at your desired result:
    You have clear illustrations defining the kind of motion you want to achieve… excellent!

We know we are dealing with motion so from this point on focus on that.

  1. Viewing the plane and the path it should follow what do we see?

We see a continual, incremental change in velocity.

I get that because I see that at one point the plane is heading straight to the right (1F, 0F) for example.
Later, it will end up heading straight up (0F, 1F) for example.

So, the problem can be seen as changing from (1F, 0F) to (0F, 1F) over time.
How much time will determine how big of a loop (circle) the plane moves in.

Consider, if the plane has a vector2 storing its current speed:

Vector2 v2CurSpeed;
v2CurSpeed.x = 1F;
v2CurSpeed.y = 0F;

By applying this to the plane’s current [transform] position the plane will move to the right slightly.

Now consider the plane has a second vector2 storing its current target velocity:

Vector2 v2TargetSpeed;
v2TargetSpeed.x = 0F;
v2TargetSpeed.y = 1;

When the plane reaches this target velocity it will be moving straight up.

It then becomes a very simple problem, right?
Incrementally, over time, the plane’s velocity needs to change from heading straight to the right to heading straight up.
You could use Lerp to do that.

What I’d do is simply have a method that is called during Update.
This method would gradually bring the plane’s current velocity to the target velocity.
A simple implementation would be:

private void AdjustCurrentVelocityToTargetVelocity()
{
   if (v2TargetSpeed.x < v2CurSpeed.x)
   {
      v2CurSpeed.x -= 0.01F;
      if (v2CurSpeed.x < v2TargetSpeed.x)
         v2CurSpeed.x = v2TargetSpeed.x;
   }
   else if (v2TargetSpeed.x > v2CurSpeed.x)
   {
      v2CurSpeed.x += 0.01F;
      if (v2CurSpeed.x > v2TargetSpeed.x)
         v2CurSpeed.x = v2TargetSpeed.x;
   }
   if (v2TargetSpeed.y < v2CurSpeed.y)
   {
      v2CurSpeed.y -= 0.01F;
      if (v2CurSpeed.y < v2TargetSpeed.y)
         v2CurSpeed.y = v2TargetSpeed.y;
   }
   else if (v2TargetSpeed.y > v2CurSpeed.y)
   {
      v2CurSpeed.y += 0.01F;
      if (v2CurSpeed.y > v2TargetSpeed.y)
         v2CurSpeed.y = v2TargetSpeed.y;
   }
}

4 target velocities and the transitions between them are enough to represent this loop motion.

private enum TargetVelocityType
{
    Right,
    Up,
    Left,
    Down
}

Adding a type to represent which target velocity we are transitioning to:

TargetVelocityType eTargetVelocityType = TargetVelocityType.Right

Then we just check if curSpeed = TargetVelocity we move on to the next velocity in the pattern:
if eTargetVelocityType == Right it becomes Up. Up becomes Left. Left Becomes Down. And Down cycles back to Right if you want to keep the looping going.

If you implemented the above you would end up with an object moving in a circular motion.

The 0.01F can be adjusted to determine how quickly the plane adjusts from its current velocity to the target velocity.
You may also want to normalize the new velocity.

Basically, for all of this stuff there are many different solutions. Some people immediately go to math (such as sin() and cos() in this case), others would use some kind of predefined motion paths, etc. None are the wrong way. None are the right way. What I have shown you here is not the wrong way or the right way. It is just showing how I break a problem down into simple steps. You do that to identify the fundamental parts. Once you have those fundamentals it is easy to code up a solution. And this is certainly not the only way to implement the solution. I could have approached the implementation in various ways focusing on the velocities and each implementation would result in basically the same visible result in the end.

@GarBenjamin , Many thanks to you. Now I can clear filter my problem into different parts.
Next time also same thing I will keep in mind.

At present, I am not completely empty with implementation. Now I have written following code :

public class CopterFly : MonoBehaviour
{
    private float copterSpeed = 2f;
    private float rotationSide = 2f;
    private float rotationSpeed = 120f;
    private float slerpTime = 0f;
    private bool touchDown, touchHold;

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            touchDown = true;
        }
        else if (Input.GetMouseButton(0) && !touchDown)
        {
            touchHold = true;
        }
        else if (Input.GetMouseButtonUp(0))
        {
            touchHold = false;

            rigidbody2D.angularVelocity = -100f;
            Vector2 landingPower = new Vector2((transform.position.x + transform.right.x) % 3f, (transform.position.y + transform.up.y) % 3f);           
            rigidbody2D.velocity = landingPower;
        }
    }

    void FixedUpdate()
    {
        if (touchDown)
        {
            slerpTime = 0f;
            touchDown = false;
        }
        else if (touchHold)
        {
            if (slerpTime < 1f)
                slerpTime += (Time.fixedDeltaTime * 0.25f);

            float rotation = rotationSpeed * rotationSide;
            transform.Rotate(Vector3.forward * Mathf.Lerp(0f, rotation, slerpTime) * Time.deltaTime);
            rigidbody2D.MovePosition(transform.position + (transform.right * copterSpeed * Time.deltaTime));

        }
    }
}

Using above code I can able to lift copter up and able to perform rotation in air.
But when player touch up his finger from device then I can’t able to land it correctly.
I have written some code for landing purpose but it didn’t seem to be correct because velocity to copter applied in wrong direction. This problem facing in my code.

Now I want to discuss some doubts related to your suggested code.

  • If I apply velocity to copter for position change instead of transformation then is it work?
  • You didn’t discuss about copter rotation and it is main thing for this type of implementation.
  • For each touch down, first copter start movement in right side then slowly goes up. On touch hold start continuous rotation. This type of implementation clearly seen in images.

Please give some suggestion over these doubts. I am eagerly waiting for reply.

Sorry for not replying sooner. Holiday break came and forgot all about it.

Yeah I just focused on the looping motion. Thought that was the thing you were working on.

I am not sure what you are asking about applying velocity to copter instead of transformation. I kind of forget that most people using Unity are probably using Unity physics applying forces and such to move things around. That seems like a very weird way of doing things to me. I could see applying forces for wind or gravitational effects. But for objects moving under their own power I would want them to be controlled by my own movement engine. I don’t use any of the Unity physics stuff for movement. So hopefuply someone who does will give you an answer.