Balistic problem

This was a unanswered question on Unity Answer. I’m opening this post because don’t think this problem can be solved with a simple straight answer. What I’m trying to achieve is a simple arc jump in a realistic physic environment. My char now is able to jump and land in the spot flagged by the click, but can’t reach spot lower than himself nor object that are 90 degree above his head (pretty lame! doh!). My jump can compute the velocity needed to achieve the jump but need a fixed angle. That’s the problem. I could have create a couple of raycast to check if the trajectory is clear but still with fixed angle the char will not jump at all. I need something that can change that angle to the lowest and safe(no obstacle in trajectory) one. The best thing is calculate some point, evenly spaced on the trajectory,shoot a ray from that point and if is clear jump, if is not try the same thing with a greater angle. So here is the code:

Vector3 BallisticVel(Vector3 target, float angle) 
    {
       Vector3 dir = target - transform.position;  // get target direction
       float h = dir.y;  // get height difference
       dir.y = 0;  // retain only the horizontal direction
       float dist = dir.magnitude ;  // get horizontal distance
       float a = angle * Mathf.Deg2Rad;  // convert angle to radians
       dir.y = dist * Mathf.Tan(a);  // set dir to the elevation angle
       dist += h / Mathf.Tan(a);  // correct for small height differences
       // calculate the velocity magnitude
       float vel = Mathf.Sqrt(dist * Physics.gravity.magnitude / Mathf.Sin(2 * a));
       return vel * dir.normalized;
    }

    Vector3 TrajectoryPoint(Vector3 startingPosition, Vector3 startingVelocity, float n )
    {
        float t = 1/60 ; // seconds per time step 
      Vector3 stepVelocity = t * startingVelocity; // m/s
      Vector3 stepGravity = t * t * Physics.gravity; // m/s/s

       Debug.Log(t +" " + stepVelocity + " " + stepGravity);

      return startingPosition + n * stepVelocity + 0.5f * (n*n+n) * stepGravity;
    }

    bool CheckTrajectory(Vector3 startingPosition,Vector3 target, float angle_jump)
    {
       Debug.Log("checking");
       if(angle_jump < 80f)
       {
         Debug.Log("if");

         Vector3 startingVelocity = BallisticVel(target, angle_jump);

         for (int i = 0; i < 180; i++) 
         { 
          //Debug.Log(i);
               Vector3 trajectoryPosition = TrajectoryPoint( startingPosition, startingVelocity, i );


          if(Physics.Raycast(trajectoryPosition,Vector3.forward,collider.bounds.extents.z))
          {
              angle_jump += 10;
//            Debug.Log("hit something");
              break; // restart loop with the new angle
          }
          else
//            Debug.Log("continuing");
              continue;

         }
          Debug.Log("loop ended");

          return true;
          JumpVelocity = BallisticVel(target, angle_jump);
         }

       return false;
    }

The problem is that TrajectoryPoint return always the same point. . .

Have you looked at iTween? It adds a lot of cool functions to Unity with a simple script that you can access via itween commands. It also supports an arc style movement. You can get it here: iTween for Unity by Bob Berkebile (pixelplacement)

And here’s the Demo of the arc I ment, maybe you can make use of it? :slight_smile:

http://itween.pixelplacement.com/examples.php

The first example should work for you: “Accurate Lob”

I’m using Itween for the moving platform and some other things, but for the char I’m using Behave, Unity steer and rigid body for realistic effects. . .

After 10 long painful days I managed to create a system with jump system that select the right angle and then jumps. Probably can be optimized, but for now I’m happy (:tearsOfJoy:)

float CalculateAngle(Vector3 target)
	{
		Vector3 relative = transform.InverseTransformPoint(target);
		float a = Mathf.Atan2(relative.y,relative.z);
		float aDeg = Mathf.Rad2Deg * a;
		//Debug.Log(aDeg);
		return aDeg;
	}
	
	
	Vector3 BallisticVel(Vector3 target, float angle) 
	{
		float vel  = 0;
		dir = target - transform.position;  // get target direction
		float h = dir.y;  // get height difference
		dir.y = 0;  // retain only the horizontal direction
		float dist = dir.magnitude ;  // get horizontal distance
		float a = angle * Mathf.Deg2Rad;  // convert angle to radian
		dir.y = dist * Mathf.Tan(a);  // set dir to the elevation angle
		dist += h / Mathf.Tan(a);  // correct for small height differences
		// calculate the velocity magnitude
		vel = Mathf.Sqrt(dist * Physics.gravity.magnitude / Mathf.Sin(2 * a));
		return vel * dir.normalized;

	}
	
	
	Vector3 TrajectoryPoint(Vector3 startingPosition, Vector3 startingVelocity, float t )
	{
		Vector3 point;
		
		float tSec = t/60f;
		point.x = startingVelocity.x * tSec + startingPosition.x;
		point.z = startingVelocity.z * tSec + startingPosition.z;
		point.y = -Physics.gravity.y * ((tSec*tSec) / 2) + (startingVelocity.y * tSec) + startingPosition.y;
		
		return point;
	}
	
	void CheckTrajectory(Vector3 target)
	{
		Debug.Log("checking");
			
		int counter = 0;
		loopEnd = false;
		angleJump = CalculateAngle(target);
		
			while(!loopEnd  angleJump < 90f  counter < 60)
		{
			Scan(target);
			counter++;
		}

		if(angleJump < 85)
		{
			JumpVelocity = BallisticVel(target,angleJump);
		} else
		{
			//jump straight
		}
		
	}
	
	
	void Scan(Vector3 target)
	{
		Debug.Log("Scanning");
		Debug.Log(angleJump);
		
		startingVelocity = BallisticVel(target, angleJump);
		heightTime = (startingVelocity.y/-Physics.gravity.y) * 60;
		heightTime = Mathf.Floor(heightTime);
		
		for (int i = 0; i < heightTime; i++) 
			{ 
				//Debug.Log(i);
	      		Vector3 trajectoryPosition = TrajectoryPoint( transform.position, startingVelocity, i );
				//Debug.Log(trajectoryPosition);
			
			Debug.DrawRay(trajectoryPosition,dir,Color.red,10f);
				
			RaycastHit hit;
			if(Physics.Raycast(trajectoryPosition,dir,out hit,3f,layerMask))
				{
					Debug.Log(hit.collider.name);
					angleJump +=10;
					break;
				}
			
			if(i == heightTime-1)
				{
					loopEnd = true;
					JumpVelocity = BallisticVel(target,angleJump);
					Debug.Log("endloop" + JumpVelocity);
				}
			}
	}

For future reference, here is a link that may have saved the OP some headaches:

http://hyperphysics.phy-astr.gsu.edu/hbase/traj.html

Most of the work was done using that link :smile: it’s simply amazing :smile: