Jump to content
  • Advertisement
Sign in to follow this  
Andre Rogers

Movement up and down a slope

This topic is 2145 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, am trying to move an object along a series of slopes, and also make it follow a trajectory when it reaches a certain velocity at the apex of a slope. Am having a few issues with my code. Am coding in C# Unity, so am using Unity's rigid body and collision system, and varying properties as and when required. I would really appreciate it someone could just check and see if there is anything wrong with it.

 

When I accelerate up a slope, it accelerates but on reaching the top or the apex of the slope it starts to move back down. And when I accelerate down a slope it moves very slowly or doesn't move at all (it should be moving at a greater acceleration). 

 

What is the appropriate condition or process to use to synch all the movement together (such that it is smooth and seamless). 

	public void Accelerate(Vector3 slopeNormal)
	{
		if(MoveDirection.magnitude > 0f)
		{
			Vector3 targetVelocity ;
	        Vector3 currentVelocity ;
	        Vector3 velocityChange ;
			Vector3 force ;
			Vector3 a ;
			
			float levelStopTime ;
			float brakingDistance ;
						
			targetVelocity = Speed * MoveDirection ;
			currentVelocity = Character.rigidbody.velocity;	
			
			velocityChange = targetVelocity - currentVelocity;	
			
			a.x = Mathf.Clamp(velocityChange.x, -MaxAcceleration, MaxAcceleration);
			a.y = Mathf.Clamp(velocityChange.y, -MaxAcceleration, MaxAcceleration);
			a.z = Mathf.Clamp(velocityChange.z, -MaxAcceleration, MaxAcceleration);
			Acceleration = a.magnitude * Mathf.Pow (Time.deltaTime, 2f);	// Not sure, CHECK!!
			
			force = Character.rigidbody.mass * a ;

//			levelStopTime = (m_character.rigidbody.velocity / m_maxAcceleration).magnitude ;
//			brakingDistance = (m_character.rigidbody.velocity.magnitude * m_levelStopTime) + (m_maxAcceleration * m_levelStopTime) ;//Mathf.Pow(m_levelStopTime, 2f) / 2f) ;					
			
			if(Input.GetKey(KeyCode.U))
				AccelerateUpSlope(slopeNormal) ;
			else if(Input.GetKey(KeyCode.D))
				AccelerateDownSlope(slopeNormal) ;
			else
				Character.rigidbody.AddForce(force) ;
		}
		else
			Debug.LogError("Movement Direction Invalid!!") ;
	}
	
	public void AccelerateDownSlope(Vector3 slopeNormal)
	{
		float fG, fNet, fParallel ;
		float m ;
		float g ;
		float theta ;
		
		float a ;
		Vector3 A ;

		Vector3 characterNormal = Character.rigidbody.velocity.normalized ;
		
		m = Character.rigidbody.mass ;
		g = Physics.gravity.y ;

		fG = m * g;
		theta = Vector3.Angle(characterNormal, slopeNormal) ;
		
		fParallel = fG * Mathf.Sin(theta) ;
		fNet = fParallel ;
		
		a = fNet / m ;
		A = a * new Vector3(1f, 1f, 0f) ;
		Debug.Log("Down " + A) ;
		
		Acceleration = a  * Mathf.Pow (Time.deltaTime, 2f);	// Not sure, CHECK!!
		Character.rigidbody.AddForce(A, ForceMode.Acceleration) ;
	}
	
	public void AccelerateUpSlope(Vector3 slopeNormal)
	{
		float fG, fNet, fParallel, fPerpendicular ;
		float m ;
		float g ;
		float theta ;
		
		float a ;
		Vector3 A ;

		Vector3 characterNormal = Character.rigidbody.velocity.normalized ;
		
		m = Character.rigidbody.mass ;
		g = Physics.gravity.y ;

		fG = m * g;
		theta = Vector3.Angle(characterNormal, slopeNormal) ;
		
		Debug.Log(theta) ;		
		
		fParallel = fG * Mathf.Sin(theta) ;
		fPerpendicular = CoefficentFriction * fG * Mathf.Cos(theta) ; 
		
		fNet = fParallel - fPerpendicular ;
		
		a = fNet / m ;
		A = a * new Vector3(1f, 1f, 0f) ;
		Debug.Log("UP " + A) ;		
		
		Acceleration = a  * Mathf.Pow (Time.deltaTime, 2f);	// Not sure, CHECK!!
		Character.rigidbody.AddForce(A, ForceMode.Acceleration) ;
	}	
		
	public void ProjectileMotion(Vector3 colliderNormal)
	{
		float maxVelocityX = 45f ;
		float maxVelocityY = 60f ;
		Vector3 initialVelocity = go.rigidbody.velocity ;
		Vector3 initialPosition = go.rigidbody.position ;
		
//		float angle = Vector3.Angle(go.rigidbody.position.normalized, colliderNormal) ;
//		float launchAngleRad = (angle * Mathf.PI) / 180f ;

		float launchAngleRad = (m_launchAngle * Mathf.PI) / 180f ;
		float timeOfFlight = (2f * initialVelocity.magnitude * Mathf.Sin(launchAngleRad)) / Physics.gravity.magnitude ;
		
//		Debug.Log("Launch Angle (rad) - " + launchAngleRad) ;
//		Debug.Log("Time of Flight - " + timeOfFlight) ;
		
		float x, y ;		
		
		x = initialPosition.x + (initialVelocity.x * Mathf.Cos(launchAngleRad) * timeOfFlight) ;
		y = initialPosition.y + (initialVelocity.y * Mathf.Sin(launchAngleRad) * timeOfFlight) - (0.5f * Physics.gravity.y * Mathf.Pow(timeOfFlight, 2)) ;
		
//		Debug.Log("x Position - " + x) ;
//		Debug.Log("y Position - " + y) ;			
		
		Vector3 amtToMove = new Vector3(x, y, go.transform.position.z) ;
		Vector3 finalVelocity = amtToMove / timeOfFlight ;

//		go.rigidbody.MovePosition(amtToMove) ;
		
		if(finalVelocity.x >= 0f)
		{
//			Debug.Log(finalVelocity) ;
			
			finalVelocity.x = Mathf.Clamp(finalVelocity.x, -maxVelocityX, maxVelocityX);
			finalVelocity.y = Mathf.Clamp(finalVelocity.y, -maxVelocityY, maxVelocityY);			
			
			go.rigidbody.AddForce(finalVelocity, ForceMode.VelocityChange) ;	// ForceMode.Acceleration) ;
		}
	}

