Movement up and down a slope

Started by
-1 comments, last by Andre Rogers 10 years, 7 months ago

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") ;
			}		
		}
	}

This topic is closed to new replies.

Advertisement