Also would this be the best way to check if the object is moving on a slope.

	public void CollisionCheck(GameObject go)
	{
		Ray ray ;
		RaycastHit hit ;
		float x, y ;
//		float offset = 10f ;
		float playerGroundSpace = 0.0005f ;	
		
		CapsuleCollider collider = go.GetComponent<CapsuleCollider>() ;
		
		// Checking for collision up and down																
		x = go.transform.position.x - go.transform.localScale.x / 2f ; 
		y = go.transform.position.y + go.transform.localScale.y / 2f ;
		
		ray = new Ray(new Vector2(x, y), new Vector2(0f, 10f)) ;
		
		Debug.DrawRay(ray.origin, ray.direction);
			
		if (Physics.Raycast(ray, out hit))
		{
			float dst = Vector3.Distance(ray.origin, hit.point) ;

			if(dst > playerGroundSpace)
			{
				Debug.Log("Collision, UP/DOWN") ;
			}
		}
		
		// Checking for collision left and right		
		x = go.transform.position.x + go.transform.localScale.x / 2f ;
		y = go.transform.position.y - go.transform.localScale.y / 2f ;
		
		ray = new Ray(new Vector2(x, y), new Vector2(10, 0)) ;
		
		Debug.DrawRay(ray.origin, ray.direction);
		
		if (Physics.Raycast(ray, out hit))
		{
			float dst = Vector3.Distance(ray.origin, hit.point) ;
		
			if(dst > playerGroundSpace)
			{
				Debug.Log("Collision, LEFT/RIGHT") ;
			}		
		}
	}

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!